Im ersten Beitrag ESP8266 DIY IoT Wetterstation mit OLED Display und DHT11 Sensor zur ESP8266 DIY IoT Wetterstation habe ich gezeigt wie diese aufgebaut und die Sensordaten des DHT11 Sensors auf dem beigefügten 0,96″ OLED Display angezeigt werden können. In diesem zweiten Teil möchte ich dir nun zeigen wie einfach es ist, diese Daten auf einer kleinen Webseite anzuzeigen und im internen WLAN bereit zustellen.
benötigte Bauteile
Der Bausatz “ESP8266 DIY IoT Wetterstation mit OLED Display und DHT11 Sensor” beinhaltet alles was du auch für dieses Projekt benötigst. Es wird lediglich ein bestehendes WLAN Netzwerk benötigt. Von diesem Netzwerk benötigst du den WLAN Schlüssel (SSID) sowie das Passwort.
Programmieren
Wie man den Treiber für den Microcontroller ESP8266 sowie für den DHT11 Sensor und das Display in der Arduino IDE installiert habe ich bereits im ersten Beitrag zu diesem Bausatz erläutert. Auf diese Installation möchte ich aufsetzen und die Bibliotheken für den WiFi betrieb verwenden.
In den Beiträgen
- WEMOS D1 – WLAN Thermometer mit DHT11 Sensor
- WEMOS D1 – WLAN Thermometer – Teil2 Upload der Daten in eine Datenbank
- ESP Weekendprojekt #1: DIY WiFi Wetterstation
habe ich diese Thematik bereits ausführlich behandelt, der dort verwendete Wemos D1 Mini hat einen gleichen Chipsatz und somit ist der Code kompatibel auch mit diesem Bausatz. Ich möchte darum hier nur kurz anschneiden wie man das Display zusätzlich nutzen kann um die IP-Adresse und den Status anzeigen zu lassen.
Aufbau einer WiFi Verbindung
Einbinden der Bibliothek für die WiFi Verbindung:
#include <ESP8266WiFi.h>
Für den Aufbau der WiFi Verbindung benötigst du die SSID sowie das Passwort für das Netzwerk.
const char* ssid = ""; //SSID aus dem Router const char* password = ""; //Passwort für den Zugang zum WLAN
Zunächst erzeugen wir uns ein WebServer Objekt welcher auf den Port 80 “lauscht”. Dieser Port ist der default Port für die HTTP Kommunikation.
WiFiServer server(80); //Port auf welchem der Server laufen soll.
Du könntest hier auch einen anderen Port wählen, dann musst du diesen jedoch beim Aufrufen der Adresse mitgeben:
http://<ID-ADRESSE>:<PORT>/
Funktion zum starten der WiFi Verbindung
void setupWiFi(){ //löschen des Displays display.clearDisplay(); //setzen des Cursors auf die Zeile=0, Spalte=0 display.setCursor(0,0); //schreiben der Zeichenkette auf das Display display.println("SSID"); //setzen des Cursors auf die Zeile=10, Spalte=0 display.setCursor(0,10); //schreiben der SSID display.println(ssid); //anzeigen des Textes display.display(); //Initialisieren der Wifi Verbindung. WiFi.begin(ssid, password); int index = 0; //Warten bis die Verbindung aufgebaut wurde. while (WiFi.status() != WL_CONNECTED) { delay(500); //eine kleine Pause von 500ms index = index +1; //incrementieren des Indexes //setzen des Cursors auf die Spalte=<index> und Zeile=18 display.setCursor(index,18); //schreiben eines Striches an die gesetzte Stelle display.println("-"); //anzeigen / aktualisieren des Displays display.display(); } //löschen des Displays display.clearDisplay(); //setzen des Cursors auf die Zeile=0; Spalte=0 display.setCursor(0,0); //schreiben des Textes auf das Display display.println("Server gestartet"); //starten des Servers server.begin(); // Starten des Servers. //setzen des Cursors auf die Zeile=10; Spalte=0 display.setCursor(0,10); //schreiben des Textes auf das Display display.println("IP-Adresse"); //setzen des Cursors auf die Zeile=18; Spalte=0 display.setCursor(0,18); //schreiben des Textes auf das Display display.println(WiFi.localIP().toString()); //aktualisieren des Displays display.display(); }
In der Funktion loop prüfen wir zunächst ob der WiFi Adapter verbunden ist, wenn dieses nicht ist wird eine Verbindung aufgebaut.
void loop(){ if(WiFi.status() != WL_CONNECTED){ setupWiFi(); } ... }
Der Vorteil an diesem ist, das wir dadurch einen eventuellen Netzwerkausfall die Verbindung somit automatisch wiederherstellen.
Wir können nun die IP-Adresse des WebServers vom Display ablesen. Und uns über einen Browser mit diesem Verbinden. Jedoch haben wir bisher keinen Code hinterlegt was passieren soll wenn sich ein Client mit dem Server verbindet, das wollen wir nun nachholen.
Aktion für einen Client definieren
Wir haben nun ein Verbindung zum WLAN Netzwerk hergestellt, als nächstes müssen bzw. sollten wir definieren was passieren soll wenn sich ein Client über einen Browser mit dem Server verbindet.
Wir können die Daten als JSON, XML, CSV oder auch als HTML Seite liefern.
Die Datenformate JSON,XML und CSV haben den Vorteil das diese durch weitere Systeme ausgewerte und somit besser maschinell verarbeitet werden können, eine HTML Seite ist für den Menschen gedacht und kann mit zusätzlichem Style (CSS) formatiert werden.
Zunächst prüfen wir ob überhaupt ein Client verbunden ist, wenn dieses nicht so ist können wir die Funktion loop verlassen und wieder am anfang der Funktion “loop” beginnen.
void loop(){ ... //Prüfen ob sich ein Client verbunden hat, wenn nicht die Loop "verlassen" WiFiClient client = server.available(); if (!client) { return; } // Wenn sich ein Client verbunden hat solange warten bis Daten gesendet werden. Serial.println("Neuer Client verbunden."); while(!client.available()){ delay(1); } ... }
Wenn sich jedoch ein Client verbunden hat dann wollen wir diesem unsere Seite präsentieren bzw. als HTTP Respond ausliefern.
void loop(){ ... writeResponse(client); } /** * Die Funktion gibt den HTML Kopf auf dem Client aus. * Dieses wird für jeden Respond verwendet. **/ void writeResponse(WiFiClient client){ client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(""); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<body>"); client.println("Hello World from ESP8266"); client.println("</body>"); client.println("</html>"); }
Als HTTP Respond (das ist die Antwort auf einen HTTP Request), senden wir unser HTML Grundgerüst mit dem Text “Hello World from ESP8266”. Durch die Angabe des “Content-Type” text/html, weiß der Browser das er dieses als HTML Seite darstellen soll.
Wenn wir nun den Code auf den Chip hochladen und im Browser die IP-Adresse eingeben erhalten wir die gewünschte HTML Seite.
Hier nun der Sketch für den ersten Versuch:
Darstellen der Sensordaten auf einer HTML Seite
Wir können nun eine HTML Seite an einen Client ausliefern, in diese können wir nun unsere Sensordaten wiefolgt einfügen.
/** * Die Funktion gibt die Sensordaten des DHT11 Sensors auf einer HTML Seite aus * Dieses wird für jeden Respond verwendet. **/ void writeResponse(WiFiClient client){ client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(""); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<body>"); //lesen der rel. Luftfeuchtigkeit float h = dht.readHumidity(); //lesen der Temperatur in Grad Celsius //mit der übergabe des Parameters "false" in der Funktion //readTemperature(), wird der Wert in Grad Fahrenheit geliefert float t = dht.readTemperature(); float f = dht.readTemperature(true); //prüfen ob Zahlenwerte geliefert wurden //Wenn der Sensor nicht gefunden wurde, dann enthalten die float Variablen "NaN" if (isnan(h) || isnan(t) || isnan(f)) { client.println("Fehler beim lesen der Sensorwerte!"); } else { client.print("Temperatur: "); client.print(String(t,2)); client.println(" °C"); client.println("<br/>"); client.print("Temperatur: "); client.print(String(f,2)); client.println(" °F"); client.println("<br/>"); client.print("rel. Luftfeuchtigkeit: "); client.print(String(f,2)); client.println(" %"); } client.println("</body>"); client.println("</html>"); }
Wenn wir nun die IP-Adresse wie auch zuvor im Browser eingeben erhalten wir statt des Textes unsere Sensorwerte.
Um nun die Daten zu aktualisieren müssen wir im Browser nur F5 oder die Schaltfläche zum neuladen der Seite betätigen. Jedoch können wir mit einem einfachen einfügen eines redirects nach x Sekunden auf die gleiche Seite auch fortlaufend aktualisieren.
In diesem Fall wird die Seite nach 5 Sekunden aktualisiert.
client.println("<head>"); client.println("<meta http-equiv='refresh' content='5; URL=http://"+WiFi.localIP().toString()+"'/>"); client.println("</head>");
Hier nun der fertige Sketch zum Download