Mail-To-Text

Mit einer einfachen Mail eine Laufschrift auf ein Laufband zauber: das ist gar nicht so schwer. Und wer mag, kann sich noch ein passendes Gehäuse dazu drucken.

Hier finden sich die beiden STL Dateien für den Druck der Halterung.

Und hier folgt der Quellcode für die Programmierung des ESP8266. An der Anzeige der Uhrzeit arbeite ich noch. Das wird später noch einmal ergänzt. Auch Umlaute werden noch nicht angezeigt. Das folgt ebenfalls noch in den nächsten Tagen.

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP_Mail_Client.h>
#include <WiFiClientSecure.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <MD_MAX72xx.h >
#define PRINTS(x)
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CLK_PIN D3 // or SCK
#define DATA_PIN D1 // or MOSI
#define CS_PIN D2 // or SS
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
#define DELAYTIME 100

#define WIFI_SSID "*****"
#define WIFI_PASSWORD "*****"

#define SMTP_server "*****"
#define SMTP_Port 587

const char *pop3Server = "*****";
const int pop3Port = 995;

WiFiClientSecure client;    // TCP-Client

const String sender_email = "deine@mail.de";
const String sender_password = "*****";

#define Recipient_email "deine@mail.de"

SMTPSession smtp;

String command;
String response;
int pause = 1000;
String ausgabetext;

void scrollText(const char *p) {
	uint8_t charWidth;
	uint8_t cBuf[8];
	PRINTS("\nScrolling text");
	mx.clear();
	while (*p != '\0') {
		charWidth = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
		for (uint8_t i = 0; i <= charWidth; i++) {
			mx.transform(MD_MAX72XX::TSL);
			if (i < charWidth) {
				mx.setColumn(0, cBuf[i]);
			}
			delay(DELAYTIME);
		}
	}
}

void setup() {
	mx.begin();
	Serial.begin(9600);
	delay(1000);
	connectingWIFI();

	smtp.debug(1);
	//mailSenden();

	scrollText("Gestartet           ");
}

void loop() {
	if (newMail()) {
		ausgabetext = myContent() + "                  ";

		scrollText(ausgabetext.c_str());
	}
	delay(500);
	scrollText("Sende mir Deine Mail und ich schreibe sie hier.           ");
	connectCheck(); // Checkt, ob die Wlan Verbindung korrekt läuft und startet diese ggf. neu
	//free((void *)inhaltsText);

}

void connectCheck() {
	if (WiFi.status() != WL_CONNECTED) {
		Serial.println("WLAN-Verbindung verloren!");
		WiFi.begin(); // Versuch, erneut zu verbinden
	} else {
		Serial.println("WLAN-Verbindung aktiv");
	}
}

String myContent() {
	scrollText("Empfange neue Nachricht:              ");
	String answer = "";
	delay(100);
	connectingPOP();
	delay(100);
	loginPOP();
	delay(100);
	answer = myText();
	delay(100);
	serverRequest("DELE 1\r\n");
	delay(100);
	serverRequest("QUIT\r\n");
	//client.stop();
	return answer;
}

String getMail(int number) {
	String answer = "";
	response = "";
	char command[20];
	//sprintf(command, "RETR %d", number);
	//strcat(command, "\\r\\n");
	sprintf(command, "RETR %d\r\n", number);
	client.print(command);

	// Serverantwort empfangen und anzeigen
	while (client.connected()) {
		if (client.available()) {
			char c = client.read();
			if (c == '\n') {
				if (response.endsWith("\r")) {
					response.remove(response.length() - 1);
				}
				answer += response + "\n";
				response = "";

				// Überprüfung der Länge des resultierenden Textes
				if (answer.length() >= 2000) {
					break;
				}
			} else {
				response += c;
			}
			if (response == ".") {
				break;
			}
		}
	}
	return answer;
}

String myText() {
	String theText = getMail(1);  //serverRequest("RETR 2\r\n");
	const char *answer = between("###", theText.c_str());
	return answer;
}

boolean newMail() {
	connectingPOP();
	loginPOP();
	String statText = serverRequest("STAT\r\n");
	Serial.println(statText);
	String anzahl = between(" ", statText.c_str());
	if (anzahl == "0") {
		return false;
	} else {
		return true;
	}
}

const char* between(const char *pattern, const char *text) {
	// eingaben validieren, ohne Text oder mit leeren Muster geht nix
	if (text == NULL || pattern == NULL || strlen(pattern) == 0) {
		return NULL;
	}

	// erstes Muster suchen, wenn's nicht vorhanden ist abbrechen
	const char *start = strstr(text, pattern);
	if (start == NULL) {
		return NULL;
	}
	// Muster im Text ueberspringen als Startposition, dann das zweite
	// Muster suchen. Wenn's nicht da ist, abbrechen
	start += strlen(pattern);
	const char *stop = strstr(start, pattern);
	if (stop == NULL) {
		return NULL;
	}

	// Neuen Speicher fuer das Ergebnis allozieren, dabei beachten, dass
	// ein C-String immer mit dem Nullzeichen abgeschlossen wird, der Speicher
	// also ein Byte laenger sein muss als die Anzahl Zeichen im Ergebnis
	size_t result_len = stop - start;
	char *result = (char*) malloc(result_len + 1);
	if (result == NULL) {
		return NULL;
	}

	// Und schliesslich noch den Inhaltsstring in den neuen Speicher kopieren
	// und den String gueltig mit einer Null abschliessen.
	strncpy(result, start, result_len);
	result[result_len] = '\0';

	// ACHTUNG: die Funktion alloziert Speicher, der spaeter freigegeben
	// werden muss, ansonsten gibt's Memory leaks (leider keine Garbage
	// Collection wie in Java :( Die aufrufende Stelle muss den neuen Speicher
	// also mit free() wieder freigeben!
	return result;
}

void connectingWIFI() {
	Serial.print("Connecting");
	WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
	while (WiFi.status() != WL_CONNECTED) {
		Serial.print(".");
		delay(200);
	}
	Serial.println("");
	Serial.println("WiFi connected.");
	scrollText("WiFi connected.           ");
	Serial.print("IP address: ");
	Serial.println(WiFi.localIP());
	Serial.println();
}

void connectingPOP() {
	client.setInsecure();       // Sicherheit herabstufen, um das SSL zu handeln
	delay(1000);
	if (!client.connect(pop3Server, pop3Port)) {
		Serial.println("Fehler beim Verbindungsaufbau zum POP3-Server!");
		scrollText("Problem mit POP3!           ");
		return;
	}
	//Serial.println("Verbunden mit POP3 Server...");
}

void loginPOP() {
	serverRequest("USER " + sender_email + "\r\n");
	serverRequest("PASS " + sender_password + "\r\n");
	delay(1000);
}

String serverRequest(String pCommand) {
	// Serveranfrage
	client.print(pCommand);
	delay(pause);
	// Serverantwort empfangen und anzeigen
	response = "";
	while (client.available()) {
		response += client.readStringUntil('\n');
		if (response.endsWith("\r\n.\r\n")) {
			// Ende der mehrzeiligen Antwort erreicht
			break;
		}
	}
	return response;
}

void mailSenden() {
	ESP_Mail_Session session;

	session.server.host_name = SMTP_server;
	session.server.port = SMTP_Port;
	session.login.email = sender_email;
	session.login.password = sender_password;
	session.login.user_domain = "";

	/* Declare the message class */
	SMTP_Message message;

	String betreff = "Eingeschaltet";

	message.sender.name = "Schaltungs-ESP8266";
	message.sender.email = sender_email;
	message.subject = betreff;
	message.addRecipient("Microcontrollerslab", Recipient_email);

	//Send HTML message
	String htmlMsg = "Der ESP wurde gestartet.";
	message.html.content = htmlMsg.c_str();
	message.text.charSet = "us-ascii";
	message.html.transfer_encoding = Content_Transfer_Encoding
	::enc_7bit;

	if (!smtp.connect(&session))
		return;

	if (!MailClient.sendMail(&smtp, &message))
		Serial.println("Error sending Email, " + smtp.errorReason());
}