Gliederung


ESP-01 Modul


ESP-07 Modul


ESP-12 Modul


NodeMCU Board


Mein ESP-12 "Starter-Kit"


WiFi Monitor mit RGB-LED und ESP-01 (Quelltext)

Startseite

ESP8266 Module - Starter Anleitung

Der ESP8266 von Espressif ist ein 32bit Mikrocontroller mit integrierter WLAN Schnittstelle. Die Firmware basiert auf dem Lightweight TCP/IP stack (lwIp) von Adam Dunkels. Es werden zahlreiche handliche Module mit diesem Mikrochip verkauft. Am rechten Rand habe ich eine kleine Auswahl davon abgebildet. Mit diesen Produkten können sogar Einsteiger eigene WLAN-fähige Geräte bauen und programmieren. Auf dieser Seite beschreibe ich alles, was man als Anfänger für den Einstieg wissen muss.

Normalerweise werden die ESP-Module mit der sogenannten "AT-Firmware" verkauft, die es ermöglicht, sie so ähnlich wie analoge Modems oder Bluetooth Module zu benutzen. Der seriell angeschlossene Computer oder Mikrocontroller sendet Befehle an das Modul, um Verbindungen aufzubauen, Daten zu senden und zu empfangen. In meinem Buch Einstieg in die Elektronik mit Mikrocontrollern habe ich gezeigt, wie man auf diese Weise einen kleinen Webserver zum Fernsteuern einer Lampe baut.

Man kann aber auch eigene Programme direkt durch den ESP Chip ausführen lassen.

Mit Preisen um 4 Euro sind die ESP Module mit großem Abstand die preisgünstigste Netzwerk-Anbindung zum Basteln.

Technische Daten

*) Durchschnittliche Werte, bei mir zu Hause gemessen. Die Latenz hängt sehr stark von der Auslastung des WLAN Netzes ab.

Module

ESP-01 Modul

Das ESP-01 Modul wurde früher mit 512k Byte, heute jedoch mit 1M Byte Flash Speicher ausgestattet. Die Besonderheit bei diesem Modul ist die kleine 8-Polige Stiftleiste. Die Minimal-Beschaltung zur Nutzung der AT-Firmware sieht so aus:


Modul PinNummer in ArduinoNummer in NodeMCUNameBeschreibung
139RxD (GPIO3)serieller Eingang oder normaler I/O Pin
2  VCCSpannungsversorgung 3,3V 500mA
303GPIO0Low beim Start aktiviert Firmware-Upload, muss zum normalen Start offen sein oder auf High liegen
4  /RESETLow=Reset, hat schwachen Pull-Up Widerstand auf High
524GPIO2Flackert beim Start, darf beim Start nicht auf Low gezogen werden
6  CH_PD (EN)Muss auf High gezogen werden, damit der Chip arbeitet. Low=Power Down
7  GNDMasse
8110TxD (GPIO1)serieller Ausgang oder normaler I/O Pin, ist mit der blauen LED verbunden, flackert beim Start, darf beim Start nicht auf Low gezogen werden
Auf dem ESP-01 Modul befindet sich eine rote Power-LED, die zusätzlich zu den oben genannten 25µA etwa 500µA Strom aufnimmt. Die blaue LED ist mit TxD verbunden, sie leuchtet bei Low Pegel.

GPIO0, GPIO1 und GPIO2 haben beim Starten eine besondere Funktion, die ich im Kapitel Firmware Hochladen beschreibe. GPIO15 ist fest mit GND verbunden. Passe auf, dass du ihn nicht versehentlich als Ausgang mit High Pegel programmierst, denn der Kurzschluss könnte den Pin so zerstören, dass der Chip nicht mehr startet.

Die Reichweite der primitiven Antenne (Leiterschleife) ist mit Smartphones vergleichbar.

ESP-07 und ESP-12 Modul

Das ESP-07 Modul ist normalerweise mit 1M Byte Flash, einer Keramikantenne und einer Steckbuchse für externe Antennen ausgestattet. Es hat alle sinnvoll nutzbaren Pins herausgeführt. Es gibt außerdem die komplett abgeschirmte Variante ESP-07S, die man nur mit externer Antenne betreiben kann.

Das ESP-12 Modul ist meistens mit 4M Byte Flash ausgestattet. Als Antenne dient hier eine aufgedruckte Leiterschleife.

Die Minimal-Beschaltung zur Nutzung der AT-Firmware sieht für beide Module so aus:


Modul PinNummer in ArduinoNummer in NodeMCUNameBeschreibung
1  /RESETLow=Reset, hat schwachen Pull-Up Widerstand auf High
2  ADCAnaloger Eingang 0...1V
3  CH_PD (EN)Muss auf High gezogen werden, damit der Chip arbeitet. Low=Power Down
4160GPIO16Wenn mit /RESET verbunden, kann ein Timer den µC aus dem Deep-Sleep aufwecken.
5145GPIO14 (SCK)Normaler I/O Pin oder SPI Takt
6126GPIO12 (MISO)Normaler I/O Pin oder SPI Daten
7137GPIO13 (MOSI)Normaler I/O Pin oder SPI Daten
8  VCCSpannungsversorgung 3,3V 500mA
9-14Durch den Flash Speicher belegt, nicht verwendbar, nur beim ESP-12 ab Version E vorhanden
15  GNDMasse
16158GPIO15muss beim Start auf Low gezogen werden, flackert beim Start
1724GPIO2Ist mit der blauen LED verbunden, flackert beim Start, darf beim Start nicht auf Low gezogen werden
1803GPIO0Low beim Start aktiviert Firmware-Upload, muss zum normalen Start offen sein oder auf High liegen
1942GPIO4Normaler I/O Pin
2051GPIO5Normaler I/O Pin
2139RxD (GPIO3)serieller Eingang oder normaler I/O Pin
22110TxD (GPIO1)serieller Ausgang oder normaler I/O Pin, flackert beim Start, darf beim Start nicht auf Low gezogen werden
Auf dem ESP-07 Modul befindet sich eine rote Power-LED, die zusätzlich zu den oben genannten 25µA etwa 500µA Strom aufnimmt. Die blaue LED ist mit GPIO2 verbunden und leuchtet bei Low Pegel.

GPIO0, GPIO1, GPIO2 und GPIO15 haben beim Starten eine besondere Funktion, die ich im Kapitel Firmware Hochladen beschreibe.

Die Reichweite der on-board Antenne ist mit Smartphones vergleichbar. Mit einer guten externen Antenne soll das ESP-07 sogar weiter kommen.

NodeMCU Board

Das NodeMCU Board besteht im Grunde genommen aus einem ESP-12 mit USB-UART Interface und Spannungsregler. Alle Anschlusspins sind herausgeführt und beschriftet, daher spare ich mir hier die Tabellarische Auflistung. Das Board hat einen Reset Taster, und einen Taster an GPIO0, damit man Firmware hochladen kann (siehe unten). Für die erstem Programmierversuche (egal ob mit oder ohne NodeMCU Software) ist das die ideale Ausstattung, und zudem sehr preisgünstig.

USB-UART Kabel

Während das NodeMCU Board schon einen USB-UART Adapter enthält, brauchst du für andere Module ein USB-UART Kabel. Ich schleife immer zwei 2,2k Ohm Widerstände in die Signal-Leitungen ein, zum Schutz gegen Verpolung und Überspannung.

Für USB-UART Kabel mit altem oder gefälschtem PL2303 Chip habe ich hier einen passenden alten Windows Treiber, denn der aktuelle Treiber mag diese Chips nicht.

Deep-Sleep / Power-Down

Per Software kann man den Deep-Sleep Modus aktivieren. Die Programmausführung stoppt und alle I/O-Pins außer GPIO16 sind inaktiv. Man kann GPIO16 mit dem /RESET-Eingang verbinden und dann einen Timer aktivieren, so dass sich der Chip selbst resetted um diesen Zustand wieder zu verlassen.

Außerdem kann man den Chip durch Low Pegel am CH_PD Eingang (auch ENABLE genannt) in den Power-Down Modus versetzen, aber erst nachdem die Firmware gestartet ist. Die Firmware startet neu, sobald der CH_PD Pin zurück auf High geht.

Bei diesem Neustart geht der Inhalt des RAM verloren, außer ein paar hundert Bytes im Speicher der integrierten Echtzeituhr (RTC). Im Deep-Sleep und Power-Down Modus nimmt der ESP Chip zusammen mit seinem Flash Speicher ca. 25µA bei 3,3V auf.

Wenn der /RESET Eingang auf Low gezogen wird nimmt der Chip ca. 25mA auf. Wenn der CH_PD zu früh (bevor die Firmware gestartet ist) auf Low gezogen wird, nimmt der Chip ebenfalls ca. 25mA auf und die Firmware startet nicht. Die Firmware startet danach erst, wenn sowohl /RESET als auch CH_PD auf High gehen.

Firmware Hochladen

Der ESP Chip enthält einen unveränderlichen Bootloader, welcher ein Firmware-Upgrade über den seriellen Port ermöglicht. Beim Reset erwartet der Chip folgende Steuersignale:

Firmware-Upload:

Normaler Start: Alle anderen Kombinationen an diesen vier Pins sind für das Booten von SD Karte und für Test-Zwecke reserviert. Nach dem Start können diese Pins jedoch als frei programmierbare I/O Anschlüsse verwendet werden. Daraus ergibt sich die folgende sinnvolle Grundschaltung:

Die Widerstände vor GPIO0 und GPIO15 schützen vor Kurzschluss, falls man den Pin als Ausgang programmiert. Wenn der Wakeup-Jumper verbunden ist, kann ein Timer den ESP Chip aus dem Deep-Sleep Modus aufwecken.

Falls man GPIO2 beschaltet, ist zu beachten, dass er beim Starten durch einen Widerstand auf High gezogen werden muss und dass er kurzzeitig als Ausgang mit flackerndem Signal agiert. Beim ESP-12 Modul ist er außerdem mit der blauen LED verbunden, die bei Low Pegel leuchtet.

Um den ESP-Chip in den Firmware-Upload Modus zu versetzen, musst du beide Taster gleichzeitig drücken und dann den Reset Taster zuerst loslassen. Der ESP Chip erwartet dann Kommandos und Daten vom PC.

Es gibt zahlreiche grafische Programme zum hochladen der Firmware, aber die scheinen alle etwas zickig zu sein. Daher empfehle ich das Script esptool.py, welches meine beiden weiter unten bereitgestellten Firmware-Pakete enthalten. Zum Ausführen musst Du vorher Python installieren. Achte darauf dass es zur PATH Variable hinzugefügt wird. Anschließend installiere die Library für serielle Ports, indem du im CMD Fenster (Eingabeaufforderung) pip install pyserial eingibst.

Maßnahmen gegen Fehlfunktionen

Sporadische Fehlfunktionen werden meistens durch mangelhafte Stromversorgung verursacht.

Da die Stromaufnahme sehr starke Spitzen hat, empfehle ich dringend, einen 100µF (oder 220µF) Kondensator direkt an die VCC und GND Anschlüsse zu löten. Außerdem sollte man den Spannungsregler sorgfältig auswählen. Einige Low-Drop Regler und manche Schaltnetzteile sind ungeeignet, weil sie die extremen Stromschwankungen zu träge ausregeln. Ich habe gute Erfahrungen mit dem LF33CV gemacht, der eignet sich auch für den Betrieb an Batterien bis knapp unter 3 Volt.

Der direkte Betrieb an 3 NiMh Akkus oder einer Lithium Zelle ist nicht ratsam, da diese in vollem Zustand zu viel Spannung abgeben.

Die Masse Leitungen sollen möglichst kurz sein und sternförmig zusammen laufen. Achte darauf, dass alle steckbaren Verbindungen zur Stromversorgung gut fest sitzen. Steckbretter sind daher nicht so gut geeignet.

Damit der Chip sich nicht ungewollt zurück setzt, sollte man sowohl den RESET Pin als auch den CH_PD Pin entweder direkt oder durch einen 2,2k Ohm Widerstand mit VCC verbinden. Zu große Widerstände machen die Pins für elektromagnetische Wellen empfänglich. Das gilt übrigens auch für sämtliche weitere Elektronik in der Nähe des Funkmoduls.

Im Kapitel Fallstricke weiter unten findest Du weitere Hinweise, die bei der Programmierung eigener Firmware zu beachten sind.

Frühere Tests mit älteren Firmware Versionen ergaben mehrere Abstürze pro Woche. Aber mit dem SDK 1.5.4 bin ich zufrieden, denn mein aktueller Langzeit-Test läuft seit Mitte April 2017 ohne Ausfall durch.

Original AT-Firmware

Die AT-Firmware ermöglicht es, das Modul wie ein Modem zu benutzen. Durch das Absetzen von Befehlen auf der seriellen Schnittstelle konfiguriert man das Modul, baut Verbindungen auf und überträgt Daten. Das Modul dient also als Netzwerk-Schnittstelle für einen angeschlossenen Mikrocontroller.

Die AT-Firmware arbeitet auffällig langsam, was bitte nicht als Abwertung zu verstehen ist. Wenn ich per WLAN ein Kommando an den seriell angeschlossenen Mikrocontroller sende und auf dessen Antwort warte, dauert das unabhängig von der Paketgröße und Baudrate meistens 100 - 200ms. Allerdings muss man im WLAN Netz ohnehin mit Verzögerungen in dieser Größenordnung rechnen.

Falls deine AT-Firmware älter als 0.50.0.0 ist, rate ich zu einem Upgrade, da frühere Versionen noch ziemlich instabil liefen. Die Firma Espressif stellt ihre AT Firmware im bin Verzeichnis des SDK zur Verfügung. Dort befindet sich auch die Textdatei README.md, in der drin steht, welche Dateien abhängig von der Größe des Flash Speichers an welche Position geladen werden müssen.

Die Größe des Flash Speichers erkennt man anhand der letzten Ziffern seiner ID-Nummer. 04=512k Byte, 08=1M Byte, 16=2M Byte, 32=4M Byte. Das esptool kann diese ID-Nummer auslesen:

python esptool.py --port COM6 flash_id

Für Module mit nur 4M bit (=512k Byte) Flash Speicher muss man die AT-Firmware 0.50.0.0 vom SDK 1.4.0 verwenden. Das ist die letzte Version, die noch dort hinein passt. Für alle größeren Module kannst du die Firmware aus dem aktuellen SDK verwenden. Ich habe mir die AT-Firmware 1.1.0.0 vom SDK 1.5.4 gesichert, weil sie gut funktioniert, was noch lange nicht für jede Version gilt.

Für die Firmware aus dem SDK 1.4.0 und 1.5.4 sind die folgenden Befehle zum Hochladen der Firmware richtig:

4M bit (=512k Byte)python esptool.py --port COM6 write_flash 0x000000 noboot/eagle.flash.bin 0x040000 noboot/eagle.irom0text.bin 0x03e000 blank.bin 0x07e000 blank.bin 0x07c000 esp_init_data_default.bin
8M bit (=1M Byte)python esptool.py --port COM6 write_flash 0x000000 boot_v1.5.bin 0x001000 512+512\user1.1024.new.2.bin 0x0fc000 esp_init_data_default.bin 0x07e000 blank.bin 0x0fe000 blank.bin
16M bit (=2M Byte)python esptool.py --port COM6 write_flash 0x000000 boot_v1.5.bin 0x001000 512+512\user1.1024.new.2.bin 0x01fc000 esp_init_data_default.bin 0x07e000 blank.bin 0x1fe000 blank.bin
32M bit (=4M Byte)python esptool.py --port COM6 write_flash 0x000000 boot_v1.5.bin 0x001000 512+512\user1.1024.new.2.bin 0x03fc000 esp_init_data_default.bin 0x07e000 blank.bin 0x3fe000 blank.bin
Auf diese Weise kannst du auch andere nicht originale Firmware hochladen. Wobei diese meistens nur aus einer bin Datei bestehen, die an Adresse 0x00000 geladen wird. Im Zweifelsfall schaue in die dazugehörige Dokumentation. Keine Angst: Wenn das Hochladen der Firmware (warum auch immer) fehlschlägt, kann man es einfach nochmal versuchen. Also Taster drücken und nochmal das esptool starten.

AT Befehle

In diesem Absatz beschreibe ich nicht alle AT Befehle, was auch schwierig wäre, weil sie sich von Version zu Version unterscheiden. Die hier genannten Befehle funktionieren auf allen mir bekannten Firmware Versionen von 0.21.0.0 bis 1.1.0.0 Die vollständige Dokumentation findest Du als PDF Dokument auf der Webseite von Espressif, sowie in den obigen Firmware downloads. Beachte beim Programmieren, dass das exakte Format der Antworten je nach Firmware Version etwas variiert.

Zum Testen von Netzwerkverbindungen empfehle ich das Kommandozeilen-Programm Netcat. Außerdem solltest Du Dir unbedingt das Programm Wireshark anschauen, falls du es noch nicht kennst.

Als Terminalprogramm zur manuellen Eingabe der AT Befehle empfehle ich das Hammer Terminal. Stelle oben "Newline at CR+LF" ein und unten "Send on Enter CR-LF". Die Baudrate ist normalerweise 115200, ansonsten versuche es mit 57600 und 9600 Baud. Nach dem Hardware-Reset zeigt das Terminal Programm einige unlesbare Zeilen an (das ist normal), und dann "ready". Danach kannst du Befehle eintippen.

AT
wird einfach mit "OK" beantwortet. Der Befehl hat keine weitere Funktion, er eignet sich prima, um die serielle Verbindung zu testen.

ATE0
schaltet das Echo der Befehle aus. Dieser Befehl kann die Programmierung vereinfachen und die Geschwindigkeit geringfügig verbessern. Mit der Zahl 1 schaltet man das Echo wieder an. Für manuelles Testen lässt man das Echo am besten eingeschaltet.

AT+GMR
Zeigt die Version der Firmware an, zum Beispiel:

AT version:1.1.0.0(May 11 2016 18:09:56)
SDK version:1.5.4(baaeaebb)
compile time:May 20 2016 15:06:44
OK

AT+CWMODE=1
stellt ein, dass das Modul sich in ein bestehendes WLAN Netz einbuchen soll.

AT+RST
löst einen Software-Neustart aus. Dies ist nach dem Wechsel von CWMODE notwendig.

AT+CWLAP
listet alle erreichbaren Access Points auf. Zum Beispiel:

+CWLAP:(4,"EasyBox-4D2D18",-72,"18:83:bf:4d:2d:b2",2,-46)
+CWLAP:(4,"UPC2827302",-63,"88:f7:c7:52:40:9d",6,-22)
+CWLAP:(0,"Unitymedia WifiSpot",-64,"8a:f7:c7:52:40:9f",6,-22)
+CWLAP:(3,"Muschikatze",-45,"5c:49:79:2d:5b:cd",7,-4)
OK

AT+CWJAP="Muschikatze","supergeheim"
das Modul verbindet sich mit dem WLAN Netz "Muschikatze" und dem angegebenen WPA/WPA2 Passwort. Diese Einstellung wird automatisch dauerhaft gespeichert und beim nächsten Neustart aktiv.

AT+CWJAP?
zeigt an, mit welchem Access Point das Modul gerade verbunden ist. Zum Beispiel:

+CWJAP:"Muschikatze","5c:49:79:2d:5b:cd",7,-60
OK

AT+CIFSR
zeigt die IP-Adresse und MAC Adresse des Moduls an zum Beispiel:

+CIFSR:STAIP,"192.168.0.111"
+CIFSR:STAMAC,"5c:cf:7f:8b:a9:f1"
OK

AT+CIPMUX=1
Stellt ein, dass das Modul mehrere Verbindungen erlauben soll. In diesem Modus sind bis zu 5 gleichzeitige Verbindungen möglich. Die folgenden Beispiele setzen alle voraus, dass dieser Modus aktiviert wurde.
Das Gegenteil wäre der AT+CIPMUX=0, wo das Modul nur als Client und mit nur einer Verbindung genutzt werden kann. In diesem Fall entfällt bei den drauf folgenden Befehlen die Kanalnummer.

AT Firmware als TCP Server benutzen

AT+CIPSERVER=1,5000
dieser Befehl schaltet den Server ein, so dass er Verbindungen auf Port 5000 annimmt. Er kann danach (je nach Firmware Version) maximal 4 oder 5 Verbindungen gleichzeitig annehmen. Danach könntest du zum Beispiel mit Netcat eine Netzwerkverbindung zu diesem Mini-Server aufbauen:

nc 192.168.0.111 5000
Hallo
Welten!

Beim Verbindungsaufbau liefert das Modul folgende Meldungen:

0,CONNECT
+IPD,0,7:Hallo
+IPD,0,9:Welten!
"0,CONNECT" bedeutet, dass der TCP Server eine Verbindung auf Kanal 0 angenommen hat. "+IPD,0,7:" bedeutet, dass der Server auf Kanal 0 genau 7 Bytes empfangen hat. Nach dem Doppelpunkt folgen genau diese 7 Bytes.

AT+CIPSEND=0,18
> Ebenfalls Hallo!
Mit diesem Befehl sendest du eine Antwort an den Computer. Die 0 ist wieder die Kanalnummer und die 18 sind die Anzahl der zu sendenden Bytes (maximal 2048). Nachdem das Modul mit ">" Antwortet, gibst du die zu sendenden Zeichen (oder Bytes) ein. Das Modul bestätigt den Sendevorgang nach kurzer Zeit mit

SEND OK

AT+CIPCLOSE=0
mit diesem Befehl schließt du die Verbindung auf Kanal 0. Das Modul antwortet mit

0,CLOSED
OK

AT Firmware als TCP Client benutzen

AT+CIPSTART=0,"TCP","mail.stefanfrings.de",25
Kanal 0 baut eine TCP Verbindung zu dem angegebenen Server auf Port 25 auf. Anstelle des Hostnamens kannst du auch eine IP Adresse verwenden. Die Antwort lautet zum Beispiel:
0,CONNECT
OK
+IPD,0,96:220 wp039.webpack.hosteurope.de 
   ESMTP Host Europe Mail Service 
   Sat, 08 Apr 2017 23:37:19 +0200

Da dieser Mail-Server sofort antwortet, siehst du auch direkt eine +IPD Zeile. Der Text hinter dem Doppelpunkt ist die Antwort des Servers. Danach kann man mit AT+CIPSEND wie bereits oben beschrieben Daten an den Server senden. Mit AT+CIPCLOSE schließt man die Verbindung.

AT Firmware für UDP benutzen

Beim UDP Protokoll entfällt der Verbindungsaufbau, und damit auch die Begrenzung auf 5 gleichzeitige Verbindungen. Man sendet einzelne Nachrichten an die gewünschten Empfänger und hofft, dass sie zügig dort ankommen. Im Gegensatz zu TCP verzichtet das UDP Protokoll auf die Wiederholung von verlorenen Paketen. Es garantiert nicht einmal, dass alle Pakete in der richtigen Reihenfolge beim Empfänger ankommen.

UDP ist einfacher zu programmieren und nutzt die Übertragungsstrecke effizienter als TCP. Es eignet sich besonders gut zur regelmäßigen Übertragung von Messwerten, wenn einzelne Aussetzer tolerierbar sind (z.B. Temperaturfühler). Leider können Javascripte in Webseiten das UDP Protokoll nicht nutzen.

AT+CIPSTART=0,"UDP","0",0,3002,0
Nach diesem Befehl kann das Modul UDP Nachrichten auf Port 3002 von beliebigen Absendern empfangen. Es kann aber keine Nachrichten senden. Zum Test kannst du das Programm Netcat benutzen:

nc -u 192.168.0.111 3002
Jetzt geht's los!

Wobei du die IP-Adresse deines WLAN Moduls angeben musst. Wenn Du dann in Netcat etwas zum senden eintippst, wird das Modul den Empfang der Nachricht mit +IPD signalisieren.

AT+CIPSTART=0,"UDP","0",0,3002,2
Das Modul empfängt UDP Nachrichten auf Port 3002 von beliebigen Absendern, und es kann Antworten mit AT+CIPSEND zurück schicken. Die Antworten werden immer an den Computer gesendet, von dem zuletzt eine Nachricht empfangen wurde.

AT+CIPSTART=0,"UDP","192.168.0.5",3001,3002,0
Das Modul kann UDP Nachrichten auf Port 3002 von beliebigen Absendern empfangen. Mit dem AT+CIPSEND Befehl wird es Nachrichten an den Computer 192.168.0.5 Port 3001 senden.

Access-Point Modus

Wo kein WLAN Netz existiert, kann das ESP-Modul selbst ein kleines provisorisches Netz aufspannen. Bis zu 4 andere Geräte können sich dann mit dem Modul verbinden, aber sie können sich nicht gegenseitig sehen. Der Access-Point Modus eignet sich sehr gut dazu, ESP Module miteinander zu verbinden. Die Nutzung mit Smartphones und Laptops kann ich nicht empfehlen, da sie bei vielen Geräten unzuverlässig funktioniert. Im Access-Point Modus erreichst du das WLAN Modul unter der IP-Adresse 192.168.4.1.

AT+CWMODE=2
AT+CWSAP="ESP-Modul","supergeheim",5,3
AT+RST
Diese Befehlsfolge aktiviert den Access-Point Modus, und stellt den Namen des Netzes und das Passwort ein. Die 5 gibt den WLAN Kanal an (0-13), und die 3 legt fest, dass WPA2 Verschlüsselung verwendet wird. Diese Einstellung wird automatisch dauerhaft gespeichert und beim nächsten Neustart aktiv.

Es gibt auch einen Kombinierten Modus (AT+CWMODE=3), in welchem sich das Modul mit einem bestehenden WLAN Netz verbindet und außerdem ein eigenes zweites Netz aufspannt.

Möglichkeiten der Programmierung

Der chinesische Hersteller Espressif stellt ein SDK bereit, mit dem man eigene Programme in C schreiben kann, die direkt von dem Prozessor des WLAN Moduls ausgeführt werden. Dazu muss man sich allerdings mit Linux auskennen und darf nicht vor gruseliger Dokumentation zurück schrecken.

Das NodeMCU Projekt bemüht sich darum, die Programmierung stark zu vereinfachen, indem man auf LUA Scripte setzt. Allerdings leidet dieser Lösungsansatz an notorischem Speichermangel. Das Script und die Daten müssen in ca 40k Byte RAM gequetscht werden. Immerhin kann man ganz viele Scripte in den Flash Speicher laden, die sich gegenseitig aufrufen. Scrolle auf der Projektseite nach unten, dort gibt es einen Link zu dem "custom firmware build service", wo man sich eine individuell zusammengestellte Firmware erzeugen lässt.

Die meiner Meinung nach Bastel-freundlichste Lösung ist hingegen die ESP8266 Erweiterung für die Arduino IDE. Man programmiert dort in C++. Die Installation der IDE ist kinderleicht, dafür ist die Dokumentation leider nur ausreichend.

Alle drei Varianten haben eines gemeinsam: Es gibt keinen Debugger. Man kann nur durch Ausgeben von Log-Meldungen (auf dem seriellen Port) nachzuvollziehen, was das Programm gerade macht.

Bei Anwendungen, die mit Batterien mehrere Monate laufen sollen kann es hilfreich sein, neben dem ESP8266 zusätzlich einen kleineren Mikrocontroller (z.B. ATmega328) zu benutzen, welcher die Stromversorgung des ESP samt Spannungsregler unterbricht. Denn so ein ATmega kann direkt an der Batterie hängen und verbraucht im Standby viel weniger Strom. Außerdem hat er mehr nützliche I/O Pins, ist besser dokumentiert und kann professionell debuggt werden.

Erste Schritte mit Arduino

Das Arduino Plugin kombiniert das SDK des Herstellers mit C++ Klassen, um die Programmierung zu erleichtern. Das damit erzeugte Compilat enthält daher immer die originale Firmware des Herstellers plus das eigene Programm. Ich habe das Plugin in Version 2.3.0 getestet, welches auf dem Espressif SDK 1.5.4 basiert. Diese Kombination funktioniert zuverlässig.
  1. Installiere die Arduino IDE
  2. Starte dann die IDE und gehe ins Menü Datei/Voreinstellungen. Gebe ins Feld "Zusätzliche Boardverwalter-URLs" die Adresse http://arduino.esp8266.com/stable/package_esp8266com_index.json ein.
  3. Gehe ins Menü Werkzeuge/Board/Boardverwalter. Suche dort nach "esp8266". Installiere die Erweiterung "esp8266 by ESP8266 Community".
  4. Die IDE lädt dann eine große Menge Dateien herunter und installiert sie ins Verzeichnis C:\Users\DeinName\AppData\Local\Arduino15.
  5. Stelle im Werkzeuge Menü das "Generic ESP8266 Module" ein, bzw. was auch immer du für ein Modul vorliegen hast.
  6. Stelle dann darunter im Werkzeuge Menü die Details zum Modul ein. Beim ESP-12 Modul sollte es sein:
    • Flash Mode: QIO (benutzt mehr Leitungen zum Flash Chip, als das langsamere DIO).
    • Flash Frequency: 40Mhz
    • CPU Frequency: 80Mhz
    • Flash Size: 4M (3M SPIFFS), das bedeutet: Von 4M Byte Flash werden 3M Byte für ein Dateisystem benutzt, das Dir frei zur Verfügung steht.
    • Debug Port: disabled
    • Debug Level: keine
    • Reset Method: NodeMCU, du musst die Taster zum Resetten benutzen.
    • Upload Speed: 115200 (mehr solltest du nicht versuchen, wenn du Widerstände in den Leitungen hast).
    • Port: Der Port, den Windows deinem USB-UART Kabel zugewiesen hat (siehe Gerätemanager).
  7. Schreibe dein Programm (Arduino nennt es "Sketch").
  8. Compiliere das Programm, mit dem Menüpunkt Sketch/Überprüfen&Compilieren.
  9. Lade dein Programm hoch, mit dem Menüpunkt Sketch/Hochladen.

Lies die Dokumentation von Arduino und der ESP8266 Erweiterung.

Beispiel Sketches

Beispielprogramme für die ESP8266WiFi Library findest du im Verzeichnis C:\Users\DeinName\AppData\Local\Arduino15\packages\esp8266\libraries\ESP8266WiFi\examples oder in C:\Arduino\hardware\esp8266com\esp8266\libraries\ESP8266WiFi\examples. Dort findest du auch noch andere nützliche Beispiele für weitere Libraries, die Du Dir anschauen solltest.

Darüber hinaus zeige ich Dir hier Sketches, die Du für erste Versuche 1:1 in deine Arduino IDE kopieren kannst.

LED Blinker

Der erste Sketch lässt die blaue LED auf dem ESP-12 Modul blinken und gibt auf dem Seriellen Port immer abwechselnd "Tick" und "Tack" aus.
// Beim ESP-12 ist an GPIO2 eine blaue LED
#define LED 2

/** Wird beim Start einmal ausgeführt */
void setup() 
{
    pinMode(LED, OUTPUT);
    Serial.begin(115200);
}

/** Hauptschleife, wird wiederholt ausgeführt. */
void loop() 
{
    digitalWrite(LED, LOW);
    Serial.println("Tick");
    delay(500);

    digitalWrite(LED, HIGH);
    Serial.println("Tack");
    delay(500);
}
Dieser Sketch lässt noch 48k Bytes RAM und 3,7M Byte Flash übrig. Das ist eine Menge Platz für viele großartige Ideen.

UDP Server

Der zweite Sketch empfängt UDP Nachrichten und sendet sie als Echo zurück:
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>

// Beim ESP-12 ist an GPIO2 eine blaue LED
#define LED 2

// Name und Passwort des Access Points
#define SSID "Muschikatze"
#define PASSWORD "supergeheim"

// Der Server nimmt Verbindungen auf diesem Port an
#define PORT 5444
WiFiUDP udpServer;

// Puffer für hereinkommende UDP Nachrichten
char udp_buffer[WIFICLIENT_MAX_PACKET_SIZE+1];


/** Wird beim Start einmal ausgeführt */
void setup()
{
    // LED aus
    pinMode(LED, OUTPUT);
    digitalWrite(LED, HIGH);

    // Seriellen Port initialisieren
    Serial.begin(115200);
    
    // Gib dem seriellen Port Monitor von der Arduino
    // IDE ein bisschen Zeit.
    delay(500);

    // Benutze einen externen AP
    WiFi.mode(WIFI_STA);
    WiFi.begin(SSID, PASSWORD);

    // UDP Server starten
    udpServer.begin(PORT);
}


/** Hauptschleife, wird wiederholt ausgeführt. */
void loop()
{
    process_incoming_udp();
    check_ap_connection();
}


/** Empfange UDP Nachrichten und sende Echo zurück */
void process_incoming_udp()
{   
    if (udpServer.parsePacket()) 
    {
        // Nachricht abholen
        int len=udpServer.read(udp_buffer,sizeof(udp_buffer)-1);
        udp_buffer[len] = 0;
                
        // Nachricht anzeigen
        Serial.print("Empfangen von ");
        Serial.print(udpServer.remoteIP());
        Serial.print(":");
        Serial.print(udpServer.remotePort());
        Serial.print(": ");
        Serial.println(udp_buffer);
        
        // Nachricht als Echo zurück senden
        udpServer.beginPacket(udpServer.remoteIP(), udpServer.remotePort());
        udpServer.print("Echo: ");
        udpServer.print(udp_buffer); 
        udpServer.endPacket();
        
        // Auf bestimmte Befehle reagieren
        if (strstr(udp_buffer, "an"))
        {
            digitalWrite(LED, LOW);
            udpServer.println("LED ist an");
        }
        else if (strstr(udp_buffer, "aus"))
        {
            digitalWrite(LED, HIGH);
            udpServer.println("LED ist aus");
        }
    }    
}


/** Optional: Zeige an, wenn die Verbindung zum AP geändert wurde. */
void check_ap_connection()
{
    static wl_status_t preStatus = WL_DISCONNECTED;
    
    wl_status_t newStatus = WiFi.status();
    if (newStatus != preStatus)
    {
        if (newStatus == WL_CONNECTED)
        {
            digitalWrite(LED, LOW);
            
            // Die eigene IP-Adresse anzeigen
            Serial.print("AP Verbindung aufgebaut, lausche auf ");
            Serial.print(WiFi.localIP());
            Serial.print(":");
            Serial.println(PORT);
        }
        else
        {
            digitalWrite(LED, HIGH);
            Serial.println("AP Verbindung verloren");
        }
        preStatus = newStatus;
    }
}
Wenn die Verbindung zum AP aufgebaut wurde, geht die blaue LED an. Auf dem seriellen Port gibt das Programm hilfreiche Statusmeldungen aus. So kannst du den Server mit Netcat testen:
nc -u 192.168.0.111 5444
Affen machen alles nach
Echo: Affen machen alles nach
aus
LED ist aus
an
LED ist an
Der UDP Service ist sehr einfach zu programmieren, weil man sich darauf verlassen kann, dass Nachrichten 1:1 wie gesendet eintreffen, also weder zerstückelt noch zusammengefügt. Außerdem braucht man sich nicht um den Verbindungs-Aufbau kümmern. Der größte Nachteil ist, dass UDP Nachrichten manchmal unbemerkt verloren gehen - besonders in drahtlosen Netzen.

TCP Server

Der dritte Sketch zeigt einen TCP Server, der mehrere Verbindungen gleichzeitig bedient:
#include <ESP8266WiFi.h>

// Beim ESP-12 ist an GPIO2 eine blaue LED
#define LED 2

// Name und Passwort des Access Points
#define SSID "Muschikatze"
#define PASSWORD "supergeheim"

// Der Server nimmt Verbindungen auf diesem Port an
#define PORT 5333
WiFiServer tcpServer(PORT);

// Objekte für Verbindungen
#define MAX_TCP_CONNECTIONS 5
WiFiClient clients[MAX_TCP_CONNECTIONS];

// Puffer für hereinkommende Textzeilen
char tcp_buffer[MAX_TCP_CONNECTIONS][30];


/** Wird beim Start einmal ausgeführt */
void setup()
{
    // LED aus
    pinMode(LED, OUTPUT);
    digitalWrite(LED, HIGH);

    // Seriellen Port initialisieren
    Serial.begin(115200);
    
    // Gib dem seriellen Port Monitor von der Arduino
    // IDE ein bisschen Zeit.
    delay(500);

    // Benutze einen externen AP
    WiFi.mode(WIFI_STA);
    WiFi.begin(SSID, PASSWORD);

    // TCP Server starten
    tcpServer.begin();
}


/** Hauptschleife, wird wiederholt ausgeführt. */
void loop()
{
    handle_new_connections();
    process_incoming_tcp();
    check_ap_connection();
}


/** 
 * Lege neue Verbindungen im Array ab und 
 * sende eine Willkommens-Nachricht.
 */
void handle_new_connections()
{
    WiFiClient client = tcpServer.available();
    if (client)
    {
        Serial.print("Neue Verbindung von ");
        Serial.println(client.remoteIP().toString());
        
        // Finde einen freien Platz im Array        
        for (int i = 0; i < MAX_TCP_CONNECTIONS; i++)
        {
            if (!clients[i].connected())
            {
                // Freien Platz gefunden
                clients[i] = client;
                tcp_buffer[i][0]=0;
                Serial.print("Kanal=");
                Serial.println(i);
                
                // Mit einer Willkommes-Meldung begrüßen
                client.println("Hallo Welt!");
                return;
            }
        }
        Serial.println("Zu viele Verbindungen");
        client.stop();
    }
}


/** Empfange TCP Nachrichten und sende Echo zurück */
void process_incoming_tcp()
{   
    static int i=0;
    
    // Bei jedem Aufruf wird nur ein TCP client abgefragt
    if (clients[i].available())
    {
        // Eine Zeile einlesen
        if (append_until(clients[i],tcp_buffer[i],sizeof(tcp_buffer[i]),'\n'))
        {        
            // Nachricht anzeigen
            Serial.print("Empfangen von ");
            Serial.print(i);
            Serial.print(": ");
            Serial.print(tcp_buffer[i]);

            // Nachricht als Echo zurück senden
            clients[i].print("Echo: ");
            clients[i].print(tcp_buffer[i]);
            
            // Auf bestimmte Befehle reagieren
            if (strstr(tcp_buffer[i], "an"))
            {
                digitalWrite(LED, LOW);
                clients[i].println("LED ist an");
            }
            else if (strstr(tcp_buffer[i], "aus"))
            {
                digitalWrite(LED, HIGH);
                clients[i].println("LED ist aus");
            }    
            
            // Bereit machen für das Empfangen der nächsten Zeile
            tcp_buffer[i][0]=0;
        }
    }
    
    // Zum nächsten TCP client weiter schalten
    if (++i >= MAX_TCP_CONNECTIONS)
    {
        i=0;
    }
}


/**
 * Hänge Zeichen von einem Stream an einen Puffer an, bis das terminierende Zeichen
 * erreicht wurde. Wenn der Puffer überläuft, lies trotzdem weiter aber verwerfe
 * die überschüssigen Zeichen.
 *
 * @param source Der Quell-Stream.
 * @param buffer Der Ziel-Puffer, muss mit '\0' zerminiert sein.
 * @param bufSize Größe des Ziel-Puffers
 * @param terminator Das letzte Zeichen, das gelesen werden soll, zum Beispiel '\n'.
 * @return True wennn das terminierende Zeichen erreicht wurde.
 */
bool append_until(Stream& source, char* buffer, int bufSize, char terminator)
{
    int data=source.read();
    if (data>=0)
    {
        int len=strlen(buffer);
        do
        {
            if (len<bufSize-1)
            {
                buffer[len++]=data;
            }
            if (data==terminator)
            {
                buffer[len]=0;
                return true;
            }
            data=source.read();
        }
        while (data>=0);
        buffer[len]=0;  
    }
    return false;
}


/** Optional: Zeige an, wenn die Verbindung zum AP geändert wurde. */
void check_ap_connection()
{
    static wl_status_t preStatus = WL_DISCONNECTED;
    
    wl_status_t newStatus = WiFi.status();
    if (newStatus != preStatus)
    {
        if (newStatus == WL_CONNECTED)
        {
            digitalWrite(LED, LOW);
            
            // Die eigene IP-Adresse anzeigen
            Serial.print("AP Verbindung aufgebaut, lausche auf ");
            Serial.print(WiFi.localIP());
            Serial.print(":");
            Serial.println(PORT);
        }
        else
        {
            digitalWrite(LED, HIGH);
            Serial.println("AP Verbindung verloren");
        }
        preStatus = newStatus;
    }
}
Wenn die Verbindung zum AP aufgebaut wurde, geht die blaue LED an. Auf dem seriellen Port gibt das Programm hilfreiche Statusmeldungen aus. So kannst du die Anwendung mit Netcat testen:
nc 192.168.0.111 5333
Hallo Welt!
Ich bin Groot
Echo: Ich bin Groot
aus
LED ist aus
an
LED ist an
Bei TCP kann man sich im Gegensatz zu UDP einigermaßen sicher sein, dass innerhalb einer Verbindung keine Nachrichten verloren gehen und dass die Reihenfolge nicht durcheinander gerät. Aber eine Textzeile kommt unter Umständen zerteilt in mehreren Segmenten an, selbst wenn sie kurz ist. Oder ein Segment liefert zwei Textzeilen, die ursprünglich einzeln gesendet wurden.

Deswegen habe ich die Funktion append_until() entwickelt, die Eingaben Zeilenweise unabhängig von der Segmentierung einsammelt. Im Gegensatz zu Arduinos readStringUntil() hat sie folgende Vorteile:

WiFi Config Service

Bei den obigen Beispielen wurden die Zugangsparameter für den WLAN Access Point einfach fest in den Quelltext geschrieben. Für Nicht-Entwickler ist diese Vorgehensweise jedoch ungeeignet. Eigentlich wurde für diesen Zweck WPS erfunden, doch das hat bei mir so oft nicht funktioniert, dass ich es gar nicht mehr verwende.

Eine naheliegende Alternative wäre, ein provisorisches WLAN Netz zu erzeugen und darüber eine Webseite zur Konfiguration bereit zu stellen. Mein kleines WiFi-Monitor Projekt enthält die Klasse ConfigService, welche genau das tut. An dem folgenden verkürzten Quelltext siehst du, wie einfach der WiFi Config Service anzuwenden ist:

#include "ConfigService.h"

ConfigService configService(80);

void setup()
{
    configService.begin(5,"WiFi Monitor","");
    ...
}

void loop()
{
    configService.run();
    ...
}
Nach dem Einschalten der Stromversorgung aktiviert das Programm für 5 Minuten ein provisorisches Netz mit dem Namen "WiFi Monitor" ohne Passwort. Du kannst deinen Computer oder Smartphone mit diesem Netz verbinden und dann die Seite http://192.168.4.1 aufrufen:

Dort kannst du nun die Zugangsdaten deiner Fritz Box (oder was auch immer du für einen WLAN Router hast) eingeben und absenden. Wenn sie richtig sind, baut das Modul sofort eine Verbindung zum Access Point auf. Das Hauptprogramm in diesem Beispielprojekt testet die Erreichbarkeit des konfigurierten Webservers und zeigt den Status anhand einer bunten LED an.

Fallstricke

Wenn dein Programm unzuverlässig läuft, kontrolliere zuerst meine Ratschläge aus dem Kapitel Maßnahmen gegen Fehlfunktionen. Wenn das alles Ok ist, dann kontrolliere die folgenden Aspekte in deinem eigenen Programm:

Es ist wichtig, das die Firmware genügend Rechenzeit ab bekommt, sonst fällt das Modul aus. Alle eigenen Programmteile müssen spätestens nach 50ms (empfohlen werden 20ms) die Kontrolle an die Firmware abgeben, indem entweder die loop() Funktion verlassen wird, oder delay(ms) oder yield() aufgerufen wird.

Für eigene Programme stehen nur ungefähr 4k Byte Stack zur Verfügung. Wenn lokale Variablen in Prozeduren mehr Platz belegen, stürzt das Programm ab. Größere Datenmengen (z.B. Puffer für Daten) sollen daher vorzugsweise global deklariert werden, damit sie außerhalb des Stack liegen.

Dynamische Speicherverwaltung auf dem Heap verlangt besondere Sorgfalt, damit der Heap nicht fragmentiert wird. Mein Tipp: Schreibe Dein Programm so, dass es gar keinen Heap belegt. Verzichte möglichst auf malloc(), calloc(), den new Operator und die Verwendung der String Klasse.

Wenn man Daten sendet, wird aus jedem Client::print() und Client::write() Aufruf ein einzelnes Ethernet Paket. Viele kleine Pakete reduzieren die Performance, da sie genau so lange dauern, wie große Pakete. Die maximale Paketgröße steht in WIFICLIENT_MAX_PACKET_SIZE und ist 1460 Bytes. Wenn man in einem Aufruf zu viele Daten sendet, teilt die Firmware sie automatisch auf mehrere Pakete auf und wartet ggf. auch darauf, dass Platz im Sendepuffer frei wird.

Da der Empfangspuffer mehrere Pakete aufnehmen kann, muss man bei der Programmierung davon ausgehen, dass Client::available() und Client::readBytes() einige Kilobytes zurück liefern können, vor allem wenn die Daten schnell aufeinander folgend eintreffen. Passe beim Auslesen der Daten auf, weder deine Puffer noch den Stack zu überladen.

Benutze die Methoden readString() und readStringUntil() am besten gar nicht, weil sie beliebig lange Strings ansammeln, die leicht einen Speicher-Überlauf auslösen.

Verlasse Dich nicht darauf, dass gesendete TCP Nachrichten den Empfänger in der gleichen Segmentierung erreichen, wie sie gesendet wurden. Die Netzwerk-Komponenten dürfen die Segmente des TCP Datenstromes zerlegen und neu zusammenfügen. In dieser Diskussion wurden die Effekte der Segmentierung sehr schön erklärt.

Beim UDP Protokoll kann man nur einzelne Nachrichten mit maximal 1460 Bytes senden oder empfangen. Unter Umständen schränken Netzwerk-Komponenten die maximale Paketgröße weiter ein. Im heimischen WLAN Netz kannst du dich jedoch auf die 1460 Bytes verlassen.

SSID und Passwort von AP und softAP werden automatisch dauerhaft gespeichert, aber nur wenn sie gültig sind. Das Passwort muss entweder ein Leerstring ("") sein oder mindestens 8 Zeichen lang sein.

NetBeans als besseren Text-Editor für Sketches verwenden

Der Text-Editor von Arduino ist gelinde gesagt knapp ausgestattet. NetBeans hat einen viel besseren Editor, deswegen nutze ich diesen gerne. NetBeans erkennt viele Fehler schon direkt während der Eingabe und hilft Dir beim Tippen. Wenn Du zum Beispiel "Serial." eintippst, listet NetBeans alle Felder und Methoden der Serial Klasse auf. Wenn Du die Strg-Taste gedrückt hälst und dann auf eine #include Datei, einen Klassen-Namen oder einen Methoden-Namen klickst, dann öffnet NetBeans die zugehörige Datei und springt zu der entsprechenden Zeile. Im Navigator Fenster zeigt NetBeans die Struktur der aktuellen Datei an, mit deren Hilfe du blitzschnell zu anderen Codeabschnitten springen kannst.

Einmalige Einrichtung

Installiere dazu Java JDK 8 und NetBeans in der Variante für C/C++. Wenn du NetBeans bereits für andere Programmiersprachen installiert hast, dann genügt es, das C/C++ Plugin hinzuzufügen.

Starte NetBeans und gehe dann ins Menü Tools/Options/Miscellaneous/Files.

Finde heraus, in welches Verzeichnis die ESP8266 Erweiterung für Arduino installiert wurde. Wahrscheinlich befindet sie sich entweder in C:\Users\DeinName\AppData\Local\Arduino15\packages\esp8266 oder in C:\Arduino\hardware\esp8266com\esp8266. Bei der folgenden Konfiguration sollst du anstelle von <esp8266> den vollständigen Pfad eingeben.

Gehe dann ins Menü Tools/Options/C/C++/Build Tools.

Wechsele dann zu dem Reiter "Code Assistance". Wähle bei "Tool Collection" die "Arduino_ESP8266" aus und füge dann darunter beim C++ Compiler folgende "Include Directories" hinzu:

Das genügt erstmal für die obigen Beispiel Sketches. In Zukunft wirst du eventuell noch weitere Verzeichnisse unter <esp8266>\libraries hinzufügen müssen, damit NetBeans deine #include Anweisungen auswerten kann.

In der Arduino IDE sollst du nun in das Menü Datei/Voreinstellungen gehen und die Option "Externen Editor verwenden" einschalten.

Arduino Sketch in Netbeans öffnen

Erstelle in deinem Arduino Projektverzeichnis (wo sich die *.ino Datei befindet) eine leere Datei mit dem Namen "Makefile" (achte dabei auf die groß/klein-Schreibung). Gehe danach in NetBeans auf den Menüpunkt File/New Project.

Wenn du vorher alles richtig konfiguriert hast, kannst du nun in NetBeans deinen Sketch (die *.ino Datei) öffnen und bearbeiten. Die obigen Beispiel-Sketche sind fehlerfrei, sie eignen sich daher sehr gut, die Konfiguration von NetBeans zu überprüfen. Es sollten keine gelben oder gar rote Markierungen erscheinen.

Ich finde diese Anleitung gut, wo die Bedienung des Editors erklärt wird.

Um den Sketch zu überprüfen (compilieren) und hochzuladen musst du weiterhin die Arduino IDE verwenden.

Manchmal funktionieren die ganzen erweiterten Editor-Funktionen bei einzelnen Dateien nicht. Klicke dann in der Projekt-Ansicht mit der rechten Maustaste auf den Dateinamen und dann auf Properties. In dem folgenden Dialog musst Du die Option "Add To Parse" einschalten, dann funktioniert es.

Kritik

Der Hersteller hat seinen Chip zu früh und mit falschen Versprechungen (insbesondere bezüglich Stromaufnahme und Leistungsdaten) vermarktet, während die Firmware noch extrem instabil war. In den ersten zwei Jahren war sie noch so unzuverlässig, daß an eine ernsthafte Nutzung nicht zu denken war.

Der ESP8266 Chip kann nur mit der closed-source Firmware des Herstellers genutzt werden, da viele wichtige Details der Hardware geheim gehalten werden. Jede Anwendung ist zwangsläufig auf Gedeih und Verderb den Eigenheiten dieser Firmware ausgeliefert.

Im Deep Sleep Modus nimmt der Chip (mit Flash Speicher) ca. 25µA auf, dazu kommt die Stromaufnahme des unvermeidbaren Spannungsreglers. Das ist ziemlich viel, denn von anderen Mikrocontrollern (z.B. ATmega328) bin ich Werte um 1µA gewohnt, und die laufen ohne Spannungsregler direkt an der Batterie. Beim Aufwachen aus dem Deep-Sleep Modus geht der RAM Inhalt verloren und die ganze Firmware muss neu booten. Dies beschränkt den Nutzen dieser Betriebsart doch sehr.

Im "Power Off" Modus nimmt der Chip angeblich 0,5µA auf, es fehlt allerdings jede Erklärung, wie man diesen Modus erreicht und was er bedeutet. Die CH_PD Leitung ist es jedenfalls nicht.

Als maximale Stromaufnahme gibt der Hersteller 170mA an, aber mehrere Leute (auch ich) haben unabhängig voneinander Werte im Bereich 300 bis 500mA gemessen.

Ziemlich irritierend finde ich, dass der Chip ursprünglich für 3,0 bis 3,6V spezifiziert war, aber laut aktuellem Datenblatt bereits ab 2,5V funktionieren soll. Immerhin haben meine Experimente ergeben, dass die 2,5V stimmen - sogar ohne merklichen Verlust von Reichweite. Mein ESP-12F startet sogar ab 2,3V und läuft danach weiter, bis die Spannung unter 2,0V fällt.

Der ADC Eingang misst 0 bis 1 Volt mit 10 Bit, aber wegen der Einstreuung des eigenen HF Signals muss man mit 0,2V (!) Abweichung rechnen. Eigentlich kann man den Eingang nur gebrauchen, wenn der HF Teil deaktiviert ist.

Der Watchdog erfüllt seinen Zweck nicht gut. Bei Programmfehlern (z.B. Stack Überlauf) kommt es sehr häufig vor, dass der Chip nach einem Watchdog-Reset nicht mehr richtig startet. Ein externer Hardware Reset funktioniert aber zuverlässig.