====== ESP8266 WiFi Module ====== {{http://cdn.boxtec.ch/images/31083.jpg?220 |ESP8266 ESP-01 Modul}} Die [[http://shop.boxtec.ch/esp8266-wifi-transceiver-module-esp01-p-42143.html|ESP8266 Module]] von Espressif bieten eine sehr günstige Möglichkeit, Mikrokontroller Projekte mit Internet Verbindung zu erweitern. Die gute Reichweite, einfache Konfiguration und vor allem der niedrige Preis machen diese Module sehr attraktiv für IoT Projekte aller Art. Dadurch dass die Module erst seit sehr kurzem auf dem Markt sind, besteht noch sehr wenig Dokumentation, diese Seite soll bekannte Informationen zusammenführen. ===== Anschlussbelegung / Pinout ESP8266 ===== ==== ESP8266 ESP-01 ==== {{:wireless:esp8266-pinout_etch_copper_top.png?300 |Pinout ESP8266 ESP-01}} ^ Label ^ Signal ^ | **VCC** | 3.3V (max 3.6V) Versorgungsspannung | | **GND** | Ground | | **TXD** | Transmit Data (3.3V Pegel) | | **RXD** | Receive Data (3.3V Pegel!) | | **CH_PD** | Chip Power down: (LOW = Power down aktiv) | | **GPIO0** | General Purpose I/O 0 | | **GPIO2** | General Purpose I/O 2 | | **RST** | Reset (LOW = Reset aktiv) | ==== ESP8266 ESP-02 ==== {{wireless:esp02-pinout.jpg?300 |Pinout ESP8266 ESP-02}} ^ Label ^ Signal ^ | **VCC** | 3.3V (max 3.6V) Versorgungsspannung | | **GND** | Ground | | **UTXD** | Transmit Data (3.3V Pegel) | | **URXD** | Receive Data (3.3V Pegel!) | | **GPI014** (//CH_PD//) | Chip Power down: (LOW = Power down aktiv) | | **GPIO0** | General Purpose I/O 0 | | **GPIO2** | General Purpose I/O 2 | | **RST** | Reset (LOW = Reset aktiv) | <- **ACHTUNG**: Atkualisiertes Anschlussdiagramm! ==== ESP8266 ESP-03 ==== {{wireless:esp03-boardtop.jpg?300 |Pinout ESP8266 ESP-03}} ^ Label ^ Signal ^ | **VCC** | 3.3V (max 3.6V) Versorgungsspannung | | **GND** | Ground | | **UTXD** | Transmit Data (3.3V Pegel) | | **URXD** | Receive Data (3.3V Pegel!) | | **CH_PD** | Chip Power down: (LOW = Power down aktiv) | | **GPIO0** | General Purpose I/O 0 | | **GPIO2** | General Purpose I/O 2 | | **GPIO12** | General Purpose I/O 12 | | **GPIO13** | General Purpose I/O 13 | | **GPIO14** | General Purpose I/O 14 | | **GPIO15** | General Purpose I/O 15 (Connect with 1k to Ground)| | **GPIO16** | General Purpose I/O 16 (RESET, LOW = Reset aktiv) | | **WIFI_ANT** | WiFi Antenna | | **NC** | Not connected | **Standardbeschaltung des ESP-03 Moduls: ** VCC: 3.3V; GND: GND; CH_PD: 3.3V, GPIO15: GND; und gegbenfalls UTXD/URXD mit RX/TX des Host Microcontrollers. ** RESET: ** GPIO16 kann als RESET verwendet werden, nachdem auf dem ESP-03 Modul die im Bild markierte Lotbrücke geschlossen wurde. {{ wireless:esp-03_rst.jpg?200 | Reset Modifikation ESP8266 ESP-03}} **Hinweis: ** Alle Eingänge des ESP8266 sind **__nicht__** 5V tolerant und dürfen ausschliesslich mit 3.3V betrieben werden. ===== AT Kommandos ==== * Baudrate: normal 115200, Für Arduino 9600, alte Modelle 57600 * Der AT Teil des Kommandos kann gross oder klein geschrieben werden, der nachfolgende Befehl muss jedoch immer gross geschrieben werden * Achte darauf, dass vor, nach und innerhalb des Befehls keine Leerzeichen (Space) vorkommen * AT-Kommandos müssen mit CR (\r\n) terminiert werden * Settings zur WLAN Verbindung werden automatisch dauerhaft gespeichert und nach Reset wieder wirksam ==== Allgemeine AT Kommandos ==== ^ AT Kommando ^ Beschreibung ^ Parameter ^ Beispiel ^ | **AT** | Test Kommando, gibt immer "OK" zurück | | //AT// | | **AT+RST** | Reset des Moduls, gibt Bootmeldungen des Moduls gefolgt von //ready// zurück | | //AT+RST// | | **AT+GMR** | Abfrage der Firmware Version | | //AT+GMR// | ==== WiFi AT Kommandos ==== ^ AT Kommando ^ Beschreibung ^ Parameter ^ Beispiel ^ | **AT+CWMODE=////** | Setzen des WiFi Betriebsmodus((Wird erst nach einem Reset mit //AT+RST// aktiv)) | 1=Station\\ 2=Access Point\\ 3=Beides | //AT+CWMODE=1// | | **AT+CWMODE?** | Abfrage WiFi Betriebsmodus | | //AT+CWMODE?// | | **AT+CWMODE=?** | Abfrage möglicher Einstellungen für WiFi Betriebsmodus | | //AT+CWMODE=?// | | **AT+CIPMUX=** | Verwenden mehrerer Verbindungen | 0=Einzelverbindung\\ 1=Mehrere Verbindungen | //AT+CIPMUX=1// | | **AT+CIPMODE=** | Einstellen des Datenmodus | 0=transparent\\ 1=Daten | //AT+CIPMODE=1// | | **AT+CIPMODE?** | Ausgabe des eingestellten Datenmodus | | //AT+CIPMODE?// | ==== WiFi Kommandos (Station / Client) ==== ^ AT Kommando ^ Beschreibung ^ Parameter ^ Beispiel ^ | **AT+CWJAP=,** | Verbinden mit WiFi Netzwerk | ssid: "SSID"\\ pass: "Passwort" | //AT+CWJAP="makerday","M4k3rd4y"// | | **AT+CWJAP?** | Ausgabe des aktuell verbundenen WiFi Netzwerks | | //AT+CWJAP?// | | **AT+CWLAP** | Ausgabe der verfügbaren APs((Zurzeit resultiert dies leider in einem zuverlässigen Reset)) | | //AT+CWLAP// | | **AT+CWQAP** | Trennt die Verbindung mit einem Access Point | | //AT+CWQAP// | | **AT+CIFSR** | Ausgabe der eigenen IP Adresse | | //AT+CIFSR// | ==== WiFi Kommandos (Access Point) ==== ^ AT Kommando ^ Beschreibung ^ Parameter ^ Beispiel ^ | **AT+CWSAP=,[,,]** | Setzen der Access Point Parameter((Wird erst nach einem Reset mit //AT+RST// aktiv))\\ Im Access-Point Modus hat das Modul die IP-Adresse 192.168.4.1. Es weist DHCP Clients Adressen ab 192.168.4.100 zu. | ssid: "SSID"\\ pass: "Passwort"\\ chan: "Kanal"\\ enc: "Encryption"\\ (0=Offen\\ 1=WEP\\ 2=WPA_PSK\\ 3=WPA2_PSK\\ 4=WPA_WPA2_PSK) | //AT+CWSAP="makerday","M4k3rd4y",5,3// | | **AT+CWSAP?** | Ausgabe der aktuellen Einstellungen für den AP | | //AT+CWSAP?// | | **AT+CWLIF** | Listet angeschlossenen Stations IPs((nur in CWMODE 2 und 3 verfügbar)) | | //AT+CWLIF// | ==== WiFi Kommandos (IP Client) ==== ^ AT Kommando ^ Beschreibung ^ Parameter ^ Beispiel ^ | **AT+CIPSTATUS** | Ausgabe Status der IP Verbindung(en) | | //AT+CIPSTATUS// | | **AT+CIPSTART=,
,** | Erstellen einer IP Verbindung mit AT+CIPMUX=0 | type: "TCP" oder "UDP"\\ address: "IP-Adresse"\\ port: TCP/UDP Port | //AT+CIPSTART="TCP","192.168.3.10",3000// | | **AT+CIPSEND=** | Senden von Daten über einzelne Verbindung((Die Daten folgen erst **nach** dem CIPSEND Befehl, nicht auf einer Zeile)) | len: Datenlänge | //AT+CIPSEND=4\\ >9901// | | **AT+CIPCLOSE** | Schliessen einer einzelnen TCP oder UDP Verbindung | | //AT+CIPCLOSE// | | **AT+CIPSTART=,,
,** | Erstellen einer IP Verbindung mit AT+CIPMUX=1 | id: 0-4\\ type: "TCP" oder "UDP"\\ address: "IP-Adresse"\\ port: TCP/UDP Port | //AT+CIPSTART="TCP","192.168.3.10",3000// | | **AT+CIPSEND=,** | Senden von Daten über merhere Verbindungen((Die Daten folgen erst **nach** dem CIPSEND Befehl, nicht auf einer Zeile)) | id: 0-4\\ len: Datenlänge | //AT+CIPSEND=1,4\\ >9901// | | **AT+CIPCLOSE=** | Schliessen einer von mehreren TCP oder UDP Verbindung | id: 0-4 | //AT+CIPCLOSE=1// | ==== WiFi Kommandos (IP Server) ==== ^ AT Kommando ^ Beschreibung ^ Parameter ^ Beispiel ^ | **AT+CIPSERVER=1[,]** | Startet den TCP Server | port: Port | //AT+CIPSERVER=1,8001// | | **AT+CIPSERVER=0** | Beendet den TCP Server | | //AT+CIPSERVER=0// | | **AT+CIPSTO=** | Setzt Timeout für TCP Server | timeout=0-28800s | //AT+CIPSTO=180// | | **AT+CIPSTO?** | Gibt Timeout für TCP Server aus | | //AT+CIPSTO?// | Wird ein IP Server gestartet, kann dieser max 5 gleichzeitige Verbindungen bearbeiten. Weitere Verbindungen können erstellt werden, werden jedoch erst bedient wenn andere geschlossen werden oder durch Timeout beendet werden. Alte Versionen (vermutlich bis 00150910) konnten auch UDP Verbindungen annehmen. Der IP Server in der aktuellen Firmware 0.40 und 0.50 unterstützt nur noch TCP. Auf dem Modul werden eingehende Daten direkt mit dem Prefix **+IPD** ausgegeben: +IPD,1,6:201.9 OK +IPD,0,6:ON OK Die Ausgabe ist wie folgt aufgeteilt: +IPD,,, Dabei ist **id** die ID der Verbindung (0-5), **len** die Länge des erhaltenen Datenpakets und **data** enthält die vom Client erhaltenen Daten. In obigem Beispiel sendet als zuerst die Verbindung 1 den Wert //201.9// und dann die Verbindung 0 den String //ON// **Hinweis:** Der IP-Server kann nur im Modus AT+CIPMUX=1 eingeschaltet werden. ===== Beispiel Code ===== /* Kontaktiert eine emoncms Instanz unter IP DSTIP Port DSTPORT und virtueller Hostname HOST und sendet die interne Spannung und Temperatur des ATmega328 zur Aufzeichnung alle 15s */ #define SSID "DEINE-SSID" #define WIFIPASS "Dein.WIFI-Passwort" #define DSTIP "192.168.10.120" #define DSTPORT 80 #define CH_PD_PIN A0 #define HOST "emon.mydomain.ch" #define APIKEY "abcdef1234567890abcdef1234567890" #define USER_AGENT "User-Agent: Mozilla/0.1 (esp8266; wifi-hack)" #define LED_PIN 13 void setup() { digitalWrite(A0, HIGH); Serial.begin(115200); pinMode(LED_PIN, OUTPUT); pinMode(CH_PD_PIN, OUTPUT); digitalWrite(CH_PD_PIN, HIGH); espInit(); } void loop() { sendIotData(); delay(15000); } void espInit() { Serial.println("AT+RST"); delay(1000); if(Serial.find("ready")) { blinkOk(); } else { blinkAlert(); } Serial.println("AT+CWMODE=1"); delay(500); Serial.println("AT+CIPMUX=0"); delay(500); // Join WiFi Network Serial.print("AT+CWJAP=\""); Serial.print(SSID); Serial.print("\",\""); Serial.print(WIFIPASS); Serial.println("\""); delay(3500); if(Serial.find("OK")) { blinkOk(); } else { blinkAlert(); } } void sendIotData(){ char tpl[] = "GET /input/post.json?json={espvcc:%s,esptemp:%s}&apikey=%s HTTP/1.1\r\nHost: %s\r\n%s\r\n\r\n"; char temp[6]; char vcc[8]; double _vcc = readVcc()/1000.0; double _temp = getTemp(); dtostrf(_temp, 2, 1, temp); dtostrf(_vcc, 1, 2, vcc); char databuf[256] = ""; sprintf(databuf, tpl, vcc, temp, APIKEY, HOST, USER_AGENT); int ix = 1; for (ix=0; ix<256; ix++) { if ( databuf[ix] == 0 ) { break; } } Serial.print("AT+CIPSTART=\"TCP\",\""); Serial.print(DSTIP); Serial.print("\","); Serial.println(DSTPORT); delay(500); Serial.print("AT+CIPSEND="); Serial.println(ix); delay(100); Serial.println(databuf); delay(500); } void blinkAlert() { for (int c=0; c<3; c++) { digitalWrite(LED_PIN, HIGH); delay(80); digitalWrite(LED_PIN, LOW); delay(80); } } void blinkOk() { digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); } long readVcc() { long result; ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); delay(2); ADCSRA |= _BV(ADSC); while (bit_is_set(ADCSRA,ADSC)); result = ADCL; result |= ADCH<<8; result = 1126400L / result; return result; } double getTemp(void) { unsigned int wADC; double t; ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3)); ADCSRA |= _BV(ADEN); delay(20); ADCSRA |= _BV(ADSC); while (bit_is_set(ADCSRA,ADSC)); wADC = ADCW; // The offset of 324.31 could be wrong. It is just an indication. t = (wADC - 324.31 ) / 1.22; // The returned temperature is in degrees Celcius. return (t); } ===== Firmware Update ===== Ein Image für den Update auf Firmware 0.91 kann hier heruntergeladen werden: * Firmware ESP8266 v0.91 {{:wireless:uart_wifi_00160910.zip|Firmware ESP8266 v0.91}} Dieses Image benötigst Du unabhängig davon ob Du den Update mit Windows oder Linux durchführen willst. ==== Firmware Update mit Linux ==== Diese Anleitung gilt nur für die AT Firmware auf alten Modulen mit 512KB Flash. Das aktuelle SDK (ab 1.5.0) erfordert Module mit mindestens 1024MB Flash. **Utility**: [[https://github.com/themadinventor/esptool|esptool]] - Verbinde das Modul mit einem USB zu seriell Adapter wie dem [[http://shop.boxtec.ch/foca-v22-ft232rl-tiny-breakout-p-40332.html|Foca Board]] und achte darauf, dass das Foca Board auf 3.3V eingestellt ist. Prüfe ob die Verbindung funktioniert in dem Du die aktuelle Firmware abfragst: AT+GMR 00150900 - Verbinde den Pin **GPIO00** mit GND - Reset des Moduls (RST kurz auf GND) - Flashen des ersten Images((Der Fehler //Exception: Failed to leave Flash mode// kann ignoriert werden, das Update funktioniert trotzdem)): ./esptool.py write_flash 0x000000 eagle.app.v6.flash.bin - Reset des Moduls (RST kurz auf GND) - Flashen des zweiten Images((Der Fehler //Exception: Failed to leave Flash mode// kann ignoriert werden, das Update funktioniert trotzdem)): ./esptool.py write_flash 0x40000 eagle.app.v6.irom0text.bin - **GPIO00** von GND trennen - Reset des Moduls (RST kurz auf GND) - Firmware Version prüfen AT+GMR 00160901 ==== Firmware Update mit Windows (nicht getestet) ==== **Utility**: {{:wireless:xtcom_util.zip|XTCOM-UTIL}} Mit XTCOM-UTIL können die beiden Firmware Images nacheinander auf das Modul geladen werden, dabei muss auch **GPIO00** mit GND verbunden werden um das Modul in den Update Modus zu bringen. ===== Stromverbrauch / Latenz ===== ==== Stromverbrauch ==== Durchschnittliche Stromaufnahme bei kurzer Distanz zum AP: 30mA, bei größerer Distanz bis zu **200mA** Durchschnittliche Stromaufnahme im AP Modus: **80mA** Kurzzeitig kann die Stromaufnahme bis zu **500mA** betragen! Wenn der ESP nicht zuverlässig arbeitet, dann kann der Stromverbrauch ein Problem sein. Es empfiehlt sich genügend Strom zur Verfügung zu haben. Der USB Anschluss eines Laptops hat da evtl. ein Problem. Evtl. hilft auch schon ein grösserer Kondensator um die Spitzen abzufangen. ==== Netzwerk Latenz ==== Ein Ping dauert meist 30-130ms. Die Übertragung von Daten dauert meist 100-200ms, unabhängig von der Paketgröße. Ein Datenpaket kann maximal 1024 Bytes Nutzdaten enthalten. ==== ESP8266 mit Arduino IDE programmieren ==== Seit einiger Zeit können alle ESP8266 Module auch direkt aus der Arduino IDE programmiert werden, ein externer Mikrokontroller ist dann nicht mehr nötig. Mit 512kB - 1MB Flash bieten die Module mehr als genug Platz für anspruchsvolle Steuerungen. Um die Module direkt aus der Arduino IDE ab 1.6 zu programmieren muss in den Einstellungen folgende //Boards Manager URL// hinzugefügt werden: http://arduino.esp8266.com/stable/package_esp8266com_index.json Um das Modul in den Bootloader Modus zu versetzen muss GPIO00 auf GND gezogen werden während ein Reset ausgeführt wird (RESET Pin auf GND). In diesem Zustand angekommen, kann ein Sketch ganz normal via Upload Button aus der Arduino IDE hochgeladen werden. Am besten nimmt man für einen ersten Versuch eines der vielen mitgelieferten Beispiele. Hier ein Beispiel für einen Http Client "basichttpclient.ino". Damit lassen sich mit wenig Aufwand Messdaten an einen Server übermitteln. {{:wireless:esp_basichttpclient.png?300|}} Weiter ist auch das Beispiel NTPClient interessant. Darüber lässt sich die UTC Zeit von einem NTP Time Server auslesen. === MQTT === Mit dem ESP8266 kann man sehr einfach MQTT Meldungen absetzen oder darauf reagieren. Dazu muss die Library PubSubClient installiert werden: {{:wireless:arduino_esp8266_pubsublib_mqtt.png?500|}} Ein sehr einfaches Beispiel ist das: Basic ESP8266 MQTT example Darin müssen nur folgende Zeilen angepasst werden und schon kann man via MQTT kommunizieren. Hier muss das Wlan und der mqtt Server definiert werden: // Update these with values suitable for your network. const char* ssid = "?"; const char* password = "?"; const char* mqtt_server = "?"; Hier habe ich dann noch user und passwort ergänzt das ist natürlich von Eurem mqtt Server abhängig. if (client.connect(clientId.c_str(),"","")) { Danach noch alle Topic anpassen. Einfach die Aufrufe mit client.publish und client.subscribe. Beispiel: client.publish("user/test/esp_out", "hello world"); // ... and resubscribe client.subscribe("user/test/esp_in"); Hier seht die die Kommunikation: {{:wireless:arduino_esp8266_mqtt.png?500|}} Hier auch noch ein Beispiel für das Empfangen von Meldungen über MQTT. {{:wireless:arduino_esp8266_mqtt_in.png?500|}} ===== Fehlersuche ===== * Hast Du CH_PD auf 3.3V gezogen wenn Du versuchst mit dem Modul zu kommunizieren ? * RX/TX vertauscht ? * Hast Du sichergestellt, dass Du ausschliesslich mit 3.3V Pegel mit dem Modul kommunizierst ? * Wenn Einstellungen nicht übernommen werden: AT+RST ausgeführt um die Einstellungen zu aktivieren ? * Hat der ESP genügend Strom zur Verfügung? Siehe das Kapitel: "Stromverbrauch". ===== Links ===== * [[http://www.esp8266.com/|ESP8266 User Forum]] * [[http://www.esp8266.com/wiki/doku.php|ESP8266 User Wiki]] * [[http://cdn.boxtec.ch/pub/diverse/0A-ESP8266-Datasheet_EN_v4.3.pdf|ESP8266 Datasheet]] * [[https://github.com/esp8266/Arduino|ESP8266 core for Arduino]] | [[http://esp8266.github.io/Arduino/|ESP8266 core for Arduino]] * [[https://github.com/themadinventor/esptool|github: esptool]] * [[https://onedrive.live.com/?cid=C4DDF72E6EEA3826&id=C4DDF72E6EEA3826!631|OneDrive SDK Mirror]] * [[https://github.com/esp8266|Github ESP8266]] * [[https://github.com/nodemcu/nodemcu-firmware|Lua based firmware for wifi-soc esp8266]] * [[http://hackaday.com/2015/03/18/how-to-directly-program-an-inexpensive-esp8266-wifi-module/|Hackaday: How to directly program the ESP8266 WiFi module]] * [[https://github.com/chriscook8/esp-arduino-apboot|ESP8266 wifi configurator in Arduino lang.. uses eeprom for configs, boots to AP mode if no working config found]] * [[http://esp8266-re.foogod.com/wiki/Random_Number_Generator|ESP8266 (somewhat secret) Random Number Generator]] * [[https://github.com/anunpanya/ESP8266_QRcode|QR Code Generator Lib]] for ESP8266 with SSD1306 OLED ===== Referenzen ===== * [[http://www.electrodragon.com/w/Wi07c|Electrodragon: Wi07c]] * [[https://nurdspace.nl/ESP8266|Nurdspace: ESP8266]] * [[http://espressif.com/en/products/esp8266/|Produkteseite Espressif]] * [[http://cdn.boxtec.ch/pub/diverse/ESP8266_Specifications(Chinese).pdf|Datenblatt ESP7266 (Chinesisch)]] * [[http://cdn.boxtec.ch/pub/diverse/Espressif_AT_Instruction_Set_CN.pdf|AT Kommandos ESP7266 (Chinesisch)]] * [[http://www.mikrocontroller.net/topic/342240|Mikrokontroller.net Forum]]