Der WiFi Monitor überwacht die Erreichbarkeit eines Webservers und zeigt den Status mit einer bunten LED an (Quelltext)
Startseite

ESP8266 und ESP8285 Module Anleitung

Auf dieser Seite findest du alles was man für den Einstieg wissen muss, um mit diesen Chips eigene WLAN-fähige Geräte zu bauen und zu programmieren.

Die ESP8266 und ESP8285 Chips vom chinesischen Hersteller Espressif sind 32bit Mikrocontroller mit integrierter Wi-Fi Schnittstelle. Ihre Firmware basiert auf dem Lightweight IP stack, der ursprünglich von Adam Dunkels entwickelt wurde. Es werden zahlreiche handliche Module mit diesen Mikrochips verkauft.

Der wesentliche Unterschied zwischen den beiden Chips ist, dass der ESP8266 einen externen Flash Speicher benötigt, während der neuere ESP8285 über 1 MByte internem Flash Speicher verfügt.

Normalerweise werden die kleinen 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 Mikrocontroller sendet dann Befehle an das Modul, um Verbindungen aufzubauen und Daten zu übertragen. 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. Mehr dazu weiter unten.

Mit Preisen ab ca. 2 Euro sind die ESP Module eine sehr preisgünstige Netzwerk-Anbindung zum Basteln.

Technische Daten

(gilt für beide Chips)
1) Im Soft-AP Modus können die WLAN Clients nur mit dem ESP kommunizieren, nicht miteinander.

Die Basis-Firmware belegt ca. 250 kByte vom Flash Speicher. Sie lässt 50 kByte RAM für eigene Anwendungen frei. Der Chip kann maximal 1 MByte vom Flash als Programmspeicher nutzen, der Rest kann für Daten verwendet werden.

Module

Ein Hinweis vorab: Der ENABLE Pin wird an anderen Stellen auch CH_PD, CHIP_PU, CHIP_EN, oder kurz EN genannt.

ESP-1 und ESP-01 Modul

Das ESP-01 Modul basiert auf dem ESP8266. Es wird mit 512 kByte (in blau) oder 1 MByte (in schwarz) Flash Speicher verkauft. Die rote Power-LED nimmt etwa 0,5 mA Strom auf, die blaue LED hängt an GPIO2. Das ESP-1 Modul basiert auf dem ESP8285. Es hat 1 MByte Flash Speicher und einen Deckel zur Abschirmung. Das ESP-1 Modul hat nur eine blaue LED an GPIO2.

Beide Module sind funktional identisch, das ESP-1 ist allerdings etwas langsamer. Die kleine 8-Polige Stiftleiste ist das auffälligste Merkmal dieser Module. Dadurch lassen sie sich leicht mit einem kurzen Flachkabel absetzen, um den Empfang zu optimieren.

Die Minimal-Beschaltung zur Nutzung der AT-Firmware sieht so aus:


Modul PinArduino PinNameBeschreibung
13RxD (GPIO3)serieller Eingang oder normaler I/O Pin
2VCCSpannungsversorgung 3,3 V
30GPIO0Low beim Start aktiviert Firmware-Upload, muss zum normalen Start offen sein oder auf High liegen
4RESETLow=Reset, hat schwachen Pull-Up Widerstand auf High
52GPIO2 (TxD)Ist mit der blauen LED verbunden, die bei LOW Pegel leuchtet. Flackert beim Start. Darf beim Start nicht auf Low gezogen werden. Ausgang vom zweiten UART, der nur Ausgabe kann.
6CHIP_ENMuss auf High gezogen werden, damit der Chip arbeitet. Low=Chip Power Down, High=Chip Enabled
7GNDMasse
81TxD (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

Die Anschlussleisten beider Module haben 2,54 mm Raster.

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 Module

Das ESP-07 Modul ist normalerweise mit einem 1 MByte Flash Chip, einer Keramikantenne und einer Steckbuchse für externe Antennen ausgestattet. Um die externe Antenne nutzen zu können, muss man den gezeigten Kondensator entfernen. Die rote Power-LED nimmt etwa 0,5 mA Strom auf. Die blaue LED hängt an GPIO2. Das ESP-07s Modul hat ebenfalls 1 MByte Flash, aber keine LED's und keine Antenne. Es kann nur mit externer Antenne betrieben werden. Das ESP-12 Modul ist meistens mit 4 MByte Flash ausgestattet. Als Antenne dient hier eine aufgedruckte Leiterschleife. Die blaue LED hängt an GPIO2, das Modul hat keine Power-LED.

Das abgebildete Modell ESP-12F hat eine etwas bessere Antenne, als das 12E Modell.

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


Modul PinArduino PinESP NameBeschreibung
1RESETLow=Reset, hat schwachen Pull-Up Widerstand auf High
217ADCAnaloger Eingang 0 bis 1 V
3CHIP_ENMuss auf High gezogen werden, damit der Chip arbeitet. Low=Chip Power Down, High=Chip Enabled
416GPIO16Wenn mit RESET verbunden, kann ein Timer den µC aus dem Deep-Sleep aufwecken.
514GPIO14 (SCK)Normaler I/O Pin oder SPI Takt
612GPIO12 (MISO)Normaler I/O Pin oder SPI Daten
713GPIO13 (MOSI)Normaler I/O Pin oder SPI Daten
8VCCSpannungsversorgung 3,3 V
9Durch den Flash Speicher belegt, nicht verwendbar*, nur beim ESP-12E und ESP-12F vorhanden.

*) Wenn man den Flash Speicher im langsamen DIO Modus anspricht, kann man Pin 12 eingeschränkt als GPIO10 nutzen. Die Einschränkung ist, dass ein Low Pegel den Schreibschutz des Flash Speichers aktiviert. Pin 11 = GPIO9 kann man nicht verwenden, denn ein Low Pegel würde den Flash Speicher deaktivieren.

10
11
12
13
14
15GNDGemeinsame Masse
1615GPIO15 (CS)Normaler I/O Pin oder SPI Chip Select, muss beim Start auf Low gezogen werden, flackert beim Start
172GPIO2 (TxD)Ist mit der blauen LED verbunden, die bei LOW Pegel leuchtet. Flackert beim Start. Darf beim Start nicht auf Low gezogen werden. Ausgang vom zweiten UART, der nur Ausgabe kann.
180GPIO0Low beim Start aktiviert Firmware-Upload, muss zum normalen Start offen sein oder auf High liegen
194GPIO4Normaler I/O Pin
205GPIO5Normaler I/O Pin
213RxD (GPIO3)serieller Eingang oder normaler I/O Pin
221TxD (GPIO1)serieller Ausgang oder normaler I/O Pin, flackert beim Start, darf beim Start nicht auf Low gezogen werden

Die Anschlussleisten beider Module haben 2 mm Raster. Die Reichweite der on-board Antenne ist mit Smartphones vergleichbar. Mit einer guten externen Antenne soll das ESP-07 sogar weiter kommen. Der Antennen-Stecker heisst SMT, U.FL oder IPEX. Achtung: die gibt es in unterschiedlichen Größen!

PSF-A85 und PSF-B85 Modul

Das PSF-A85 Modul von der Firma Itead hat einen ESP8285 mit Stecker für eine externe Antenne. Der Antennen-Stecker heisst SMT, U.FL oder IPEX. Achtung: die gibt es in unterschiedlichen Größen! Das PSF-B85 Modul hat hingegen eine sehr kleine keramische Antenne on-board.

Pinbelegung:

Modul PinArduino PinESP NameBeschreibung
1AntAntenne (nur PSF-85A)
217ADCAnaloger Eingang 0 bis 1 V
3CHIP_ENMuss auf High gezogen werden, damit der Chip arbeitet. Low=Chip Power Down, High=Chip Enabled
416GPIO16Wenn mit RESET verbunden, kann ein Timer den µC aus dem Deep-Sleep aufwecken.
514GPIO14 (SCK)Normaler I/O Pin oder SPI Takt
612GPIO12 (MISO)Normaler I/O Pin oder SPI Daten
713GPIO13 (MOSI)Normaler I/O Pin oder SPI Daten
815GPIO15 (CS)Normaler I/O Pin oder SPI Chip Select, muss beim Start auf Low gezogen werden, flackert beim Start
92GPIO2 (TxD)Flackert beim Start. Darf beim Start nicht auf Low gezogen werden. Ausgang vom zweiten UART, der nur Ausgabe kann.
100GPIO0Low beim Start aktiviert Firmware-Upload, muss zum normalen Start offen sein oder auf High liegen
114GPIO4Normaler I/O Pin
12GNDMasse
139GPIO9Normaler I/O Pin
1410GPIO10Normaler I/O Pin
15Durch den internen Flash Speicher belegt, nicht verwendbar
16
17
18
195GPIO5Normaler I/O Pin
20GNDGemeinsame Masse
213RxD (GPIO3)serieller Eingang oder normaler I/O Pin
221TxD (GPIO1)serieller Ausgang oder normaler I/O Pin, flackert beim Start, darf beim Start nicht auf Low gezogen werden
23VCCSpannungsversorgung 3,3 V
24RESETLow=Reset, hat schwachen Pull-Up Widerstand auf High

Diese beiden Module haben im Vergleich zu allen anderen hier vorgestellten Modulen zwei zusätzliche I/O Pins frei, nämlich GPIO9 und GPIO10. Die Anschlussleisten haben 1,27 mm Raster, sie sind daher sehr klein und schwieriger zu löten.

Die Minimal-Beschaltung zur Nutzung der AT-Firmware ist abgesehen von der anderen Pin-Reihenfolge mit dem obigen ESP-12 Modul identisch. Weiter unten finden Sie eine etwas umfangreichere Grundschaltung.

NodeMCU Board

Das NodeMCU Board besteht aus einem ESP-12 Modul mit Spannungsregler und USB-UART Interface. Der Flash Speicher ist 4 Megabytes groß. Für die erstem Programmierversuche ist das die ideale Ausstattung.


Board J2NodeMCU LabelArduino PinESP NameBeschreibung
1VINSpannungsversorgung 5 bis 9 V
2GGNDGemeinsame Masse
3RSTRESETHat 12 kΩ Pull-Up Widerstand und einen Taster mit 470 Ω nach GND
4ENCHIP_ENLow=Chip Power Down, High=Chip Enabled, hat 12 kΩ Pull-Up
53VVCCSpannungsversorgung 3,3 V
6GGNDGemeinsame Masse
7Durch den Flash Speicher belegt, nicht verwendbar *

*) Wenn man den Flash Speicher im langsamen DIO Modus anspricht, kann man J2 Pin 12 eingeschränkt als GPIO10 nutzen. Die Einschränkung ist, dass ein Low Pegel den Schreibschutz des Flash Speichers aktiviert. Pin 11 = GPIO9 kann man nicht verwenden, denn ein Low Pegel würde den Flash Speicher deaktivieren.

8
9
10
11
12
13Reserviert
14
15A017ADCAnaloger Eingang für 0 bis 3,2 V weil mit Spannungsteiler 220 kΩ + 100 kΩ

Board J1NodeMCU LabelArduino PinESP NameBeschreibung
13VVCCSpannungsversorgung 3,3 V
2GGNDGemeinsame Masse
3TX (D10)1TxD (GPIO1)Serieller Ausgang des ESP über 470 Ω mit dem USB-UART verbunden, flackert beim Start, darf beim Start nicht auf Low gezogen werden
4RX (D9)3RxD (GPIO3)Serieller Eingang des ESP über 470 Ω mit dem USB-UART verbunden
5D815GPIO15 (CS)Normaler I/O Pin oder SPI Chip Select, muss beim Start Low sein, hat 12 kΩ Pull-Down Widerstand, flackert beim Start
6D713GPIO13 (MOSI)Normaler I/O Pin oder SPI Daten
7D612GPIO12 (MISO)Normaler I/O Pin oder SPI Daten
8D514GPIO14 (SCK)Normaler I/O Pin oder SPI Takt
9GGNDGemeinsame Masse
103VVCCSpannungsversorgung 3,3 V
11D42GPIO2 (TxD)Ist mit der blauen LED verbunden, die bei LOW Pegel leuchtet. Flackert beim Start. Muss beim Start high sein. Hat 12 kΩ Pull-Up Widerstand. Ausgang vom zweiten UART, der nur Ausgabe kann.
12D30GPIO0Low beim Start aktiviert Firmware-Upload, hat 12 kΩ Pull-Up Widerstand und einen Taster mit 470 Ω nach GND, flackert beim Start
13D24GPIO4Normaler I/O Pin
14D15GPIO5Normaler I/O Pin
15D016GPIO16Ist mit der blauen LED verbunden, die bei Low leuchtet. Die optionale Brücke R3 verbindet diesen Pin mit RESET, damit kann ein Timer den µC aus dem Deep-Sleep aufwecken.

In Arduino kann man die NodeMCU Labels nutzen, ich empfehle allerdings, die Arduino Pin Nummern zu verwenden da sie den GPIO Nummern des Chips entsprechen.

Man kann es wahlweise am 3,3V Eingang mit 2,5 bis 3,6 V betreiben, oder am 5 V Eingang mit 5 bis 9 V, oder über das USB Kabel mit 5 V. Eine Diode verhindert, dass Strom vom 5V Eingang zum USB Anschluss fließt. Der Eingebaute Spannungsregler hat für externe Erweiterungen maximal 300 mA Leistungsreserve bei 5 V Eingangsspannung. Für Batteriebetrieb eignet sich das Board eher nicht, da es eine Ruhestromaufnahme von etwa 15 mA hat.

Auf einem Steckbrett läuft das Board zuverlässiger, wenn man die Stifte entfernt, die zum Flash Speicher führen.

Die Reset Leitung und GPIO0 können durch den USB-UART angesteuert werden. Damit aktiviert die Arduino IDE den Firmware-Upgrade Modus vollautomatisch:

DTRRTSRESETGPIO0
AusAusHighHigh
EinEinHighHigh
AusEinLowHigh
EinAusHighLow

Im Schaltplan sind dafür die beiden über Kreuz verbundenen Transistoren zuständig. Alternativ kann man den Firmware-Upgrade Modus manuell aktivieren, indem man beide Tasten drückt und dann den Reset-Taster zuerst loslässt.

Wemos D1 Mini

Das Wemos D1 Mini Board gibt es in folgenden Versionen:

VersionESP ChipFlash MByteLED an GPIO2AntenneLithium Laderegler
Wemos D1 Mini Lite v1ESP82851jaLeiterschleifenein
Wemos D1 Mini v2ESP-12 Modul (=ESP8266)4neinLeiterschleifenein
Wemos D1 Mini v3ESP82664jaLeiterschleifenein
Wemos D1 Mini Pro v1 (oder -16)ESP826616jaKeramikantenne und ext. Antennenanschlussnein
Wemos D1 Mini Pro v2ESP826616jaKeramikantenne und ext. Antennenanschlussja

Die oberen vier Boards haben die gleichen Abmessungen, das letzte mit Laderegler ist etwas länger. Alle Versionen haben einen USB-UART (CH-340) und einem Low-Drop Spannungsregler. Alle freien I/O Pins des ESP Chips sind herausgeführt, aber nicht der ENABLE Pin.

Die Pinbelegung ist bei allen Wemos D1 Mini Boards gleich:

Board PinNodeMCU LabelArduino PinESP NameBeschreibung
1RSTRESETHat 10 kΩ Pull-Up Widerstand und einen 100 nF Kondensator nach GND
2A017ADCAnaloger Eingang für 0 bis 3,2 V weil mit Spannungsteiler 220 kΩ + 100 kΩ
3D016GPIO16Wenn mit RESET verbunden, kann ein Timer den µC aus dem Deep-Sleep aufwecken. Die Versionen Mini v3 und Pro v2 haben dazu auf der Rückseite eine "Sleep" Lötbrücke.
4D514GPIO14 (SCK)Normaler I/O Pin oder SPI Takt
5D612GPIO12 (MISO)Normaler I/O Pin oder SPI Daten
6D713GPIO13 (MOSI)Normaler I/O Pin oder SPI Daten
7D815GPIO15 (CS)Normaler I/O Pin oder SPI Chip Select, muss beim Start Low sein, hat 10 kΩ Pull-Down Widerstand, flackert beim Start
83V3VCCSpannungsversorgung 3,3 V
95VSpannungsversorgung 4 bis 7 V
10GGNDGemeinsame Masse
11D42GPIO2 (TxD)Alle außer Mini v2 haben eine blaue LED, die bei Low Pegel leuchtet. Flackert beim Start. Muss beim Start high sein. Hat 10 kΩ Pull-Up Widerstand. Ausgang vom zweiten UART, der nur Ausgabe kann.
12D30GPIO0Low beim Start aktiviert Firmware-Upload, hat 10 kΩ Pull-Up Widerstand, flackert beim Start
13D24GPIO4Normaler I/O Pin
14D15GPIO5Normaler I/O Pin
15RX (D9)3RxD (GPIO3)Serieller Eingang des ESP über 470 Ω mit dem USB-UART verbunden
16TX (D10)1TxD (GPIO1)Serieller Ausgang des ESP über 470 Ω mit dem USB-UART verbunden, flackert beim Start, darf beim Start nicht auf Low gezogen werden

In Arduino kann man die NodeMCU Labels nutzen, ich empfehle allerdings, die Arduino Pin Nummern zu verwenden da sie den GPIO Nummern des Chips entsprechen.

Man kann es wahlweise am 3,3V Eingang mit 2,5 bis 3,6 V betreiben, oder am 5 V Eingang mit 3 bis 7 V, oder über das USB Kabel mit 5 V. Eine Diode verhindert, dass Strom vom 5V Eingang zum USB Anschluss fließt.

Die Ruhestromaufnahme des Boardes liegt je nach Variante zwischen 200 und 300 µA, so dass es für Batteriebetrieb bedingt geeignet ist. Der Spannungsregler reicht gerade für den WLAN Chip aus, er darf extern nur minimal belastet werden (50 mA bei 5 V).

Der Reset Taster zieht den Reset-Pin ohne Schutzwiderstand direkt auf GND. Außerdem besitzt das Board die gleiche Reset Schaltung wie das NodeMCU Board, zum automatischen Aktivieren des Firmware-Upgrade Modus. Das Wemos D1 Mini hat keinen "Flash" Taster.

Der Analoge Eingang A0 ist mit einem Spannungsteiler (220kΩ + 100kΩ) ausgestattet, damit man Spannungen bis zu 3,2 V messen kann.

Dokumentation des Herstellers.

WIFI Kit 8

Das WIFI Kit 8 (alias Heltec HTIT-W8266 oder Wemos TTGO ESP8266) aus China hat 4 MByte Flash Speicher, sowie ein winzig kleines 0,91" OLED Display mit 128x32 Pixeln. Darauf kann man Grafiken und 4x21 Zeichen Text ausgeben. Der Display Controller vom Typ SSD1306 ist über I²C mit dem ESP8266 verbunden. Für die USB Buchse wurde der Chip CP2104 von Silabs verwendet.

Viele Händler verkaufen diese Boards mit falsch beschrifteten Pins und falschen Anschlussplänen! Die folgenden Zeichnungen zeigen die richtige Pinbelegung, und in Klammern die Verbindungen zum Display:

Obere Stiftleiste:

StiftVersion AVersion BArduino PinBeschreibung
1GND
25 VSpannungsversorgung 5 V 430 mA
33,3 VSpannungsversorgung 3,3 V 430 mA
4GNDGemeinsame Masse
5/CTSClear-To-Send Eingang vom USB-UART, Low aktiv
6/DTRData-Terminal-Ready Ausgang vom USB-UART, Low aktiv
7GPIO55Version A: I²C Takt zum Display mit 10 kΩ Pull-Up Widerstand
Version B: Normaler I/O Pin.
8TxD (GPIO1)1Serieller Ausgang des ESP oder normaler I/O Pin, direkt mit dem USB-UART verbunden, flackert beim Start, darf beim Start nicht auf Low gezogen werden
9RxD (GPIO3)3Serieller Eingang des ESP, direkt mit dem Ausgang des USB-UART verbunden, daher nicht als GPIO verwendbar.
10RESETHat 1,2 kΩ Pull-Up Widerstand und einen Taster nach GND
11GPIO2 (TxD)GPIO42 bzw. 4Version A: Normaler I/O Pin, flackert beim Start, darf beim Start nicht auf Low gezogen werden. Ausgang vom zweiten UART, der nur Ausgabe kann.
Version B: Reset Signal zum Display, Low aktiv.
12ENABLEMuss auf High liegen, damit der Chip arbeitet. Hat 10 kΩ Pull-Up Widerstand. Low=Power Down, High=Enabled

Untere Stiftleiste:

StiftVersion AVersion BArduino PinBeschreibung
1GNDGemeinsame Masse
25 VSpannungsversorgung 5 V 430 mA
33,3 VSpannungsversorgung 3,3 V 430 mA
4GNDGemeinsame Masse
5GPIO4GPIO04 bzw. 0Version A: I²C Daten zum Display mit 10 kΩ Pull-Up Widerstand.
Version B: Low beim Start aktiviert Firmware-Upload, hat 10 kΩ Pull-Up Widerstand und einen Taster nach GND, flackert beim Start
6GPIO0GPIO2 (TxD)0 bzw. 2Version A: Low beim Start aktiviert Firmware-Upload, hat 10 kΩ Pull-Up Widerstand und einen Taster nach GND, flackert beim Start.
Version B: Normaler I/O Pin, flackert beim Start, darf beim Start nicht auf Low gezogen werden. Ausgang vom zweiten UART, der nur Ausgabe kann.
7GPIO15 (CS)15Normaler I/O Pin oder SPI Chip Select, muss beim Start Low sein, hat 10 kΩ Pull-Down Widerstand, flackert beim Start
8GPIO13 (MOSI)13Normaler I/O Pin oder SPI Daten
9GPIO12 (MISO)12Normaler I/O Pin oder SPI Daten
10GPIO14 (SCK)14Version A: Normaler I/O Pin oder SPI Takt.
Version B: I²C Takt zum Display mit 10 kΩ Pull-Up Widerstand
11GPIO1616Version A: Setzt das Display bei Low Pegel zurück.
Beide Versionen: Wenn mit RESET verbunden, kann ein Timer den µC aus dem Deep-Sleep aufwecken.
12ADC17Analoger Eingang für 0 bis 3,2 V weil mit Spannungsteiler 220 kΩ + 100 kΩ. In Arduino heißt der Pin A0 oder Nummer 17.

Die Infos von Heltec passen zur Version A, sind aber unvollständig und fehlerhaft.

Die Stromversorgung erfolgt wahlweise über USB, ein 3,3 V Netzteil oder ein 5 V Netzteil. Das Display nimmt zusätzlich zum ESP Chip ca. 30 mA auf. Der eingebaute Spannungsregler hat für Erweiterungen maximal 200 mA Leistungsreserve. Da der 5 V Anschluss direkt mit der USB Buchse verbunden ist, soll bei Nutzung von USB nicht gleichzeitig ein 5 V Netzteil verwendet werden.

Das Board eignet sich nur bedingt für Akku-Betrieb, da seine Ruhestromaufnahme nie unter 6 mA fällt. Unterhalb von 3,3 V Akku-Spannung fällt das Board aus und saugt dann den Akku mit 80 mA leer, bis er entweder kaputt geht oder seine integrierte Schutzschaltung (falls vorhanden) abschaltet. Beim Aufladen wird die Platine ziemlich warm, was für die Lebensdauer des Displays schlecht ist.

Die Reset Methode zum automatischen Aktivieren des Firmware-Upgrade Modus entspricht dem NodeMCU Board. Die beiden Taster ziehen die Leitungen RESET und GPIO0 direkt ohne Schutzwiderstände auf Low. Auch der USB-UART ist direkt mit den I/O Pins für TxD und RxD verbunden, deswegen kann man den RxD Pin (=GPIO3) nicht für andere Zwecke verwenden.

Ich hatte beim Experimentieren auf einem Steckbrett äußerst schlechten WLAN Empfang. Durch Verlängern der Anschlussbeine um 7 mm konnte ich das Problem beheben.

Zur Programmierung des Displays empfehle ich entweder meine OLED Klasse oder die Libraries SSD1306 und GFX von Adafruit. Die Adafruit Library muss allerdings für Version B des Moduls angepasst werden (Pin Nummern als Parameter zu Wire.begin() hinzufügen).

Man sollte die geringe Lebensdauer des OLED beachten. Die häufiger benutzten Pixel werden schon nach einem Jahr deutlich sichtbar schwächer, das steht auch so im Datenblatt des Displays. Das Display hält länger, wenn man es bei nicht-Gebrauch dunkel oder ganz aus schaltet.

Da ich öfters danach gefragt wurde: Hier ist ein primitives Beispiel, wie man Datum und Uhrzeit von einem beliebigen Webserver abrufen kann.

Stromversorgung

Zu schwache Stromversorgung ist die häufigste Ursache von sporadischen Fehlfunktionen, sie kann sogar zur Zerstörung des Chips führen. Der ESP Chip benötigt für zuverlässigen Betrieb ohne Einschränkungen eine Spannungsversorgung von 3 bis 3,6 Volt und ca. 400 mA. Sie muss extreme Strom-Schwankungen sehr schnell ausregeln können.

Ich benutze meistens ein gewöhnliches 5 bis 12 Volt Steckernetzteil in Kombination mit dem Spannungsregler LF33CV zur Fein-Regelung. Der deckt den ganzen Strom-Bereich ab und ist schnell genug.

Egal woher die Stromversorgung kommt, empfehle ich dringend einen 100 µF Kondensator direkt an die Anschlüsse VCC und GND des ESP-Moduls zu löten. Beim NodeMCU Board ist dieser bereits vorhanden.

Die Leitungen der Stromversorgung sollen möglichst kurz sein und sternförmig an einem Verteil-Punkt zusammen kommen. Das gilt ganz besonders für GND. Steckbretter sind aufgrund der hohen Kontaktwiderstände schlecht zur Strom-Verteilung geeignet.

Die Widerstände um den Chip herum sollten maximal 2,2 kΩ haben, denn hochohmige Widerstände sind für die Funkwellen empfänglich. In der Nähe der Antenne sind Metallteile (auch Leiterbahnen) zu vermeiden, da sie den Empfang beeinträchtigen.

Betrieb an Batterien/Akkus

Alle fertigen Module mit USB Schnittstelle und Spannungsregler auf dem Board eignen sich eher nicht für Langzeit-Betrieb an Batterien, da sie mehr als 1 mA Ruhestrom verbrauchen. Hier sind minimale ESP Module ohne Schnickschnack die bessere Wahl.

Für Batteriebetrieb eignen sich LiFePO4 Zellen am besten, da ihre Spannung bereits ohne Regler passt. Für alle anderen Batterien von 3,6 bis 7,4 Volt empfehle ich den Spannungsregler HT7833 mit 4 µA Ruhestrom. Die häufig empfohlenen MCP1700 und MCP1702 sind meiner Meinung nach zu schwach.

Wenn der Chip wegen Unterspannung ausfällt, nimmt er ca. 80mA auf. Lithium- und Blei-Akkus müssen daher unbedingt mit einem Tiefentladeschutz ausgestattet werden. Manche Lithium-Akkus enthalten so eine Schutz-Schaltung bereits.

Es gibt zahlreiche Funk-Module ohne WLAN, die wesentlich sparsamer sind, als der ESP8266.

Deep-Sleep Modus

Im Deep-Sleep Modus beträgt die Stromaufnahme etwa 25-50 µA (incl. Flash). Je höher die Spannung und Temperatur ist, umso höher die Stromaufnahme. Die WLAN Verbindung wird dabei unterbrochen. Die RTC (Uhr) läuft weiter, allerdings ungenauer als im Normalbetrieb (typisch 2 Minuten Abweichung pro Tag).

Man aktiviert den Deep-Sleep Modus durch Aufrufen der Funktion ESP.deepSleep(µs) gefolgt von delay(100). Als Parameter (µs) gibt man an, in wie vielen Mikrosekunden der Chip wieder aufwachen soll. Maximal 71 Minuten sind möglich. Der Wert 0 lässt den Chip für immer schlafen, oder bis zum nächsten Hardware-Reset.

Wenn man den Wakeup-Timer benutzt, muss der Timer-Ausgang GPIO16 mit dem RESET Eingang verbunden werden, sonst hängt der Chip nach dem Aufwachen. Da die Firmware beim Aufwachen neu startet, geht der Inhalt des RAM verloren. Die RTC enthält jedoch 512 Byte zusätzlichen Speicher, der den Deep-Sleep Modus (jedoch nicht Power-Down) überlebt.

Da beim Aufwachen eine neue WLAN Verbindung aufgebaut werden muss, dauert es typischerweise 3 Sekunden.

Power-Down Modus

Im Power-Down Modus ist der Chip komplett abgeschaltet. Es fließt nur noch ein kleiner Leckstrom von etwa 15 µA (incl. Flash).

Dieser Modus wird durch eine fallende Flanke am ENABLE Eingang ausgelöst, aber erst nachdem die Firmware gestartet ist. Wenn ENABLE zu früh auf Low gezogen wird, nimmt der Chip ca. 2,5 mA auf!

Die steigende Flanke am ENABLE Eingang bewirkt, dass der Power-Down Modus verlassen wird und die Firmware neu startet.

Stromaufnahme im Reset

Während der RESET Eingang auf Low gehalten wird nimmt der Chip ca. 23 mA auf. Der RESET Eingang eignet sich daher nicht zum Strom-sparen.

USB-UART Kabel

Für die Module ohne USB Anschluss, brauchst du ein USB-UART Kabel oder Adapter, um es mit dem PC zu verbinden. Dabei ist wichtig, dass das Ding 3,3 V Pegel hat. Ich schleife in die Signal-Leitungen immer 1 kΩ Widerstände zur Strombegrenzung ein, falls eine Seite mal keine Spannungsversorgung hat.

Für USB-UART Produkte mit altem oder gefälschtem PL2303 Chip habe ich hier einen passenden alten Windows Treiber, denn der aktuelle Treiber mag diese Chips nicht. Den Treiber für den chinesischen CH340 oder CH341 kann man direkt von der Webseite des Herstellers downloaden.

Anschluss an 5 V Mikrocontroller

Der ESP Chip verträgt maximal 3,6 V an allen Pins. Die Signale von 5 V Mikrocontrollern kann man mit einem Spannungsteiler herabsetzen. Das klappt bei 115200 Baud einwandfrei, höhere Baudraten habe ich nicht ausprobiert.

Signale in umgekehrte Richtung (vom ESP Chip zum Mikrocontroller) benötigen normalerweise keine Anpassung, da die gängigen Mikrocontroller 3,3 V bereits als gültigen High Pegel akzeptieren.

Flash Speicher

Der ESP8266 Chip kopiert seine Firmware blockweise von einem externen Flash Speicher in sein internes RAM. Von dort aus wird der Code dann ausgeführt. Der ESP kann bis zu 16 MByte Flash Speicher adressieren, davon jedoch nur maximal 1 MByte als Programmspeicher. Ungefähr 250 kB davon belegt die Basis Firmware.

Der ESP8266 unterstützt folgende Zugriffsarten auf den Flash Speicher:

Offensichtlich sind alle ESP8266 Module mit Flash Speicher ausgestattet, der alle vier Modi mit 80 Mhz unterstützt.

Der ESP8285 hat einen internen Flash Speicher mit 1 MByte Größe. Dieser muss im DOUT Modus mit 40 Mhz angesprochen werden, das ist etwas langsamer. Dafür hat man zwei weitere I/O Pins frei, nämlich GPIO9 und GPIO10.

Die Zugriffsart und Geschwindigkeit wird durch die Firmware festgelegt. Zum Ändern muss sie neu compiliert werden.

Performance

Um einen Eindruck zu bekommen, wie stark sich die Varianten der Flash Anbindung auf die Gesamt-Performance auswirken, habe ich zwei Testreihen durchgeführt.

Die erste Testreihe erfasste die durchschnittliche Antwortzeit (Latenz) bei Anpingen mit jeweils 1 kB während das Modul zugleich alle 10 Sekunden die aktuelle Uhrzeit aus dem Internet abruft und auf einem Grafik-Display anzeigt. Die zweite Testreihe vergleicht die reine Rechenleistung.

CPU Freq.Flash Freq.Flash ModeLatenzRechenleistung
160 Mhz80 MhzQIO und QOUT9 ms871
DIO und DOUT10 ms870
40 MhzQIO und QOUT11 ms870
DIO und DOUT12 ms870
80 Mhz80 MhzQIO und QOUT9 ms435
DIO und DOUT10 ms435
40 MhzQIO und QOUT11 ms434
DIO und DOUT12 ms434

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 über SDIO Interface (als WLAN Netzwerkadapter im PC) 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, GPIO2 und GPIO15 schützen vor Kurzschluss, falls man den Pin als Ausgang programmiert. Der Wakeup-Jumper muss verbunden sein, wenn man den Deep-Sleep Modus mit Wakeup-Timer verwendet.

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.

Der eigentliche Firmware-Upload geschieht mit dem Befehl:

python esptool.py --port COM6 write_flash 0x000000 firmware.bin
Keine Angst: Wenn das Hochladen der Firmware (warum auch immer) fehlschlägt, kann man es einfach nochmal versuchen. Der Bootloader gibt im Fehlerfall eventuell hilfreiche Meldungen mit 74880 Baud aus.

Mit Hilfe des esptool kann man folgendermaßen die Größe des Flash Speichers anhand seiner ID Nummer ermitteln:

python esptool.py --port COM6 flash_id
4013512 kByte
40141 MByte
40152 MByte
40164 MByte

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.

Auf der Seite I/O Schnittstellen Module für WLAN stelle ich eine solche Beispiel-Anwendung vor, und im Buch Einstieg in die Elektronik mit Mikrocontrollern erkläre ich detailliert, wie man so etwas macht.

Die AT Firmware sendet und empfängt im 100 ms Raster, maximal 2048 Bytes pro Intervall.

Für Module mit nur 512 kByte 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. Da die Firmware in mehrere Dateien aufgeteilt ist, muss man sie so installieren:

512 kBytepython 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

Für alle größeren Module habe ich mir die zuverlässige AT-Firmware 1.1.0.0 vom SDK 1.5.4 gesichert. Sie wird mit folgendem Befehl installiert:

1 MBytepython 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
2 MBytepython 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
4 MBytepython 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

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.

AT Befehle

In diesem Kapitel beschreibe ich nur die Befehle, die mir wichtig sind. Sie funktionieren mindestens mit der AT-Firmware von Version 0.21.0.0 bis 1.1.0.0, vielleicht auch mit neueren. Beachte beim Programmieren, dass das 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 das Hammer Terminal, Putty oder Cutecom.

Die AT Firmware kommuniziert in der Regel mit 115200 Baud. Manche Module sind auf 57600 oder 9600 Baud vor-eingestellt. Das Format für Zeilenumbrüche ist CR+LF.

Nach dem Hardware-Reset zeigt das Terminal Programm einige unlesbare Zeilen an, und dann "ready". Danach kannst du Befehle eintippen. Sollten jedoch nur unlesbare Zeichen erscheinen, stelle die Baudrate auf 74880 um, dann kannst du die Fehlermeldungen des Bootloaders lesen.

Befehle:

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,"Pussycat",-45,"5c:49:79:2d:5b:cd",7,-4)
OK

AT+CWJAP="Pussycat","supersecret"
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. Das Passwoet muss mindestens 8 Zeichen lang sein!

AT+CWJAP?
zeigt an, mit welchem Access Point das Modul gerade verbunden ist. Zum Beispiel:
+CWJAP:"Pussycat","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
Hello
World!

Am seriellen Port des Moduls erscheinen dabei folgende Meldungen:

0,CONNECT
+IPD,0,7:Hello
+IPD,0,8:World!
"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 (nämlich "Hello\r\n") empfangen hat. Nach dem Doppelpunkt folgen genau diese 7 Bytes. Achtung: Wenn der empfangene Text nicht mit einem Zeilenumbruch endet, dann kommt die nächste +IPD Meldung direkt dahinter in der selben Zeile!

AT+CIPSEND=0,9
> Welcome!
Mit diesem Befehl sendest du eine Antwort an den Computer. Die 0 ist wieder die Kanalnummer und die 9 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

Laut Dokumentation soll man nach diesem Kommando mindestens 1 Sekunde warten. Bei meinen Tests funktionierten aber 4 Kommandos pro Sekunde weitgehend zuverlässig.

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 (das passiert in lokalen Netzen allerdings praktisch nie).

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
Lets start!

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.

Soft-AP 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 Soft-AP Modus eignet sich gut dazu, ESP Module untereinander zu verbinden. Die Nutzung mit Smartphones und Laptops kann ich nicht empfehlen, da sie bei vielen Geräten unzuverlässig funktioniert. Im Soft-AP Modus erreichst du das WLAN Modul mit der fest codierten IP-Adresse 192.168.4.1.

AT+CWMODE=2
AT+CWSAP="ESP-Modul","supersecret",5,3
AT+RST
Diese Befehlsfolge aktiviert den Soft-AP 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. Das passwort muss mindestens 8 Zeichen lang sein!

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 gut mit Linux auskennen und mit unvollständiger Dokumentation arbeiten.

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. 40 kByte 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 Bastel-freundlichste Lösung ist meiner Meinung nach die ESP8266 Erweiterung für Arduino. Man programmiert dort in C++. Die Installation der Arduino IDE ist kinderleicht - kein Vergleich zum Espressif SDK.

Alle drei Varianten haben eines gemeinsam: Das Debuggen mit einer IDE ist nur sehr eingeschränkt möglich. In der Praxis wird man eher mit seriellen Log-Meldungen arbeiten.

Erste Schritte mit Arduino

Der Arduino Core kombiniert das SDK des Herstellers mit dem Arduino Framework, um die Programmierung in C++ zu erleichtern. Das damit erzeugte Compilat enthält daher immer die originale Firmware des Herstellers plus dein eigenes Anwendungsprogramm.
  1. Installiere die Arduino IDE (Version 1.8.7) und starte sie.
  2. 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 den ESP8266 Core, die Version 2.3.0 läuft stabil.
  4. Stelle im Werkzeuge Menü das "Generic ESP8266 Module" ein, bzw. was auch immer du für ein Modul vorliegen hast.
  5. Stelle dann darunter im Werkzeuge Menü die Details zum Board ein, im Zweifelsfall:
    • Upload Speed: 115200
    • CPU Frequency: 80 Mhz
    • Flash Size: 512k (64k SPIFFS)
    • Flash Mode: QIO
    • Flash Frequency: 40 Mhz
    • Reset Method: NodeMCU
    • Debug Port: disabled
    • Debug Level: keine
    • Port: Entsprechend deinem USB-UART Kabel
    • Programmer: spielt keine Rolle, es wir immer ein USB-UART verwendet
  6. Schreibe dein Programm (Sketch).
  7. Compiliere das Programm, mit dem Menüpunkt Sketch/Überprüfen&Compilieren.
  8. Lade dein Programm hoch, mit dem Menüpunkt Sketch/Hochladen.

Lies die Dokumentation von Arduino und dem ESP8266 Core Version 2.3.0 / aktuelle Version.

Beispiel Sketche

Die Arduino IDE zeigt im Menü Datei/Beispiele Sketche an, welche die Verwendung der ESP8266 Erweiterung demonstrieren. Darüber hinaus zeige ich Dir hier Sketche, 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.
//The ESP-12 has a blue LED on GPIO2
#define LED 2

/** Runs once at startup */
void setup() 
{
    pinMode(LED, OUTPUT);
    Serial.begin(115200);
}

/** Main loop, executed repeatedly */
void loop() 
{
    digitalWrite(LED, LOW);
    Serial.println(F("Tick"));
    delay(500);

    digitalWrite(LED, HIGH);
    Serial.println(F("Tack"));
    delay(500);
}

UDP Server

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

// The ESP-12 has a blue LED on GPIO2
#define LED 2

// Name and password of the access point
#define SSID "Pussycat"
#define PASSWORD "supersecret"

// The server accepts connections on this port
#define PORT 5444
WiFiUDP udpServer;

// Buffer for incoming UDP messages
char udp_buffer[WIFICLIENT_MAX_PACKET_SIZE+1];


/** Receive UDP messages and send an echo back */
void process_incoming_udp()
{   
    if (udpServer.parsePacket()) 
    {
        // Fetch received message
        int len=udpServer.read(udp_buffer,sizeof(udp_buffer)-1);
        udp_buffer[len] = 0;
                
        // Display the message
        Serial.print(F("Received from "));
        Serial.print(udpServer.remoteIP());
        Serial.print(":");
        Serial.print(udpServer.remotePort());
        Serial.print(": ");
        Serial.println(udp_buffer);
        
        // Send echo back
        udpServer.beginPacket(udpServer.remoteIP(), udpServer.remotePort());
        udpServer.print(F("Echo: "));
        udpServer.print(udp_buffer); 
        udpServer.endPacket();
        
        // Execute some commands
        if (strstr(udp_buffer, "on"))
        {
            digitalWrite(LED, LOW);
            udpServer.println(F("LED is on"));
        }
        else if (strstr(udp_buffer, "off"))
        {
            digitalWrite(LED, HIGH);
            udpServer.println(F("LED is off"));
        }
    }    
}


/** Optional: Notify about AP connection status changes */
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);
            
            // Display the own IP address and port
            Serial.print(F("AP connection established, listening on "));
            Serial.print(WiFi.localIP());
            Serial.print(":");
            Serial.println(PORT);
        }
        else
        {
            digitalWrite(LED, HIGH);
            Serial.println(F("AP conection lost"));
        }
        preStatus = newStatus;
    }
}


/** Runs once at startup */
void setup()
{
    // LED off
    pinMode(LED, OUTPUT);
    digitalWrite(LED, HIGH);

    // Initialize the serial port
    Serial.begin(115200);
    
    // Give the serial monitor of the Arduino IDE time to start
    delay(500);

    // Use an external AP
    WiFi.mode(WIFI_STA);
    WiFi.begin(SSID, PASSWORD);

    // Start the UDP server
    udpServer.begin(PORT);
}


/** Main loop, executed repeatedly */
void loop()
{
    process_incoming_udp();
    check_ap_connection();
}
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
Monkey see monkey do
Echo: Monkey see monkey do
off
Echo: off
LED is off
on
Echo: on
LED is on
Der UDP Service ist 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. In seltenen Fällen erreichen schnell aufeinander folgende Pakete ihren Empfänger in veränderter Reihenfolge.

TCP Server

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

// The ESP-12 has a blue LED on GPIO2
#define LED 2

// Name and password of the access point
#define SSID "Pussycat"
#define PASSWORD "supersecret"

// The server accepts connections on this port
#define PORT 5333
WiFiServer tcpServer(PORT);

// Objects for connections
#define MAX_TCP_CONNECTIONS 5
WiFiClient clients[MAX_TCP_CONNECTIONS];

// Buffer for incoming text
char tcp_buffer[MAX_TCP_CONNECTIONS][30];


/**
 * Collect lines of text.
 * Call this function repeatedly until it returns true, which indicates
 * that you have now a line of text in the buffer. If the line does not fit
 * (buffer to small), it will be truncated.
 *
 * @param source The source stream.
 * @param buffer Target buffer, must contain '\0' initiallly before calling this function.
 * @param bufSize Size of the target buffer.
 * @param terminator The last character that shall be read, usually '\n'.
 * @return True if the terminating character was received.
 */
bool append_until(Stream& source, char* buffer, int bufSize, char terminator)
{
    int data=source.read();
    if (data>=0)
    {
        int len=static_cast<int>(strlen(buffer));
        do
        {
            if (len<bufSize-1)
            {
                buffer[len++]=static_cast<char>(data);
            }
            if (data==terminator)
            {
                buffer[len]='\0';
                return true;
            }
            data=source.read();
        }
        while (data>=0);
        buffer[len]='\0';  
    }
    return false;
}


/** Optional: Notify about AP connection status changes */
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);
            
            // Display the own IP address and port
            Serial.print(F("AP connection established, listening on "));
            Serial.print(WiFi.localIP());
            Serial.print(":");
            Serial.println(PORT);
        }
        else
        {
            digitalWrite(LED, HIGH);
            Serial.println(F("AP conection lost"));
        }
        preStatus = newStatus;
    }
}


/** 
 * Put new connections into the array and
 * send a welcome message.
 */
void handle_new_connections()
{
    WiFiClient client = tcpServer.available();
    if (client)
    {
        Serial.print(F("New connection from "));
        Serial.println(client.remoteIP().toString());
        
        // Find a freee space in the array   
        for (int i = 0; i < MAX_TCP_CONNECTIONS; i++)
        {
            if (!clients[i].connected())
            {
                // Found free space
                clients[i] = client;
                tcp_buffer[i][0]='\0';
                Serial.print(F("Kanal="));
                Serial.println(i);
                
                // Send a welcome message
                client.println(F("Hello World!"));
                return;
            }
        }
        Serial.println(F("To many connections"));
        client.stop();
    }
}


/** Receive TCP messages and send echo back */
void process_incoming_tcp()
{   
    static int i=0;
    
    // Only one connection is checked in each call
    if (clients[i].available())
    {
        // Collect characters until line break
        if (append_until(clients[i],tcp_buffer[i],sizeof(tcp_buffer[i]),'\n'))
        {        
            // Display the received line
            Serial.print(F("Empfangen von "));
            Serial.print(i);
            Serial.print(": ");
            Serial.print(tcp_buffer[i]);

            // Send an echo back
            clients[i].print(F("Echo: "));
            clients[i].print(tcp_buffer[i]);
            
            // Execute some commands
            if (strstr(tcp_buffer[i], "on"))
            {
                digitalWrite(LED, LOW);
                clients[i].println(F("LED is on"));
            }
            else if (strstr(tcp_buffer[i], "on"))
            {
                digitalWrite(LED, HIGH);
                clients[i].println(F("LED is off"));
            }    
            
            // Prepare the buffer to receive the next line
            tcp_buffer[i][0]='\0';
        }
    }
    
    // Switch to the next connection for the next call
    if (++i >= MAX_TCP_CONNECTIONS)
    {
        i=0;
    }
}


/** Executes once during start*/
void setup()
{
    // LED off
    pinMode(LED, OUTPUT);
    digitalWrite(LED, HIGH);

    // Initialize the serial port
    Serial.begin(115200);
    
    // Give the serial monitor of the Arduino IDE time to start
    delay(500);

    // Use an external AP
    WiFi.mode(WIFI_STA);
    WiFi.begin(SSID, PASSWORD);

    // Start the TCP server
    tcpServer.begin();
}


/** Main loop, executed repeatedly */
void loop()
{
    handle_new_connections();
    process_incoming_tcp();
    check_ap_connection();
}
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
Hello World!
I am Groot
Echo: I am Groot
off
Echo: off
LED is off
an
Echo: on
LED is on
Bei TCP kann man sich im Gegensatz zu UDP absolut 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 dazu 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 dort 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 gibst du die Zugangsdaten deines Access Points (z.B. Fritz Box) ein. Wenn sie richtig sind, baut das Modul sofort eine Verbindung zu diesem Gerät auf. Das Hauptprogramm in diesem Beispielprojekt testet die Erreichbarkeit des konfigurierten Webservers und zeigt den Status anhand einer bunten LED an.

WLAN vorübergehend aus schalten

Ohne WLAN nimmt der Chip 10-15 mA Strom auf. Der analoge Eingang funktioniert in diesem Zustand viel besser. Um die WLAN Schnittstelle vorübergehend aus zu schalten, muss man den Wakeup-Timer einbeziehen:
  ESP.deepSleep(1, WAKE_RF_DISABLED); 
  delay(100);
Der Mikrocontroller legt sich sehr kurz schlafen und startet mit deaktiviertem WLAN neu durch. So reaktiviert man die Schnittstelle wieder:
  ESP.deepSleep(1, WAKE_RFCAL); 
  delay(100);
Dabei muss der GPIO16 Pin mit dem RESET Eingang verbunden sein. Ein abgeschaltetes WLAN kann man nur auf diese Art wieder einschalten. Vielen Dank an Michael U. für diesen wertvollen Hinweis.

Fallstricke

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 50 ms (empfohlen werden 20 ms) die Kontrolle an die Firmware abgeben, indem sie entweder die loop() Funktion verlassen oder die Funktion delay(ms) oder yield() aufrufen.

Für eigene Programme stehen nur ungefähr 4 kByte 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.

Bedenke das String Objekte und Zeichenketten normalerweise im RAM liegen. Hier ist beschrieben, wie man sie stattdessen im Flash Speicher anlegt, um RAM zu sparen.

Dynamische Speicherverwaltung auf dem Heap verlangt besondere Sorgfalt, damit der Heap nicht fragmentiert wird. Sobald der eigene Code die Schlüsselwörter delete oder free() enthält, sollte man die Langzeit-Stabilität der Anwendung gründlich überprüfen. Außerdem rate ich dringend dazu, String Objekte zu meiden, weil sie davon intensiv Gebrauch machen. Mehr dazu hier.

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. Wenn man jedoch in einem Aufruf zu viele Daten sendet, teilt die Firmware sie automatisch auf mehrere Pakete auf und wartet notfalls sogar 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 am Stück zurück liefern, vor allem wenn die Daten schnell aufeinander folgend eintreffen. Passe daher 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. Besser geht es mit meiner append_until() Funktion aus dem obigen Beispiel-Sketch.

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 schön erklärt.

Beim UDP Protokoll sendet und empfängt man Pakete mit der oben genannten maximalen Größe. Diese kann unter Umständen durch Netzwerk Komponenten (Router, Modems, etc.) noch weiter eingeschränkt sein.

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

Interrupt-Handler Routinen müssen mit dem Makro ICACHE_RAM_ATTR gekennzeichnet werden, sonst stürzt der Mikrocontroller ab. Innerhalb von Interruptroutinen darf man keine WLAN-Funktion benutzen, den ADC nicht auslesen und auch nicht delay() oder yield() benutzen. Ich rate davon ab, Interrupts überhaupt zu verwenden, weil es dabei oft zu unerwarteten Störungen kommt.

Es wird empfohlen, nach ESP.deepSleep() immer einen delay(100) einzufügen, damit das Einschlafen zuverlässig funktioniert.

Andere IDE als besseren Text-Editor verwenden

Der Text-Editor von Arduino ist gelinde gesagt knapp ausgestattet. Andere Entwicklungsumgebungen sind viel komfortabler, deswegen nutze ich diesen gerne. Sie erkennen viele Fehler schon direkt während der Eingabe und helfen beim Tippen, indem sie Vorschläge anzeigen. Wenn Du zum Beispiel "Serial." eintippst, listet sie IDE alle Felder und Methoden der Serial Klasse auf. Wenn Du die Strg-Taste gedrückt hältst und dann auf eine #include Datei, einen Klassen-Namen oder einen Methoden-Namen klickst, dann öffnet sich die zugehörige Datei und der Cursor springt zu der entsprechenden Zeile.

Ich habe sowohl mit Netbeans als auch mit Qt-Creator gute Erfahrungen gemacht. Qt-Creator gefällt mir besser, weil es den Quelltext schon beim Tippen analysiert und auf mögliche Fehler hinweist.

In den folgenden Absätzen habe ich das Installationsverzeichnis der Arduino IDE mit <arduino> abgekürzt. Das <packages> Verzeichnis, wo die Erweiterungen instaliert sind, liegt normalerweise im persönlichen Ordner:

Bei einer Portable Installation befinden sich die Packages hingegen im "portable" Verzeichnis der Arduino Software.

Gehe in der Arduino IDE in das Menü Datei/Voreinstellungen und schalte die Option "Externen Editor verwenden" ein.

NetBeans

NetBeans 8.2 benötigt das Java Development Kit in Version 8.

Installiere das Oracle JDK (unter Linux geht auch OpenJDK) und NetBeans in der Variante für C/C++. Wenn du NetBeans bereits für andere Programmiersprachen installiert hast, genügt es das C/C++ Plugin hinzuzufügen.

Starte NetBeans und gehe dann ins Menü Tools/Options/Miscellaneous/Files. Wähle die Dateiendung C++ aus. Klicke dann auf den "New..." Knopf und füge die Endung "ino" hinzu. Danach erkennt NetBeans die *.ino Dateien als C++ Quelltext an.

Gehe ins Menü Tools/Options/C/C++/Build Tools. Füge eine neue "Tool Collection" mit dem Basis-Verzeichnis <esp8266>/tools/xtensa-lx106-elf-gcc hinzu. Darunter muss die "Tool Collection Family" auf "GNU MinGW" (unter Windows) bzw. "GNU" (unter Linux) eingestellt werden. Der Name für die neue Tool Collection soll "ESP8266" sein.

Der C-Compiler heißt xtensa-lx106-elf-gcc, und der C++ Compiler heißt xtensa-lx106-elf-cpp. Beide liegen irgendwo im <packages> Verzeichnis. Die anderen Programm-Felder darunter dürfen leer bleiben:

Wechsle dann zu dem Reiter "Code Assistance". Wähle bei "Tool Collection" die "ESP8266" aus und füge dann darunter beim C++ Compiler unter "Include Directories" alle verwendeten ESP8266 Libraries hinzu, und die core Library von Arduino:

Darunter fügst du eine "Macro Definition" mit dem Wert "ARDUINO=010807" ein, das ist die Versionsnummer 1.8.7 deiner Arduino IDE.

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. Wähle als Projekt-Typ "C/C++ with Existing Sources" aus. Im nächsten Dialog gibst du das Projektverzeichnis und die Tool Collection ist "ESP8266" an. Die Option "Use Build Analyzer" soll ausgeschaltet werden.

Nun kannst du deinen Sketch mit Netbeans editieren. Um ihn zu überprüfen (compilieren) und hochzuladen musst du weiterhin die Arduino IDE verwenden. Eventuell magst du dir diese Anleitung anschauen, wo die Bedienung des Editors erklärt wird.

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.

Qt-Creator

Verwende den Installer vom Qt SDK, um das Programm Qt-Creator zu installieren. Die optionalen Komponenten brauchst du nicht. Starte das Programm und gehe dann ins Menü Extras/Einstellungen/Erstellung und Ausführung/Compiler. Dort musst du den C Compiler und den C++ Compiler aus der ESP8266 Erweiterung für Arduino als Typ "MinGW" (unter Windows) bzw. "GCC" (unter Linux) hinzufügen. Bei mir sieht das unter Linux so aus:

Der C-Compiler heißt xtensa-lx106-elf-gcc, und der C++ Compiler heißt xtensa-lx106-elf-cpp. Beide liegen irgendwo im <packages> Verzeichnis. Qt-Creator nutzt diese beiden Befehle, um die Standard-C Libraries automatisch zu finden. Danach gehe in den "Kits" Reiter und lege dort ein neues Kit mit den gerade angelegten Compilern an:

Die CMAKE Konfiguration spielt keine Rolle, lasse sie einfach unverändert.

Anschließend kannst du das Arduino-Projekt über das Menü "Datei/Neu/Projekt importieren/Import eines existierenden Projekts" importieren. Gebe danach in der Datei "ProjektName.files" alle Dateien an, die du mit Qt-Creator editieren möchtest - also die *.ino, *.h und *.cpp Dateien.

In der Datei "ProjektName.includes" musst du die Verzeichnisse der verwendeten ESP8266 Libraries hinzufügen, sowie die core Library von Arduino:

<packages>/esp8266/hardware/esp8266/2.3.0/cores/esp8266
<packages>/esp8266/hardware/esp8266/2.3.0/variants/generic
<packages>/esp8266/hardware/esp8266/2.3.0/tools/sdk/include
<packages>/esp8266/hardware/esp8266/2.3.0/libraries/ESP8266WiFi/src
<packages>/esp8266/hardware/esp8266/2.3.0/libraries/EEPROM
<packages>/esp8266/hardware/esp8266/2.3.0/libraries/Wire
<packages>/esp8266/hardware/esp8266/2.3.0/libraries/SPI
<arduino>/hardware/arduino/avr/cores/arduino

In der Datei "ProjektName.config" gibst du die Version 1.8.7 deiner Arduino IDE an:

#define ARDUINO 010807

Nun kannst du deinen Sketch mit Qt-Creator editieren. Um ihn zu überprüfen (compilieren) und hochzuladen musst du weiterhin die Arduino IDE verwenden.

Kritik

Der ESP8266 Chip kann nur mit der Firmware des Herstellers genutzt werden, da viele wichtige Details der Hardware geheim gehalten werden. Große Teile davon sind nur in Binärform ohne Quelltext veröffentlicht. Jede Anwendung ist somit zwangsläufig den Eigenheiten dieser Firmware ausgeliefert - auch Arduino und NodeMCU.

In den ersten zwei Jahren war diese Firmware noch so unzuverlässig, dass an eine ernsthafte Nutzung nicht zu denken war. Inzwischen gibt es mit SDK Version 1.5.4 und dem Arduino Core 2.3.0 ein brauchbares Entwicklungs-Kit. Die danach veröffentlichten Versionen laufen nach meinem Kenntnisstand wieder weniger stabil.

Bitte lassen Sie sich nicht von falschen Versprechungen wie "besonders Sparsam" und falschen Zahlen täuschen! WLAN hat verglichen mit anderen Alternativen generell einen hohen Energiebedarf, und der ESP8266 ist besonders hungrig. Zum Beispiel sind die Silabs AWM136 und Texas Instruments CC3120 Module sparsamer.

Das Datenblatt nennt einige Features (z.B. I²C, PWM, IR Remote), die der Chip in Wirklichkeit nicht hat. Im "Kleingedruckten" dazu heißt es, dass man diese in Software implementieren "kann".

Mich stört, dass der Hersteller den Pin 7 mehrfach umbenannt hat: CH_PD, CHIP_PU, CHIP_EN. Weder im Datenblatt, noch in der entsprechenden Application Note wird erwähnt, dass der Eingang erst nach dem Start der Firmware richtig funktioniert.

Ein mutmaßlicher Fehler im Design des Chips bewirkt, dass er sich beim Aufwachen aus dem Deep-Sleep Modus aufhängt. Deswegen muss der Timer Ausgang mit dem Reset Eingang verbunden werden, was einen kompletten Neustart der Firmware mit Verlust der Daten im RAM bewirkt.

Der Watchdog-Reset schlägt nach einem Programmfehler (z.B. Stack Überlauf) häufig fehl. Ein externer Hardware Reset funktioniert aber zuverlässig. Ein Impuls an ENABLE-Eingang genügt hingegen nicht, um eine Blockierung zu lösen.

Der ADC Eingang taugt nur als grobes Schätzeisen, weil er nicht linear arbeitet und sich vom RF Interface stören lässt. Laut einer sehr gut versteckten Info im Datenblatt sind bis zu 20 % Abweichung normal!

Die RTC läuft im Deep Sleep Modus so ungenau, dass sie praktisch unbrauchbar ist. Daher ist mir die fehlende Unterstützung im Arduino Framework egal.

Da die Firmware in unregelmäßigen Abständen mit der WLAN Schnittstelle beschäftigt ist, ist die Erzeugung von Signalen mit exakten Timings per Software fast unmöglich. Dies äußert sich zum Beispiel in sichtbarem Flackern bei PWM gedimmten Lampen. Für die beliebten Neopixel (WS2812 und ähnliche) muss man die serielle Schnittstelle oder I2S mit DMA missbrauchen, um ausreichend genaue Signale zu erzeugen.

Für Hobbyprojekte ist der Chip trotzdem interessant, vor allem wegen seines unschlagbaren Preises.

Vergleich mit ESP32

Es gibt viele unterschiedliche ESP32 Chips. Sie sind größer, breiter und schneller. Manche Modelle haben zwei CPU Kerne, Bluetooth und/oder Ethernet. Aber leider sind nur sehr wenige Boards mit Ethernet ausgestattet. Dazu kommen 2x I²C, CAN, ein DAC, 16x PWM, ein Hall Sensor und ein Temperatur Sensor.

Bei den Modellen mit 2 CPU Kernen kann man einen Kern für das Anwendungsprogramm reservieren, während der andere Kern sich um WLAN kümmert. Die 2-Kern Modelle haben gerade genug Leistung für ernsthafte Verschlüsselung, dafür ist allerdings ihre Stromaufnahme wesentlich höher.

ADC und RTC sind gemäß öffentlichen Diskussionen beide ebenso ungenau, wie beim Vorgänger.

Leider machen sowohl das Espressif IoT Development Framework (IDF) als auch der Arduino Core Ende 2018 noch einen unausgereiften Eindruck. Das wird sich hoffentlich in den nächsten Jahren ändern.

Auf der Webseite von Dipl. Ing. (BA) Frank Carius findest du noch weitere Infos zu dem ESP8266 und ganz viele Links zu relevanten Webseiten.

ESP12E, Einstieg mit dem ESP8266 Modul ist ein umfangreiches Tutorial mit Anwendungsbeispielen und schön detaillierten Fotos.