Hallo,
Ich arbeite gerade an einem Projekt mit einem ESP-8266-Modul. Und zwar soll auf Knopfdruck eine E-Mail versand werden. Ich habe mich hierbei bereits am Quellcode unter folgendem Link orientiert
http://playground.arduino.cc/Code/Email
Diesen Quellcode habe ich etwas bearbeitet. Und zwar habe ich eine Variable eingefügt mit der ich einen "debug-modus" aktivieren oder deaktivieren kann. In meinem Arduino-Quellcode gibt es bereits eine andere Funktion mit der ich mich in ein W-Lan-Netzwerk einloggen kann. Ich habe daher die Funktionen für den E-Mail-Versand ausgelagert.
Soweit funktioniert alles. Einige Funktionen verstehe ich aber nicht. Wie funktioniert hier denn genau dieser E-Mail-Versand? Wird da eine Verbindung über Tel-net aufgebaut oder was soll das?
Teilweise habe ich Probleme damit den Inhalt der E-Mail anzugeben. Als ich die Stringvariable hierfür verändert habe hat das Programm nicht mehr funktioniert. Ich habe dafür jetzt zwei Extra-Zeilen Code eingefügt um die "Stabilität" zu verbessern. (ESP8266-Start und ESP8266-Ende) Seit dem habe ich keine Probleme mehr aber ich weiß nicht warum das so ist.
Weitere Forderungen an das Projekt:
Ich möchte zusätzlich neben dem SMTP2GO-server auch noch E-Mails über andere SMTP-Server versenden. Welche Möglichkeiten hätte ich in diesem Fall? Und wie könnte eine Lösung aussehen? Ich habe es bereits mit dem server von gmail probiert aber ich hatte bislang noch keinen Erfolg.
Außerdem:
Sobald der Knopf gedrückt wird arbeitet der ESP8266 und er ist erst einmal mit dem Versand beschäftigt. Ich möchte aber während dessen noch andere Sachen mit dem ESP8266 machen. Was könnte ich in so einem Fall tun? Ich dachte hierbei an eine Möglichkeit mit der der ESP nur jede zweite Sekunde oder so mit der Bearbeitung der Mail zu tun hat.
Hier nochmal der Quellcode
//include header
#include "EMailSoftware.h"
#include "LIB/OLED_IO.h"
#include "Softwareprofile.h"
void efail();
int debug = 0;
//Einbinden von Bibliotheken
#include <ESP8266WiFi.h>
WiFiServer server(80);
//Benötigte Formularangaben
char sender[] = "XXXX"; // E-Mail-Addresse des Senders
char user[] = "Projekt"; // user des Mail-Servers
char userb64[] = "cHJvamVrdA=="; // User des Mail-Servers in base64 codiert
char PW[] = "projekt1"; // Passwort für Mail-Server
char PWb64[] = "cHJvamVrdDE="; // Passwort für Mail-Server in base 64 codiert
char receiver[] = "XXXX@gmx.de"; // Empfängeraddresse
char messageline1[] = "Alarm vom ESP Text geändert\n"; // Mitteilung line 1
char messageline2[] = "Alarm vom ESP line 3"; // Mitteilung line 2
char smtpcorp[] = "smtpcorp.com"; // E-Mail-Server
int port = 2525; // Port
//EthernetClient client;
WiFiClient client;
byte eRcv()
{
byte respCode; // Variable die die Antwort des Servers ausgibt
byte thisByte; // Variable
int loopCount = 0; // Variable mit der die Zeit bestimmt wird....
// Funktion um sich mit dem Server zu verbinden
while(!client.available()) { // ....und die anschließende Funktion zum hochzählen
delay(1);
loopCount++;
// if nothing received for 10 seconds, timeout
if(loopCount > 10000) {
client.stop();
if(debug)
{
Serial.println(F("10 sec \r\nTimeout"));
}
return 0;
}
// Beim Überlauf wird eine 0 ausgegeben
}
respCode = client.peek(); // Funktion mit der einkommende Daten ausgewertet und gespeichert werden
// Funktion mit der einkommende Daten ausgelesen werden und über die serielle Schnittstelle angezeiogt werden können
while(client.available())
{
thisByte = client.read();
if(debug)
{
Serial.write(thisByte);
}
}
// Übertragung erfolgreich???
if(respCode >= '4')
{
efail();
return 0;
}
return 1;
}
// Prüfen auf Erreichbarkeit und im Notfall abbrechen
void efail()
{
byte thisByte = 0;
int loopCount = 0;
client.println(F("QUIT"));
while(!client.available()) {
delay(1);
loopCount++;
// if nothing received for 10 seconds, timeout
if(loopCount > 10000) {
client.stop();
if(debug)
{
Serial.println(F("efail \r\nTimeout"));
}
return;
}
}
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
client.stop();
if(debug)
{
Serial.println(F("disconnected"));
}
}
int sendEmail()
{
byte thisByte = 0;
byte respCode;
if(client.connect( smtpcorp,port) == 1)
{
if(debug)
{
Serial.println(F("connected "));
}
}
else
{
if(debug)
{
Serial.println(F("connection failed "));
}
return 0;
}
if(!eRcv())
{
if(debug)
{
Serial.println("before ehlo");
}
return 0 ;
}
//Nachricht soll über telnet erstellt und versandt werden
// Siehe auch -> Protokoll um E_mails mit Hilfe von Telnet zu versenden
if(debug)
{
Serial.println(F("Sending EHLO")); // Befehl wird über die serielle Verbindung übertragen und kann im serial monitor betrachtet werden
}
client.println(F("EHLO 139.13.210.77")); // CMD_PROMPT: Befehl für das cmd prompt mit der jeweiligen IP-Addresse des Micro-Controllers
if(!eRcv())
{
if(debug)
{
Serial.println("ehlo");
}
return 0 ;
}
if(debug)
{
Serial.println(F("Sending auth login")); // Befehl über serielle Verbindung
}
client.println("auth login"); // Befehl für das cmd prompt -> Befehl um sich bei smtp2go anmelden zu können
if(!eRcv())
{
if(debug)
{
Serial.println("auth");
}
return 0 ;
}
if(debug)
{
Serial.println(F("Sending User")); // Befehl über serielle Verbindung
}
client.println(userb64); //<---------User // base 64 codierter Name des users
if(!eRcv())
{
if(debug)
{
Serial.println("user");
}
return 0 ;
}
if(debug)
{
Serial.println(F("Sending Password")); // Bfehl für cmd prompt -> Befehl um das Passwort eingeben zu können
}
client.println(PWb64); //<---------Passwort mit base64 codiert
if(!eRcv())
{
if(debug)
{
Serial.println("Passwort");
}
return 0;
}
if(debug)
{
Serial.println(F("sending from XXXX")); // Befehl über serielle Verbindung
//Serial.println(sender);
}
client.println(F("mail from: XXXX")); // CMD-PROMPT: E-Mail-addresse von der gesendet werden soll
if(!eRcv())
{
if(debug)
{
Serial.println("email sender");
}
return 0 ;
}
if(debug)
{
Serial.println(F("sending to XXXX@gmx.de")); // Befehl über serielle Verbindung
//Serial.println(receiver);
}
client.println(F("rcpt to: XXXX@gmx.de")); // CMD-PROMPT: E-Mail-Addresse zu der gesendet werden soll
//client.println(receiver);
if(!eRcv() )
{
if(debug)
{
Serial.println("email rcpt");
}
return 0 ;
}
if(debug)
{
Serial.println(F("Sending DATA")); // Befehl über serielle Verbindung
}
client.println(F("data")); // CMD-PROMPT: Daten die versendet werden sollen
if(!eRcv())
{
if(debug)
{
Serial.println("data");
}
return 0 ;
}
if(debug)
{
Serial.println(F("Sending email")); // Befehl über serielle Verbindung
}
client.println(F("Subject: Esp8266 email test \r \n")); // CMD-PROMPT: Subject der E-Mail
client.println(F("\n")); // CMD-PROMPT: 2 x bestätigen
client.println("ESP8266: Start");
client.println(messageline1); // CMD-PROMPT: line 1
// client.println(F("\n"));
client.println(messageline2); // CMD-PROMPT: line 2
client.println("ESP8266: Ende\n");
//client.println(F("This is line 3 from my ESP8266")); // CMD-PROMPT: line 3
client.println(F(".")); // CMD-PROMPT: Ende der Mail
if(!eRcv())
{
if(debug)
{
Serial.println("aftersending");
}
return 0 ;
}
if(debug)
{
Serial.println(F("Sending quit")); // Befehl über serielle Verbindung
}
client.println(F("quit")); // CMD-PROMPT: Quit
if(!eRcv() && debug) {Serial.println("afterQuit");return 0 ;}
client.stop();
if(debug == 1)
{
Serial.println(F("disconnected")); // Befehl über serielle Verbindung
}
return 1;
}
// Funktion mit der eine E-Mail auf Knopfdruck versand wird
void E_MAIL_SENDEN( void )
{
unsigned char c;
c = pollkey_();
if( c == 0x88 ) // unten links
{
// line_1(); // Gehe auf dem display in Zeile 1
server.begin(); // Verbindung mit Server aufbauen
// puts_( "Sending E-Mail"); // Testausgabe mit puts_(...);
// LCD_UPDATE(); // Display updaten
sendEmail(); // Funktionsaufrauf
}
}
Du solltest den Sketch in „Code-Tags“ fassen. Dann ist er besser les- und „bedienbar“. Du kannst das auch nachträglich tun.
Gruß
Gregor
Das SMTP-Protokoll ist rel. simpel, textbasiert und hat tasächlich Ähnlichkeit mit Telnet. Zwischen Client und Server gibt es ein Handshake-Pingpong und wenn sich beide an die Regeln halten, keine Probleme.
Komplizierter ist es mit dem Verbindungsaufbau zum SMTP-Server. Es gibt wahrscheinlich keinen oder nur noch sehr wenige Provider, bei dem du deine Mail unverschlüsselt einliefern kannst. Für TLS/SSL ist ein Arduino zu schwachbrüstig, für den ESP8266 soll es eine TLS-Lib geben, aber auch für den ist das Ganze grenzwertig, wenn auch nicht unmöglich.
https://www.mikrocontroller.net/topic/438820
Arduinogenie:
Sobald der Knopf gedrückt wird arbeitet der ESP8266 und er ist erst einmal mit dem Versand beschäftigt. Ich möchte aber während dessen noch andere Sachen mit dem ESP8266 machen.
Bei mir dauert das senden zu SMTP2GO nur einstellige Millisekunden und selbst die Antwort von SMTP2GO ist in unter 100 ms auf dem Esp8266.
Das ist mit den vielen einzelnen client.println() und Serial.print() in deinem Sketch natürlich nicht zu schaffen.
Email Versand mittels SmtpGo als Sketch für Esp8266 und Esp32.
Email Versand mittels SmtpGo als Funktion für den Esp8266 zum Einfügen in eigene Projekte
Gruß Fips
Hallo,
erstmal vielen Dank für die Antworten. Also mein ESP8266 benötigt gute 22 Sekunden für den Versand der E-Mail. Die debug-funktion die ich eingebaut habe verkürzt die Zeit um keine Sekunde. (Ich bin sogar der Meinung dass der Arduino dann noch eine halbe Sekunde länger braucht)
Jetzt hätte ich auf Anhieb 2 Ideen wie man das System verbessern könnte:
Entweder ich schreibe eine zweite Funktion vollständig ohne diese ganzen unnötigen lines und rufe dann entweder die eine oder die andere Funktion auf je nachdem ob das bit für debug gesetzt worden ist oder nicht.
Oder aber ich schreibe eine Funktion in die loop die das Programm alle x Sekunden aufruft und immer nur einen Befehl ausführt zum Beispiel mit hilfe eines Zählers...
Außerdem:
Also gibt es keinen anderen smtp-Server mit dem ich mails mit Hilfe meines Arduino versenden kann?
Arduinogenie:
Also gibt es keinen anderen smtp-Server mit dem ich mails mit Hilfe meines Arduino versenden kann?
Wie ich oben schon geschrieben habe, dauert es bei mir nur Millisekunden die Mail an Smtpgo auszuliefern.
Du solltest das Problem nicht beim smtp-Server suchen!
Gruß Fips
Ich versuche gerade den code so weit es geht zu vereinfachen. Aber ich weiß nicht welche Zeilen relevant sind und welche nicht. Ich habe jetzt auf jeden Fall alle Kommandos mit serial.println("XXX") rausgenommen und der E-Mail-Versand ist kein Stück schneller geworden....
und ich versuche hier auch nicht dem smtp-server die Schuld zu geben nein ich möchte dass der e-mail-versand auch über andere smtp-server funktioniert das ist alles.
also ich habe das ganze Programm jetzt mal mit debugger überprüft. Es hakt an folgenden Stellen:
Sending EHLO
Sending from
Sending to
Sending E-Mail
Meine Idee wäre es jetzt diese While-Schleife in diesem Unterprogramm gegen eine If-Abfrage auszutauschen. Die Frage ist nur ob das funktioneirt und wie es funktionieren könnte. Das Ziel wäre dann die kontrolle über den Arduino zu behalten solange der Versand stattfindet. Der Arduino würde erst dann wieder das PRogramm weiterabarbeiten lassen wenn die jeweilige Aufgabe vollbracht wurde.
Also: ist es möglich die while-schleife in der diese loop hochgezählt wird in eine if-abfrage umzuändern?
byte eRcv()
{
byte respCode; // Variable die die Antwort des Servers ausgibt
byte thisByte; // Variable
int loopCount = 0; // Variable mit der die Zeit bestimmt wird....
// Funktion um sich mit dem Server zu verbinden
while(!client.available()) { // ....und die anschließende Funktion zum hochzählen
delay(1);
loopCount++;
// if nothing received for 10 seconds, timeout
if(loopCount > 10000) {
client.stop();
if(debug)
{
Serial.println(F("10 sec \r\nTimeout"));
}
return 0;
}
// Beim Überlauf wird eine 0 ausgegeben
}
respCode = client.peek(); // Funktion mit der einkommende Daten ausgewertet und gespeichert werden
// Funktion mit der einkommende Daten ausgelesen werden und über die serielle Schnittstelle angezeiogt werden können
while(client.available())
{
thisByte = client.read();
if(debug)
{
Serial.write(thisByte);
}
}
// Übertragung erfolgreich???
if(respCode >= '4')
{
efail();
return 0;
}
return 1;
}
Hallo,
Ich habe das ganze Problem noch ein bisschen genauer untersucht und habe dabei festgestellt dass es nicht an dieser Funktion lag. Es lag wohl eher an folgender Funktion:
Client.println(F("To: receiver@gmail.com"));
In den bereits benanntten Schritten benötigt diese Zeile zwischen 2 und 6 Sekunden. Ich verstehe aber nicht warum da eigentlich nur ein string übergeben wird. Hat hier jemand Vorschläge?