ESP8266 Wetteranzeige

DSC_1987

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

esp8266_pinout_h

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.

 

 

weather-display

 

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.

Quellcode

19 thoughts to “ESP8266 Wetteranzeige”

  1. 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?

    1. 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.

    2. 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.

  2. 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

  3. 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.

      1. 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

  4. 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?

  5. Mittlerweile habe ich den Verdacht, dass das Ganze mit der Library, die jetzt heruntergeladen werden kann, nicht mehr funktioniert. Kann das jemand bestätigen?

  6. 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?

Leave a Reply

Your email address will not be published. Required fields are marked *