Tech-Ecke / Programmieren / Arduino - ESP8266

Arduino - ESP8266

Diese Seite beinhaltet

Ergänzende Seiten zum:


Auch wenn diese Seite unter der Rubrik Programmieren zu finden ist, so ist Arduino ist eigentlich keine Programmiersprache, sondern ein Open-Source-Projekt. Es umfasst diverse Entwicklerboards und die Arduino-IDE (Programmiereditor und mehr). Als Programmiersprache dient eine auf C/C++ basierende, vereinfachte Sprache. Bei Arduino werden Programme übrigens  als "Sketch" (Skizze) bezeichnet. Das aller erste Arduino Board entstand 2005, auf Basis eines ATMEL ATmega8 Controllers durch Massimo Banzi und David Cuartielles in Italien. Das erste kommerzielle Board war der "Arduino RS232". Das heute bekannteste Board dürfte wohl der Arduino Uno sein, aber aufgrund des Open-Source-Konzeptes gibt es auch jede Menge Drittanbieter-Hardware. Diese sind zu 100% kompatibel, dürfen aber nicht Arduino im Namen tragen. Eines dieser Entwicklerboards ist der "WEMOS D1 Mini", auf Basis des ESP8266. Auch wenn hier der D1-Mini angeführt wird, so lässt sich das hier gezeigte auch auf allen anderen ESP-8266 Boards oder ESP-Modulen selbst umsetzen. Der ESP8266 der Chinesischen Firma Espressif ist ein 32-Bit-Mikrocontroller, inkl. WLAN. Klein in der Stomaufnahme, Abmaßen und Preis, aber groß in der Flexibilität. Ein Idealer Baustein für selbstgebastelte IoT-Geräte.




Arduino IDE

Installation:
Ich als bekennender Liebhaber von Portable-Apps habe meine Arduino IDE unter Windows wie folgt installiert: Zunächst habe ich mir die Version 1.8.16 auf der offiziellen Arduino-Seite unter Old Releases heruntergeladen. Dann das Setup in einer Virtuellen Maschine (Win7) installiert und den kompletten Installationsordner (C:\Program Files (x86)\Arduino) auf meinen "physischen" Rechner kopiert. Im Anschluss fügt man noch den Ordner "portable" hinzu und voilà, fertig ist die Portable-Arduino-IDE. Gestartet wird die IDE über die "Arduino.exe". Alle App-Downloads und Einstellungen wandern den Ordner "portable" und können z.B. per USB vom einen zum anderen Rechner mitgenommen werden.

ESP8266 Board-Installation:
Die ESP8266-Bibliothek ist nicht Bestandteil der Installation und muss erst noch nachträglich nachinstalliert werden. Dazu im Hauptmenü:

USB-Treiber:
Zum Abschluss der Installation muss nun noch der USB-Treiber des Wemos Boards installiert werden. Dies ist ein USB-to-Serial CH340 Treiber und kann hier direkt heruntergeladen werden.

CH340 Treiber  (180 kb)


Board-Auswahl

Mit der Installation der Board-Bibliothek fliegen jede Menge ESP8266 basierte Boards auf die Platte. Um für den D1-Mini das richtige Board zu wählen geht man auf "Werkzeuge/Board/ESP8266 Boards" und wählt dort das "LOLIN(WEMOS) D1 mini (clone)" aus.




COM-Port
Damit die Arduino-IDE mit dem USB-Adapter und somit letztlich auch mit dem ESP kommunizieren kann, muss der COM-Port des Adapters angegeben werden. Hierzu ermittelt man zunächst über den Windows Gerätemanager dem Adapter zugewiesenen COM-Port. In meinem Fall ist das der COM7.


Blinktest

Nachdem die Installation abgeschlossen ist kann man das Board mittels Micro-USB Kabel an den PC anschließen und in der IDE ein erstes simples Beispiel- und Testprogramm - pardon ich meine natürlich "Sketch" hochladen und ausführen. Dieses wird nichts weiter tun als die blaue Status-LED's des Boards zum blinken bringen. Dazu geht man im Menü auf "Datei/Beispiele/01.Basics/Blink" und schon fliegt der Sketch in die IDE. Durch einen Klick auf den Button hochladen wird der Sketch kompiliert und auf den ESP8266 geschoben und gestartet.

Hat alles geklappt, so sollte die blaue LED nun mit einer Frequenz von 1 Hz anfangen zu Blinken. Um die Blinkfrequenz zu ändern sucht man im Code nach den beiden "Sleep" Befehlen und kann diese nach belieben verändern. Die Angabe ist in Millisekunden. Nach einem erneuten Klick auf den Butten "Hochladen" wird der geänderte Sketch dann an den Mikrocontroller gesendet und wieder direkt ausgeführt.


Code Aufbau und Serieller Monitor

Bevor es nun richtig los geht noch ein paar Worte zum Code-Aufbau und Seriellen-Monitor. Der Sketch teilt sich im groben in drei Bereiche auf. Ganz oben (rot) werden die für das Programm benötigten Module (Libraries) eingetragen und globale Variable und Konstante gesetzt. Bei "void setup()" (blau) kommen initialisierende Anweisungen hin, die nur beim Programmstart abgearbeitet werden. z.B. das Starten des WLAN, Webserver,... und auch das Initialisieren des Serial-Monitors, dazu gleich mehr. Im dritten Abschnitt "void loop()" (grün) kommt der sich wiederholende Programmteil hin. Also Warten auf Ereignisse und die Reaktionen darauf. All das wird beim nächsten Punkt "WLAN" sich verdeutlichen.

Der Serial-Monitor ist ein sehr nützliches Werkzeug. Er dient als Ausgabefenster des ansonsten anzeigelosen ESP8266. Zum einen kann man sich hier den Programmfortschritt anzeigen lassen, zum anderen lässt er sich durch gezielte Ausgaben als Debugging-Hilfe einsetzen. Wie bereits oben erwähnt muss er zunächst im Programmbereich "void setup()" initialisiert werden, das geschieht über die Zeilen: Serial.begin(9600); Wobei 9600 für die Übertragungsrate in Boud steht. Das Monitorfenster selbst wird über das Menü "Werkzeuge/Serieller Monitor", oder über die Tastenkombination [Strg] + [Umschalt] + [M] geöffnet. Wichtig ist, dass die im Code angegebene Boudrate auch im Monitorfenster eingestellt wird, ansonsten wird man nicht viel brauchbares sehen können. Ich nutze eigentlich hier immer die Standardeinstellung "9600", aber viele Sketch-Beispiele im Netz wählen hier höhere Werte, die entsprechend im Code und Monitor-Fenster abgeglichen werden müssen.
    

Um eine Ausgabe auf dem Monitor zu platzieren kann der Befehl "print" bzw. "println" benutzt werden. Wobei println am Ende der Ausgabe einen Zeilenumbruch sendet, print hingegen nicht.
Beispiel: Serial.println("Hallo Welt"); gibt den Text "Hallo Welt" inklusive Zeilenumbruch auf dem Monitor aus.


WLAN

Am Router im Heimnetzwerk anmelden

Im nun folgenden Sketch wird der ESP8266 eine Wifi-Verbindung zum heimischen Netzwerk (Router) aufbauen. Damit sich dann auch was tut bekommt er auch noch ein Webserver, welcher mit den beiden URL's "/led_ein" und "/led_aus" gefüttert wird. Über diese beiden URL's lässt sich dann die blaue Status-LED am ESP8266 ein- und ausschalten. Der Webserver bekommt eine einfache Start-Seite mit zwei Links zu den beiden URL's. Der HTML-Code für die URL's wird direkt nach dem Laden des WLAN- und Webservermoduls in die Variable "html" geschrieben.
Der komplette Sketch kann per Copy&Paste in die IDE kopiert werden, lediglich die WLAN-Zugangsdaten ("ssid" und "pwd") müssen zuvor noch angepasst werden. Der Code ist komplett kommentiert, somit sollten die einzelnen Aktion nachvollziehbar sein.

Nachdem der Code kopiert und die beiden Variablen "ssid" und "pwd" angepasst wurden, öffnet man den "Serial-Monitor" mit [Strg] + [Umschalt] + [M] und klickt auf  "Hochladen" bzw. [Strg] +[U].
Ist der Sketch kompiliert und hochgeladen, so startet der ESP8266 automatisch durch und baut eine Verbindung zum Heimnetzwerk auf. Läuft alles wie geplant, dann wird im Serial-Monitor die vom Router vergebene IP-Adresse angezeigt. In meinem Fall ist dies die 192.168.178.76, diese wird natürlich mit an Wahrscheinlichkeit grenzender Sicherheit bei dir irgendeine andere sein. Diese kopiert man nun in die Adresszeile des Browsers und bestätigt mit der Eingabetaste. Betreibt man den ESP ohne Serial-Monitor, so kann man den ESP mit dem Namen "Du suchst mich" im Router finden, dieser wurde im Code mit WiFi.hostname("Du suchst mich"); vergeben.

Wenn alles geklappt hat sollte jetzt die Startseite im Browser angezeigt werden. Mit den beiden Links "LED EIN" und "LED AUS" lässt sich die blaue Status LED ein- und ausschalten. Man kann aber auch direkt die entsprechende URL eingeben, in meinem Fall "192.168.178.76/led_ein" bzw. "192.168.178.76/led_aus".
Die Zeile "<meta name="viewport" content="width=300px">" im HTML-Quellcode sorgt dafür, dass auf dem Handy die Seite gezoomt angezeigt wird.


Statische IP-Adresse verwenden

Im oben gezeigten Code wird dem D1, über DHCP vom Router irgend eine freie IP-Adresse zugewiesen. Möchte man sich am Router mit einer bestimmten IP-Adresse anmelden, so ist der Code wie folgt gezeigt zu ergänzen.

Im Header, am besten direkt unter "#include <ESP8266WiFi.h>" werden die drei Variablen local_IP, gateway und subnet deklariert und entsprechend der Router-Adresse befüllt. In meinem Fall besitzt der Router die Adresse 192.168.178.1 und ich hätte gerne die 192.168.178.15 für den D1-Mini. Der Router wird die Adresse jedoch nur dann zulassen, wenn sie nicht bereits durch ein anderes Gerät benutzt oder reserviert wurde! Vor der Zeile "WiFi.begin(ssid, pwd);" werden die Variablen dann mittels WiFi.config() übergeben.
Eine fest vergebene IP-Adresse kann übrigens auch die Anmeldung am Router beschleunigen.


Einen Access-Point für WLAN-fähige Geräte bereitstellen

Der folgende Sketch mach prinzipiell das gleiche wie der oben gezeigte. Jedoch wird sich der ESP8266 nicht ins Heimnetzwerk einwählen, sondern stattdessen einen Accesspoint aufbauen, über diesen man z.B. per Handy auf den Server zugreifen und somit die LED schalten kann.

Nachdem der Code kopiert und die beiden Variablen "ssid" und "pwd" angepasst wurden, öffnet man den "Serial-Monitor" mit [Strg] + [Umschalt] + [M] und klickt auf  "Hochladen" bzw. [Strg] +[U].
Ist der Sketch kompiliert und hochgeladen, so startet der ESP8266 automatisch durch und baut einen Access-Point mit dem Namen (SSID) "ESP8266_AccessPoint" auf. Wählt man sich nun mit dem Handy darin ein, so kann über die IP-Adresse "192.168.1.1" die Startseite aufgerufen werden.

Die HTML-Seite lässt sich natürlich auch mittels HTML-Formatierung und durch hinzufügen von Java-Script etwas ansprechender gestalten.



HTML Authentifikation  (basic access authentication)

Wenn man den Zugriff auf den ESP8266 bzw. dessen Webserver beschränken möchte, dann empfiehlt sich eine HTML Authentifikation. Dazu legt man zunächst die Zugangsdaten in Konstanten ab, hier im Beispiel für Benutzername http_UserName = "admin" und http_pwd = "1234".
Bei Aufruf der URL wird der Benutzer nun aufgefordert sich mit den festgelegten Daten einzuloggen.



HTML-Code im Sketch

Wie in den vorangegangenen Beispielen zu sehen wird der HTML-Code zunächst in eine Variable vom Typ String geschrieben und diese dem Server übergeben. Dabei kommt es bei den Anführungszeichen zu einem Konflikt, da diese innerhalb des HTML-Codes und auch zum definieren einer Zeichenkette im Arduino-Sketch verwendet werden. Um dies zu vermeiden gibt es drei Möglichkeiten:

  1. Wie in den Beispielen gezeigt per String html = R"***( <button class="button">Klick Mich</button> )***";
    • Der HTML-Code kann zwischen den Klammern unverändert eingegeben werden
  2. Im HTML-Code Hochkomma (') statt Anführungszeichen (") verwenden und normal zuweisen String html = "<button class='button'>Klick Mich</button>"
  3. Anführungszeichen mittels Backslash "\" maskieren String html = "<button class=\"button\">Klick Mich</button>"

Für Methode 3 hatte ich mal für einen anderen Zweck ein Tool geschrieben dass die Maskierung mittels "\" automatisch vornimmt und auch wieder umkehren kann. Ebenso wird jede Zeile in Anführungszeichen gekackt, so dass der HTML-Code direkt in den Sketch kopiert werden kann.

TE ESP HTML Convert (861 kB)



MQTT

MQTT (Message Queuing Telemetry Transport) ist ein schlankes Nachrichtenprotokoll, um Informationen innerhalb eines IoT-Netzwerks (Internet of Things) auszutauschen. Dabei dient ein Server, welcher hier Broker genannt wird als Vermittler zwischen den einzelnen Geräten (Clients). Ein Gerät das Daten empfangen soll "subscribed" für ein Topic beim Broker (-> abonniert ein Thema). Das Gerät das senden soll senden (published) die Information zusammen mit einem Topic an den Broker. Dieser leitet die Information an alle Geräte weiter die den Topic subscribed, also das Thema abonniert haben.
Hier mal ein Beispiel. Ein ESP8266 (Sensor) ließt einen Fotowiderstand aus und übergibt die Information (Tag/Nacht = 0/1) mit einem Topic, z.B. "Dämmerdungsschalter" an den Broker. Der Broker leitet die Information an alle Clients weiter die den Topic "Dämmerungsschalter" subscribed haben. PC und Handy zeigen an ob es Tag (1) oder Nacht (0) ist. Ein weiterer ESP8266 (Aktor), welcher ebenfalls den Topic subscribed hat schaltet bei Nacht das Licht an und am Tag wieder aus.

Wie das Beispiel zeigt kann der ESP8266 sowohl als Subscriber (Empfänger) als auch als Publisher (Sender) arbeiten. Er kann aber auch beides gleichzeitig sein, gleiches gilt natürlich auch für den PC und Mobile Endgeräte. Genug Theorie, fangen an.

MQTT-Broker
Als erstes benötigen wir einen Broker. Hier kann man einen der zahlreichen Brokerdienste im Netz in Anspruch nehmen oder eben selbst einen im Heimnetzwerk aufsetzen betreiben. Vermutlich bin ich einfach nur altmodisch, aber die Daten auf einen Internetserverserver hochladen, um sie dann 5m weiter wieder herunterladenzuladen fühlt sich irgendwie krank an. Deshalb läuft bei mir ein Raspberry Pi Zero W2, der sich im Betrieb gerade mal 1 Watt nimmt. Wie man die Himbeere aufsetzt und darauf den MQTT-Server Mosquito installiert ist hier zu finden. Wer keinen Raspberry hat kann Mosquito auch auf dem PC ausführen.

MQTT-Client
Um MQTT auf dem ESP8266 nutzen zu können benötigt man eine entsprechende Library, ich nutze hier die "PubSubClient" von Nick O'Leary. Diese installiert man wie folgt:

Bei mir hat die Suche jedoch nicht funktioniert, deshalb habe ich mir die Library als Zip bei Arduino.cc heruntergeladen und über "Sketch/Bibliothek einbinden/ZIP-Bibliotheken hinzufügen..." von Hand zu Fuß installiert.


Daten an den Broker senden

Der folgende Sketch baut zunächst eine Verbindung ins heimische Netzwerk auf und verbindet sich dann mit dem Broker. Danach beginnt der ESP8266 im 5-Sekundentakt die Information "Nachricht xy" mit dem Topic "test1" an den Broker zu senden. Wobei "xy" ein Zähler ist, der sich bei jedem Senden um "1" erhöht. Das Ganze dient als Demo bzw. als Grundgerüst für einen Sensoraufbau, welcher anstelle von "Nachricht xy" die Zustände der Eingangspins sendet. Die Wifi-Initialisierung habe ich hier mal in eine eigene Sub-Routine gepackt, um den Setup-Bereich etwas übersichtlicher zu halten.

Die gesendeten Informationen kann man sich z.B. mit TE MQTT Client am PC anschauen, oder mit dem IoT MQTT Panel auf dem Android Smartphone oder Tablet bestaunen.


Daten vom Broker empfangen

Der nächste Sketch ist ein Beispiel wie man MQTT-Nachrichten empfängt und darauf reagiert. Genauer gesagt abonniert der ESP8266 den Topic "test1" und sobald auf diesem die Nachricht "ein" gesendet wird, schaltet er die blaue Status-LED ein. Wird ein "aus" gesendet wird er sie wieder ausschalten. Bei allem anderen wird die Nachricht nur auf dem Serial-Monitor ausgegeben aber nichts weiter unternommen.

Zum Senden von Nachrichten mit dem Topic "test1" kann ebenfalls der TE MQTT Client benutzt werden.


MQTT im Browser

In diesem Zusammenhang kann das Senden und Empfangen von MQTT Nachrichten im Browser ebenfalls interessant sein und so einige Spielereien beflügeln. Das hatte ich bereits im Zusammenhang mit dem Tasmota Stromzähler-Adapter (hier werkelt auch ein ESP6288 :-) beschrieben und ist hier zu finden. 



Deep-Sleep Mode

Der Tiefschlafmodus kann genutzt werden, um den Strombedarf des ESP6288 zu minimieren. Dabei erledigt der ESP seine Aufgaben und legt sich dann, für eine vordefinierte Zeit schlafen. Nach dem Schlaf nimmt er wieder seine Arbeit auf, erledigt diese und legt sich wieder hin. Das Ganze eignet sich z.B. für eine Intervallmessung im Batteriebetrieb. Der D1-Mini benötigt im Betrieb (gemittelt inkl. Wifi) ca. 73 mA, im Deep-Sleep-Mode ca. 230 μA (beide Werte gemessen am 3,3 V Einspeisepin). Hierzu mal eine Abschätzung der Laufzeit im Batteriebetrieben:

Der D1 soll alle 15 Minuten einen Messwert erfassen (z.B. Temperatur oder Spannung) und diesen per Wifi versenden. Für das Erfassen und Senden benötigt er 5 Sekunden. Unter Berücksichtigung der Arbeits- und Deep-Sleep-Phase ergibt sich eine gemittelte Stromaufnahme von ca. 0,634 mA/h. Eine Batterie (3,3 V) mit 2500 mA/h würde demnach ca. 3941,5 h, also ca. 164 Tage durchhalten.

Ein "nacktes" ESP-12E/F Modul benötigt im Deep-Sleep nur 18 mA (gemessen) und würde somit unter den gleichen Bedingungen auf 246 Tage kommen. Gleiches gilt für das ESP-01(S) Modul.

Tipp: Die Verwendung einer statischen IP-Adresse spart eventuell etwas Zeit beim Anmelden am Router, was wiederum die Arbeitszeitphase etwas verkürzt. Eine halbe Sekunde weniger Arbeitszeit bedeutet im obigen Beispiel 12 Tage mehr Laufzeit.

Um mit den Werten ein wenig zu spielen, hier mal ein OnlineRechner .


Code-Umbau

Um den Deep-Sleep-Modus nutzen zu können muss der komplette Code im "void setup()" Bereich liegen, "void loop()" bleibt leer. Am Ende wird der D1 dann mit dem Befehl "ESP.deepSleep()" schlafen geschickt. Hier mal ein (sinnloses :-) Beispiel:

Hardware-Umbau

Lässt man den Code nun laufen, so wird der D1 zwar in den Deep-Sleep-Modus fallen, aber daraus nicht mehr erwachen. Damit der das tut muss zunächst noch der Pin "RST" mit "D0" gebrückt werden!

Nach Ablauf der vordefinierten Deep-Sleep-Zeit wird über D0 ein Reset ausgeführt und der Code im "void setup()" wird erneut ausgeführt.
Beim ESP-12E/F Modul muss die Brücke übrigens zwischen "RST" und "GPIO16" gelegt werden. Beim ESP-01(s) ist etwas diffizile Lötarbeit notwendig.


Die Option Drucken funktioniert erst ab Netscape V4.0 bzw. I-Explorer 5.0 !
[letzte Aktualisierung 26.04.2024]