1. Diese Seite verwendet Cookies. Wenn Sie sich weiterhin auf dieser Seite aufhalten, akzeptieren Sie unseren Einsatz von Cookies. Weitere Informationen
  2. Kandidat werden bei Die Modellbauer
    Information ausblenden

ESP8266 von Anfang an

Dieses Thema im Forum "Arduino, RaspberryPi und Co." wurde erstellt von BAXL, 12. September 2019.

Schlagworte:
  1. BAXL

    BAXL Moderator Mitarbeiter

    In diesem Thema möchte ich, wie in einer Art Blog, meine Bemühungen dokumentieren, den ESP8266 zu verstehen und anwenden zu können.

    Der ESP8266 ist sehr einfach ausgedrückt ein kleiner Mikrokontroller, der einmal die reine Verarbeitungseinheit CPU beinhaltet und mit einer kleinen 2,4 GHz Antenne über WLAN mit der Aussenwelt kommunizieren kann. Der Programmspeicher ist je nach Modell ein kleiner Extrachip oder in dem Blechgehäuse integriert. Die Bezeichnung ESP8266 hat sich dabei zu einem Synonym für eine Vielzahl von fertigen Platinen entwickelt, an die man sehr einfach eine externe Beschaltung, wie z.B. digitale Sensoren, anschließen kann und der idR. auch einen Micro-USB Anschluß besitzt, über den man diese Baugruppe bequem per PC programmieren und abfragen kann. Das verhält sich so ähnlich wie beim Arduino, den es ebenfalls in vielen Erscheinungsformen gibt.

    Der ESP8266 quasi nackt

    [​IMG]

    Der ESP8266 ganz minimalistisch mit nur wenigen Anschlußpins

    [​IMG]
    Und hier als Entwicklerplatine bereits mit USB-Stecker und auf Pfostenstecker herausgeführte Anschlüsse

    [​IMG]


    Und nochmal im Vergleich

    [​IMG]

    Der offensichtlichste Unterschied zwischen den beiden Familien sind die Leistungsfähigkeit, zur Verfügung stehender Speicher, die WLAN-Fähigkeit und dass beim ESP8266 nur ein analoger Eingang vorhanden ist, der ADC0. Ansonsten hat man mehrere digitale Ein/Ausgänge, die sich GPIO nennen und nur mit 3,3 V zurechtkommen und nicht wie bei vielen Adruinos, mit 5V. Außerdem haben nicht alle digitalen Ports bereits intern vorhandene Pull-Up oder Pull Down Widerstände. Einige schon, doch das ist ein Thema für sich.

    [​IMG]

    Beiden gemein ist die Möglichkeit sie über die Arduino Programmierumgebung programmieren zu können. Der ESP8266 erfeut sich zudem bei den Freunden für Heimautomatisierung größter Beliebtheit.

    [​IMG]

    Vom ESP8266 habe ich zuerst von einem Kollegen gehört, der darüber in höchsten Tönen geschwärmt hat und mir von alternativen Betriebsystem und Programmierumgebungen usw. erzählte. Das hat mich Anfangs sehr verwirrt und ich habe nur Bahnhof verstanden.

    Nähert man sich diesem Modul aber etwas langsamer und behutsamer, fällt auf, dass man es bei der Programmiereung eigentlich wie einen Arduino händeln kann. Er kennt so ziemlich dieselben Befehle und das Überspielen eines Programms geht genau so schnell.

    Lässt man die WLAN-Fähigkeit außen vor, hat man quasi einen Arduino.

    Um damit tatsächlich arbeiten zu können und die WLAN-Fähigkeit nutzen zu können, sollte man in einfachen Schritten vorgehen.

    Man benötigt im einfachsten Fall ein ESP8266 Modul, das möglichst angelötete Pins besitzt und einen Micro-USB Anschluß. Dann sollte man sich die Arduino-Programmierumgebung auf dem PC installieren und der Programmierumgebung diesen neuen "Prozessortyp" bekannt machen. Wie das geht, dazu gibt es jede Menge Seiten, die das sehr gut erklären. Zum Beispiel auf heise.de.

    Nicht zu vergessen sei die Installation eines passenden USB-Treibers, damit der PC den ESP auch "sehen" und bedienen kann. Den Treiber findet man unter dem Namen CH340, oder man guckt gleich beim Makershop.

    Damit hat man eigentlich die erste Hürde überwunden und kann mit dem ersten Simpelprogramm starten, das in der Regel das Blinkenlassen der auf dem Bord angebrachten blauen LED ist.

    Das erstmal das Wichtigste für den Anfang. Sobald ich anfange damit zu fummeln schreibe ich mehr, dabei gehe ich wieder absichtlich nicht auf alle möglichen Feinheiten ein und konzentriere mich darauf, alles so einfach wie möglich zu halten, aber die wichtigsten Sachen nicht zu unterschlagen. Es gibt unzählige Seiten, da schreiben Leute, die viel besser sind als ich und viel mehr davon verstehen, leider setzen die bei ihren Erklärungen nicht selten ein gewissen Wissen in vielen Bereichen voraus, oder die Kenntnis, was verschiedene Abkürzungen bedeuten.
     
    Zuletzt bearbeitet: 12. September 2019
  2. BAXL

    BAXL Moderator Mitarbeiter

    Es gibt weitere zarte Erkenntnisse, die zumindest bei der Programmierung der Digitalausgänge wichtig werden können. Beim Arduino steuern wir die Digitalausgänge mit der Zahl an, deren Nummer der Pin trägt. D.h. bei D3 wäre es die 3, bei D4 die 4...D9 die 9 usw..

    Beim ESP8266 sieht das anders aus. Da werden die Ausgänge mit GPIO1 bis GPIO(irgendwas) bezeichnet, wobei sogar einige Nummern ausgelassen werden. Das ist verwirrend. Die Pinbezeichnungen von Platinen haben aber wieder eine durchgehende Nummerierung von D0 bis D10. In der Programmierumgebung setzt man dann für die Pinbezeichnung in den Befehlen die Bezeichnungen D0, D1, D2 usw..

    Ok, das war zu schwierig. Beispiel:

    Ausgabebefehl für einen Arduino, mit dem der Digitalausgang D5 eingeschaltet wird:

    digitalWrite( 5, HIGH);

    Beim ESP8266 haben wir den GPIO5, der aber auf den Pin D1 herausgeführt wird, da heißt das dann:

    digitalWrite(D1, HIGH);

    obwohl es sich um den GPIO5 handelt. Ganz wichtig, das D muß vor der Zahl stehen!


    Zuordnung der Belegung der Digitale Pins zum GPIO

    D0
    - GPIO16 / LED_BUILTIN Kann sein
    D1 - GPIO5
    D2
    - GPIO4
    D3
    - GPIO0
    D4
    - GPIO2 / LED_BUILTIN Kann auch sein
    D5
    - GPIO14
    D6
    - GPIO12
    D7
    - GPIO13
    D8
    - GPIO15
    D9
    - GPIO3
    D10
    - GPIO1

    Man sollte bei der Borddoku nachsehen an welchem Port die BuiltIn LED angeschlossen ist.
     
    Zuletzt bearbeitet: 13. September 2019 um 19:11 Uhr
    Crazy virus 4.0, froetz und BlackbirdXL1 gefällt das.
  3. BAXL

    BAXL Moderator Mitarbeiter

    Heute sind die drei bestellten ESP8266 D1 mini eingetroffen. Natürlich wollte ich zuerst prüfen, ob die Dinger leben. Dazu habe ich mir ein Beispiesketch aus dem Internet besorgt und in die Arduino IDE geladen. In dem Sketch soll die auf dem Board verbaute blaue LED im Sekundentakt blinken.

    Nun kam das erste Problem, welches Board stelle ich ein. Nach einiger Suche und Rumfummelei habe ich herausgefunden, dass man das "LOLIN(WEMOS) D1 R2 & mini" einstellen muß.

    Nochmal schnell den Sketch kompiliert und hochladen lassen. Es gab keine Fehlermeldung. Trotzdem blinkte die LED nicht. Nach einer weiteren Suche bin ich dahinter gekommen, dass in dem Beispielprogramm der falsche Digitalport eingestellt war. Es war nicht D0, sondern D4. Hätte ich das Beispielprogramm geladen, welches beim Installieren des Boardtreibers mitinstalliert wurde, hätte es sofort geklappt, weil man dort einfach als Angabe in pinMode() LED_BUILTIN eingesetzt hatte. In der Dokumentation vom Lieferanten bin ich dann auf die Fehlerursache gestoßen. Der Digitalport für die Builtin-LED ist der Pin D4!

    Also nochmal das erste Sketch ausprobiert, welches dann auch funktionierte. Hurra, die LED blinkt nun vor sich hin.

    #define LED D4

    void setup() {
    pinMode(LED, OUTPUT); // Port aus Ausgang schalten
    }

    void loop() {
    digitalWrite(LED, LOW); //Led port ausschalten
    delay(1000); //1 Sek Pause
    digitalWrite(LED, HIGH); //Led port einschlaten
    delay(1000);
    }

    void setup() {
    // initialize digital pin LED_BUILTIN as an output.
    pinMode(LED_BUILTIN, OUTPUT);
    }

    // the loop function runs over and over again forever
    void loop() {
    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
    delay(1000); // wait for a second
    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
    delay(1000); // wait for a second
    }

    Beide Sketches funktionieren :)

    Der nächste Schritt wird es sein, den ESP seiner eigentlichen Bestimmung zuzuführen, nämlich der Kommunikation per WLAN, ansonsten kann man für so triviale Sachen, wie LEDs blinken lassen, auch einen einfachen Arduino nehmen.

    Zum Größenvergleich habe ich das ESP8266 D1 mini neben eine Briefmarke gehalten:

    [​IMG]
     
    Zuletzt bearbeitet: 13. September 2019 um 19:09 Uhr
  4. BAXL

    BAXL Moderator Mitarbeiter

    Im Moment bin ich am verzweifeln. Meine kleinen ESP-Freunde schaffen es offenbar, sich in mein lokales WLAN "einzuwählen". Wenn ich den ESP per USB am PC habe, wird mir im seriellen Monitor artig die IP-Adresse angezeigt und ich kann im Browser am Smartphone über http://<IP-Adresse> kontakt zum ESP aufnehmen.

    #include <ESP8266WiFi.h> // stellt die WiFi Funktion zur Verfügung
    WiFi.begin(ssid, passwort); // die beiden Strings kann man sich selbst ausdenken

    while (WiFi.status() != WL_CONNECTED)
    {
    delay(500);
    Serial.print(".");
    // solange noch keine Verbindung hergestellt wurde lassen wir uns in 0,5s Abständen einen Punkt anzeigen
    }


    Wenn man dem ESP keine statische IP-Adresse vergeben will oder kann, muß man die DNS-Funktion nutzen, d.h., dass dem ESP bei jedem Anmelden eine IP-Adresse vom WLAN zugewiesen wird. Diese Adresse kann sich aber im Laufe der Zeit mal ändern, dann erreicht man den ESP nicht mehr über die IP-Adresse und man muß irgendwie die neue IP-Adresse herausfinden.

    #include <ESP8266WebServer.h> // ermöglicht die Erreichbarkeit
    ESP8266WebServer server(80); // Objekt für den Webserver bereitstellen und Port festlegen Standard ist 80


    Es soll aber eine Möglichkeit geben, dass dieses Problem behebt. Diese Funktion nennt sich mDNS und bedeutet wohl soviel, dass man dem ESP in seinem Programm einen Namen gibt, meinetwegen "BAXLSESP" oder so. Damit soll es dann möglich sein, ohner die aktuelle IP-Adresse zu kennen, einfach http://BAXLSESP.local einzugeben und man bekommt auch kontakt zum ESP. Tja, und das klappt trotz aller Bemühungen nicht.

    #include <ESP8266mDNS.h> // verhindert Probleme bei sich ändernder IP-Adresse

    Wenn sich so ein ESP in meiner Fritz Box anmeldet, dann sehe ich irgendeinen andern Namen mit ESP davor, aber nicht den, den ich im Programm vergeben habe.
    Ich weiß nicht auf wievielen Seiten ich schon gesucht habe, wie oft ich das Listing aus dem YT-Video abgetippt habe und ich habe auch von anderen Seiten Listings ausprobiert - ohne Erfolg. Über die IP-Adresse komme ich immer dran, aber über diesen Alias-Namen geht es nicht. :(
     
    Zuletzt bearbeitet: 15. September 2019 um 18:38 Uhr
    BlackbirdXL1 gefällt das.
  5. BAXL

    BAXL Moderator Mitarbeiter

    Ich glaube ich habe die Ursache, aber keine Lösung. Damit das funktioniert, muss der WLAN Router aus dem Namen eine IP Adresse machen. Das nennt sich DNS Rebinding. Diese Funktion ist bei meinen WLAN Routern deaktiviert. Der Grund dafür ist, dass das ein Sicherheitsloch im WLAN hervorrufen kann, was Angreifern die Möglichkeit für einen Einbruch ins Homenetz ermöglicht.

    AVM macht das per default

    Ergo muss ich mir was Neues einfallen lassen.
    Ich habe da was von APs gelesen, kann das aber noch nicht erklären. Also dranbleiben.
     
    Zuletzt bearbeitet: 15. September 2019 um 20:43 Uhr
    Crazy virus 4.0 gefällt das.
  6. Joungmerlin

    Joungmerlin Mitglied

    Wenn die Teile Wlan bzw. Netzwerk fähig sind müssen die doch ne feste MAC Adresse haben.
    Demnach musst du doch nur den MAC Adressen im DHCP vom Router feste IP Adressen zuordnen.

    Schon hat sich dein Problem in Luft aufgelöst.
     
  7. BAXL

    BAXL Moderator Mitarbeiter

    Da hast Du im Prinzip Recht, dazu muß der entsprechende Router allerdings immer verfügbar sein. Das kann ich aber nicht immer garantieren, darum wird es auf einen Access Point, kurz AP hinauslaufen.

    Wenn hier im Thema nicht, wie bei den Arduinos gewohnt, von mir in relativ kurzen Taktzeiten Posts kommen, dann liegt das daran, dass ich im Internet herumsuche und viel lese. Allmählich beginne ich zu verstehen, das reicht aber noch nicht aus, um sinnvoll weiterzumachen, oder gar erklärende Posts zu schreiben. Besonders die Erstellung einer "Internet"-Seite, wenn der ESP aufgerufen wird, ist für mich noch wie ein Schnittmuster. Die Befehle sehen sehr kryptisch aus, wenn man sich damit nicht auskennt.


    Hier ist mal so ein Beispiel, was ich mir aus den vielen Quellen "besorgt" habe. Wo auch immer html oder http steht wird es sehr unübersichtlich. Für einen Webseitenprofi sicherlich kalter Kaffee, dafür würde der sich aber die Ohren bei der Hardwareprogrammierung brechen. Und, man muß nicht in allem ein Experte sein.

    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>
    #include <EEPROM.h>

    String html1 = "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n\
    <meta content=\"text/html; charset=ISO-8859-1\" http-equiv=\"content-type\">\r\n\
    <title>WebSchalter</title>\r\n<form action=\"";
    // String((val)?"/1.html":"/0.html")
    String html2 = "\">\r\n<input value=\"ON/OFF\" style=\"";
    String html3 = " width:5em;height:3em; font-size: 16px;\" type=\"submit\"></form>\r\n</head>\r\n<body>\r\n</body>\r\n</html>";
    String Temp = "";

    const char htmlFrame[] = "<!DOCTYPE html><html><head><meta charset=\"utf-8\">\r\n\
    <title>IP Steckdose</title></head><body><h1>IP Steckdose</h1>\
    <script type=\"text/javascript\">setInterval(refreshIframe2, 3000);\r\n\
    function refreshIframe2(){ var frame = document.getElementById(\"Frame2\");\r\n frame.src = frame.src;}</script>\r\n\
    <iframe id=\"Frame2\" src=\"/\" name=\"IP Relais\" height=\"300\" width=\"300\" frameBorder=\"0\"></iframe></body></html>";


    ESP8266WebServer server(80); // Serverport hier einstellen
    int val = 1; //Schaltzuschtand 1 ist Aus, 0 ist Ein
    int i; //Variable fuer Adresse in EEPROM

    void Ereignis_SchalteON() // Wird ausgefuehrt wenn "http://<ip address>/1.html" aufgerufen wurde
    {
    val = 0; // Relais Aus
    digitalWrite(0, val); // GPIO0
    Temp = html1 + String((val) ? "/1.html" : "/0.html");
    Temp += html2 + String((val) ? "BACKGROUND-COLOR: DarkGray;" : "BACKGROUND-COLOR: Chartreuse;") + html3;
    server.send(200, "text/html", Temp);
    }

    void Ereignis_SchalteOFF() // Wird ausgefuehrt wenn "http://<ip address>//0.html" aufgerufen wurde
    {
    val = 1; // Relais Ein
    digitalWrite(0, val); // GPIO0
    Temp = html1 + String((val) ? "/1.html" : "/0.html");
    Temp += html2 + String((val) ? "BACKGROUND-COLOR: DarkGray;" : "BACKGROUND-COLOR: Chartreuse;") + html3;
    server.send(200, "text/html", Temp);
    }

    void Ereignis_Index() // Wird ausgeuehrt wenn "http://<ip address>/" aufgerufen wurde
    {
    Temp = html1 + String((val) ? "/1.html" : "/0.html");
    Temp += html2 + String((val) ? "BACKGROUND-COLOR: DarkGray;" : "BACKGROUND-COLOR: Chartreuse;") + html3;
    server.send(200, "text/html", Temp);
    }

    void Ereignis_Frame() // Wird ausgefuehrt wenn "http://<ip address>/frame" aufgerufen wurde
    {
    server.send(200, "text/html", htmlFrame );
    }

    void setup() // Wird 1 Mal beim Start ausgefuehrt
    {
    char ssid[32] = "1234\0"; //Variable fuer Wlan Name
    char passphrase[64] = "567890\0"; //Variable fuer Passwort

    digitalWrite(0, 1); // warscheinlich ueberfluessig
    pinMode(0, OUTPUT); // GPIO0 als Ausgang konfigurieren
    digitalWrite(0, 1); // Anfangszustand 1 (Relais ausgeschaltet)
    pinMode(2, INPUT_PULLUP); // GPIO2 als Eingang mit Pullup konfigurieren

    Serial.begin(115200); // Serielle schnittstelle initialisieren
    Serial.println("\r\n"); // Lehere Zeile ausgeben
    EEPROM.begin(64); // EEPROM initialisieren mit 64 Byts
    sprungmarke: // Hier landen wir wenn EEPROM leer

    // Eeeprom einlesen
    for (i = 0; i < 32; i++) ssid = EEPROM.read(i);
    for (i = 32; i < 64; i++) passphrase[i - 32] = EEPROM.read(i);

    // Wenn EEPROM leer
    if (ssid[0] == 255)
    {
    Serial.println("SSID nicht konfiguriert\r\n") ;
    Serial.println("Weiter mit \"Enter\"\r\n") ;
    while (!Serial.available())yield(); //Warte bis Seriell etwas reinkommt
    InputEEPR();
    goto sprungmarke;
    }
    // Wlan-Zugang konfigurieren
    WiFi.mode(WIFI_STA); // modus
    WiFi.begin(ssid, passphrase);
    WiFi.printDiag(Serial); // Wlan Daten seriell ausgeben

    while (WiFi.status() != WL_CONNECTED)// Warten auf verbindung
    {
    delay(500);
    Serial.print(".");
    if (Serial.available()) InputEEPR(); //Ausgand wenn Seriell etwas empfangen
    } // dann Wlan Name und Passwort eingeben

    Serial.println(""); // Wenn verbunden
    Serial.print("Verbunden mit ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());// Aktuelle IP des ESP8266-servers zeigen

    //Bechandlung der Ereignissen anschlissen
    server.on("/", Ereignis_Index);
    server.on("/1.html", Ereignis_SchalteON);
    server.on("/0.html", Ereignis_SchalteOFF);
    server.on("/frame", Ereignis_Frame);

    server.begin(); // Starte den Server
    Serial.println("HTTP Server gestartet");
    }

    void InputEEPR() // Unterprogramm zum eingeben der Wlan-Daten
    {
    String Text = "";
    char inser;

    inser = Serial.read();
    if (inser == 13) // Wenn "Enter" bet?tigt, 27 esc
    {
    Serial.println("Input SSID: ");
    for (i = 0; i < 32; i++) // SSID maximal 32 Byte
    {
    while (!Serial.available()) yield(); //warte bis etwas empfangen wird
    inser = Serial.read();
    Serial.write(inser); //Echo

    if (inser == '\r') // Wenn zeile abgeschlossen ist
    {
    EEPROM.write(i, '\0'); //Stringende setzen
    break; // for Schleife verlassen
    } else EEPROM.write(i, inser);//nechste Zeichen in EEPROM speichern
    }
    Serial.println("\r\nOK");

    Serial.println("Input Passwort: ");
    for (i = 32; i < 64; i++) // Passwort maximal 32 Byte
    {
    while (!Serial.available()) yield(); //warte bis etwas empfangen wird
    inser = Serial.read();
    Serial.write(inser);
    if (inser == '\r') // Wenn zeile abgeschlossen ist
    {
    EEPROM.write(i, '\0'); //Stringende setzen
    break; // for schleife verlassen
    } else EEPROM.write(i, inser);//nechste Zeichen empfangen
    }
    EEPROM.commit(); // EEPROM Schreiben
    Serial.println("\r\nOK");
    Serial.println("Bitte ESP8266 neu starten");
    }
    }


    void loop() //Hautprogramm
    {
    if (Serial.available()) InputEEPR();// Wenn Seriell etwas empfangen
    server.handleClient(); // Serwerereignisse abarbeiten

    if (!digitalRead(2)) // Wenn Taster an GPIO2 betaetigt wurde
    {
    val = !val; // Schaltzstand ?endern
    digitalWrite(0, val); // Schaltzstand an denn GPIO2 ausgeben
    while (!digitalRead(2))server.handleClient(); //Warten bis der Taster losgelassen wird
    }
    }
     
    Zuletzt bearbeitet: 16. September 2019 um 11:31 Uhr
    Crazy virus 4.0 und BlackbirdXL1 gefällt das.
  8. Joungmerlin

    Joungmerlin Mitglied

    Öhhhmmmm...

    Ein Access Point?

    Du weißt schon, daß der keine IP Adressen vergibt.
    Ein reiner Access Point hat keinen DHCP Server. Diesen hat nur ein nicht eingeschränkter Router.

    Man kann quasi jeden Router zu nem AP kastrieren in dem man diesem einfach ne feste IP Adresse verpasst und den DHCP Server deaktiviert.
     
  9. BAXL

    BAXL Moderator Mitarbeiter

    Warum sollte ein ESP denn auch IP Adressen vergeben? Ich will damit ja keine FritzBox o.ä. nachbilden oder gar ersetzen. Der ESP hat primär die Aufgabe etwas zu messen oder zu schalten und wenn gerade kein WLAN in der Nähe ist muss er eben seine eigene Verbindung anbieten. Aber trotzdem danke dass Du mich auf dieses wichtige Detail aufmerksam gemacht hast.
     
    Joungmerlin und BlackbirdXL1 gefällt das.

Diese Seite empfehlen