Dies ist mein erster Versuch mit einem ESP8266 WiFi-Modul und einem Arduino Daten zu laden. Das Programm auf dem Arduino basiert auf dem Beispiel von Seedstudio, holt aktuelle Wetterdaten von openweathermap.org und zeigt diese auf einem kleinen Display an.
Das Modul
Das Modul habe ich bei Electrodragon gekauft. Diese Version hat zwei LEDs, eine rote Power-LED und eine TX-LED. Das Modul läuft mit 3.3 Volt und die serielle Schnittstelle ist auf 115200 baud eingestellt. Der CH_PD-Pin muss auf high liegen. Nach einem Reset gibt das Modul folgendes über die serielle Schnittstelle aus:
[code]
AT+RST
OK
ets Jan 8 2013,rst cause:4, boot mode:(3,6)
wdt reset
load 0x40100000, len 24236, room 16
tail 12
chksum 0xb7
ho 0 tail 12 room 4
load 0x3ffe8000, len 3008, room 12
tail 4
chksum 0x2c
load 0x3ffe8bc0, len 4816, room 4
tail 12
chksum 0x46
csum 0x46
ready
[/code]
Verkabelung
Die Verkabelung ist ziemlich einfach. Das Modul braucht nur jeweils zwei Leitungen für die Stromversorgung und die serielle Kommunikation. Als Display habe ich ein 1.8 Zoll (45.72 mm) TFT-Display genommen das via SPI-Schnittstelle angesteuert wird.
Arduino | ESP8266 Module | Display Module |
---|---|---|
3.3V | VCC & CH_PD | – |
5V | – | VCC |
GND | GND | GND & BKL |
0 (RX) | TX | – |
1 (TX) | RX | – |
8 | – | RESET |
9 | – | RS |
10 | – | LCD CS |
11 | – | MOSI |
13 | – | SLCK |
Das Programm
Den Quellcode von Seedstudio habe ich etwas abgeändert. Da bei 115200 baud der 64Byte UART-Buffer des Arduino schnell voll ist, wird der Buffer so schnell wie möglich geleert. Ansonsten ist das Programm ziemlich einfach gestrickt.
[code language=”java”]
#include <SoftwareSerial.h>
#include <JsonParser.h>
#define cs 10 // Pins for the display
#define dc 9
#define rst 8
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
using namespace ArduinoJson::Parser;
#define SSID "<ssid>" // insert your SSID
#define PASS "<password>" // insert your password
#define LOCATIONID "2925533" // location id
#define DST_IP "188.226.224.148" //api.openweathermap.org
SoftwareSerial dbgSerial(2, 3); // RX, TX for debugging
JsonParser<32> parser;
void setup()
{
Serial.begin(115200);
Serial.setTimeout(5000);
dbgSerial.begin(9600); // for debuging
dbgSerial.println("Init");
tft.initR(INITR_BLACKTAB);
tft.setRotation(1);
tft.fillScreen(ST7735_BLACK);
tft.setCursor(2, 2);
tft.setTextColor(ST7735_WHITE);
Serial.println("AT+RST"); // restet and test if module is redy
delay(1000);
if(Serial.find("ready")) {
dbgSerial.println("WiFi – Module is ready");
tft.println("WiFi – Module is ready");
}else{
dbgSerial.println("Module dosn’t respond.");
tft.println("Module dosn’t respond.");
tft.println("Please reset.");
while(1);
}
delay(1000);
// try to connect to wifi
boolean connected=false;
for(int i=0;i<5;i++){
if(connectWiFi()){
connected = true;
tft.println("Connected to WiFi…");
break;
}
}
if (!connected){
tft.println("Coudn’t connect to WiFi.");
while(1);
}
delay(5000);
Serial.println("AT+CIPMUX=0"); // set to single connection mode
}
void loop()
{
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += DST_IP;
cmd += "\",80";
Serial.println(cmd);
dbgSerial.println(cmd);
if(Serial.find("Error")) return;
cmd = "GET /data/2.5/weather?id=";
cmd += LOCATIONID;
cmd += " HTTP/1.0\r\nHost: api.openweathermap.org\r\n\r\n";
Serial.print("AT+CIPSEND=");
Serial.println(cmd.length());
if(Serial.find(">")){
dbgSerial.print(">");
}else{
Serial.println("AT+CIPCLOSE");
dbgSerial.println("connection timeout");
tft.fillScreen(ST7735_BLACK);
tft.setCursor(2, 2);
tft.setTextColor(ST7735_WHITE);
tft.println("connection timeout");
delay(1000);
return;
}
Serial.print(cmd);
unsigned int i = 0; //timeout counter
int n = 1; // char counter
char json[100]="{";
while (!Serial.find("\"main\":{")){} // find the part we are interested in.
while (i<60000) {
if(Serial.available()) {
char c = Serial.read();
json[n]=c;
if(c==’}’) break;
n++;
i=0;
}
i++;
}
dbgSerial.println(json);
JsonObject root = parser.parse(json);
double temp = root["temp"];
double pressure = root["pressure"];
double humidity = root["humidity"];
temp -= 273.15; // from kelvin to degree celsius
tft.fillScreen(ST7735_BLACK);
tft.setCursor(2, 25);
tft.setTextColor(ST7735_BLUE);
tft.setTextSize(2);
tft.print("Temp: ");
tft.print((int)temp);
tft.print(".");
tft.print((int)((temp-(int)temp)*10));
tft.println(" C");
tft.setCursor(2, 55);
tft.setTextColor(ST7735_GREEN);
tft.setTextSize(2);
tft.print("Press: ");
tft.print((int)pressure);
tft.setCursor(2, 85);
tft.setTextColor(ST7735_YELLOW);
tft.setTextSize(2);
tft.print("Humidity: ");
tft.print((int)humidity);
tft.println("%");
dbgSerial.println(temp);
dbgSerial.println(pressure);
dbgSerial.println(humidity);
dbgSerial.println("====");
delay(600000);
}
boolean connectWiFi()
{
Serial.println("AT+CWMODE=1");
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
dbgSerial.println(cmd);
Serial.println(cmd);
delay(2000);
if(Serial.find("OK")){
dbgSerial.println("OK, Connected to WiFi.");
return true;
}else{
dbgSerial.println("Can not connect to the WiFi.");
return false;
}
}
[/code]
Fazit
Das Programm ist sehr einfach gehalten, und eigentlich könnte man noch mehr Daten anzeigen. Wenn ihr Verbesserungsvorschläge habt, schreibt sie einfach in die Kommentare.
Hier noch zwei Links mit weiteren Informationen:
Update: Es hat sich ein kleiner Programmierfehler eingeschlichen, aber Jody Roth hat ihn entdeckt. Der Fehler ist jetzt behoben.
Cool! Wird wohl noch zwei oder drei Wochen dauern bis meine Module da sind. Ich bin gespannt…
Kannst Du was darueber sagen wie die Reichweite fuer den WLAN-Empfang ist? Also im Vergleich zu einem Handy oder einem Notebook? Welche Strecke ueberbrueckst Du damit?
Der Empfang ist damit besser als erwartet. Also zumindest besser als mit einem Samsung Galaxy S Plus. Allerdings habe ich das noch nicht ausgiebig getestet.
… und ich warte immer ungeduldiger auf die Lieferung. 🙂
Es gibt ein Video in welchem ein paar Jungs die Reichweite zwischen einem Router und dem ESP8266 testen, und (zum Teil mit Modifikationen) auf Reichweiten von einigen hundert Metern bis zu einigen Kilometern kommen.
Hast du schon versucht, den ESP8266 als Server zu betreiben? Mich würde interessieren, ob man den Kleinen auch per Broadcast-Nachricht erreichen kann. (Sprich, mehrere Empfänger gleichzeitig zu kontaktieren).
Beste Grüße,
Sascha
Das habe ich noch nicht ausprobiert, aber angeblich soll er sich auch als Server betreiben lassen. Was Multicast angeht, so glaube ich das dies mit der aktuellen Firmware nicht möglich ist. Aber mit einer neuen Firmware wäre dies möglich.
http://www.esp8266.com/viewtopic.php?f=9&t=224
Du schließt RX und TX von einem 5V Arduino Board einfach an das esp8266 Modul?
Sind die 5V des Arduino nicht zu viel? esp8266 arbeitet ja mit 3.3V.
Zumindest mein Modul scheint, obwohl es mit 3.3 Volt arbeitet, die 5 Volt des Arduinos zu verkraften.
Hm, fragt sich wie lange 😀
wo finde ich die #include lib ?
wo finde ich die #include JsonParser.h lib ?
hier: https://github.com/bblanchon/ArduinoJson
Habe versucht es nach zu bauen.
Kannst du mir genau sagen, wie du die lib abgelegt hast?
Einfach die Zip-Datei von github nach libraries zu entpacken (in ein Unterverzeichnis “JsonParder”) geht nicht.
Vielen Dank
Danke für Ihre Artikel.
Ich habe Arduino für ESP8266 entdeckt und Programm direkt für ESP8266 Controller in Arduino IDE geschrieben. Da braucht man kein zusätzlicher Arduino-Board. Hier sind meine ersten Sketche http://esp8266-server.de/
Ich bekomme den folgenden Fehler:
fatal error: JsonParser.h: No such file or directory
Die Datei ist auch nicht in der Library enthalten. Wie kann ich vorgehen?
Mittlerweile habe ich den Verdacht, dass das Ganze mit der Library, die jetzt heruntergeladen werden kann, nicht mehr funktioniert. Kann das jemand bestätigen?
Wie finde ich meine LOCATIONID ?
Ich habe nun meine Module erhalten und gemäß Tutorial den Aufbau vorgenommen.
Als Libraries habe ich installiert: ArduinoJson-master und ArduinoJsonParser-master .
Die anderen waren schon installiert von anderen kleinen Projekten.
Ich habe aber beim Kompilieren gleich eine Fehlermeldung in der Zeile:
using namespace ArduinoJson::Parser;
Fehlermeldung:
Wetter_ESP:12: error: ‘ArduinoJson’ has not been declared
Wetter_ESP:12: error: ‘Parser’ is not a namespace-name
Wetter_ESP:12: error: expected namespace-name before ‘;’ token
Hat jemand einen Tipp für mich Anfänger?