Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Über mich
  • Deutsch
  • English
Menu

ESP Weekendprojekt #1: DIY Wi-Fi Wetterstation

Posted on 19. März 20207. März 2024 by Stefan Draeger

In diesem Beitrag möchte ich dir zeigen, wie du dir mit wenigen Bauteilen, relativ günstig und vor allem an einem Wochenende eine kleine DIY Wi-Fi Wetterstation aufbaust.

DIY Wetterstation mit Wemos D1 Mini & DHT11 Sensor

  • Ziel
  • benötigte Bauteile
  • Werkzeuge
  • Aufbau
    • das Gehäuse
    • Bodenplatte
    • zusammenstecken der Shields
    • Anschluss der Batterie
  • Programmierung
    • Ausbaustufe 1 – Daten auf der seriellen Schnittstelle ausgeben
    • Ausbaustufe 2 – Webserver einrichten
    • Ausbaustufe 3 – zusammenfügen der Sketche
    • Ausbaustufe 4 – Daten als JSON Bereitstellen
      • ein kleines Oracle Java Programm
      • Python3 Script
    • Ausbaustufe 5 – Daten in einer Webseite darstellen
      • Daten als Text darstellen
        • automatische Aktualisierung nach x Sekunden
    • Ausbaustufe 6 – Daten in einem Diagramm darstellen
      • Liniendiagramm 
        • eine Tabelle mit Daten implementieren

Ziel

Das Ziel soll es zunächst sein die Wetterstation aufzubauen und eine kleine Webseite zu erstellen auf welcher die Messdaten eines DHT11 (Temperatur & relative Luftfeuchtigkeit) anzeigt.

Wemos D1 mini DHT11 Shield
Wemos D1 mini DHT11 Shield

Die Webseite kann von einem Smartphone, Tablet oder ähnlichem Gerät aufgerufen werden. Dabei spielt die Zielplattform (Android, iPhone, Windows Phone) keine Rolle.

benötigte Bauteile

BeschreibungPreis
Wemos D1 Mini*2 €
Wemos D1 Mini, DC Power Supply Modul*2 €
Wemos D1 Mini, DHT11*3,5 €
Wemos D1 Mini, Dual Base Shield*1 €
Batterieclip mit Anschlußkabel und Hohlbuchse*1 €
9V Blockbatterie**1 €
Frischebox (als Gehäuse)*1,5 €
Micro USB Kabel (min. 1m)*3 €
4x M3 Schraube inkl. Mutter3 €
1x kleinen Kabelbinder (für die Batterie) 

Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!

Die 9V Block Batterie erhält man in jedem gut sortierten Supermarkt (zbsp. Aldi, Lidl).
Die Frischebox habe ich aus dem örtlichen Woolworth für knapp 1,5 € erhalten, natürlich findet man diese auch im T€di, 1 € Shop, Thomas Phillips oder andere günstige Märkte.

Die Gesamtkosten des Projektes betragen ca. 18€.

Werkzeuge

  • Bohrmaschine,
    • 10er Holzbohrer
  • Lötkolben, 15 Watt
    • Lötzinn,
    • hitzebeständige Unterlage
  • evtl. dritte Hand,
  • Seitenschneider,
  • Entlötpumpe,

Aufbau

Der Vorteil am Wemos D1 Mini ist, dass, die Module, nachdem Löten einfach zusammengesteckt werden können. Jedoch muss man darauf achten, dass die Module korrekt zusammengesteckt werden, d.h. man muss auf die Beschriftung der Platine achten!

Pinbelegung auf den Shields
Pinbelegung auf den Shields

Die Module werden fast komplett zerlegt geliefert d.h. wir müssen zunächst die Pins anlöten.

Wemos D1 mini Shield - DC Power Shield
Wemos D1 mini Shield – DC Power Shield

Es empfiehlt sich für das Zusammenlöten ein kleines, 170 Pin, Breadboard zu verwenden, auf dieses Breadboard lassen sich die Pins im geradezu 90 Grad Winkel stecken und somit ist die Platine zum Löten bestens ausgerichtet.

Breadboards
Breadboards

das Gehäuse

Es gibt einige Gehäuse, welche man mit einem 3D Drucker drucken kann, die entsprechenden Vorlagen findet man zbsp. unter Thingiverse.com. In diesem kleinen Weekend Projekt möchte ich jedoch auf eine einfache Frischebox zurückgreifen, denn das Drucken eines solchen Gehäuses würde selber ein Wochenende dauern. (natürlich ist das abhängig vom 3D Drucker)

Frischebox als Gehäuse für die DIY Wetterstation
Frischebox als Gehäuse für die DIY Wetterstation

Ich verwende eine Frischebox mit den Abmaßen 

  • nutzbare Fläche 70 mm x 70 mm
  • Höhe 40 mm

In dieses Gehäuse wird nun mit einem 10er-Holzbohrer in jede Seite ein Loch gebohrt. Das Loch wird anschließend mit einem scharfen Taschenmesser (zbsp. Opinel Nr.9) oder einem Cuttermesser entgratet.

Bodenplatte

Damit die Dual Base Plate des Wemos und die 9v Batterie sicher im Gehäuse verstaut und untergebracht ist, benötigen wir eine kleine Bodenplatte im Maß von 70 mm x 70 mm. Hier bietet sich einfaches 3 mm Sperrholz an, dieses bekommst du in jedem Baumarkt (und wenn man lieb fragt sägen diese einem das auf genau richtige Maß zurecht).

Ich verwende hier mir meinen 3D Drucker mit transparentem, 1,75mm Filament.

Bodenplatte - DIY Wetterstation
Bodenplatte – DIY Wetterstation

Zum selber Nachdrucken, findest du hier das STL File:

3D Modell – Bodenplatte, DIY WetterstationHerunterladen

Auf die Bodenplatte kann man nun mit den M3 Schrauben die Dual Base Plate des Wemos D1 mini festschrauben. Oder aber man verwendet kleine Plastikschrauben inkl. Abstandshalter und Muttern. Diese gibt es im Sortiment auf zbsp. ebay.de für 10 Euro in Schwarz oder Weiß.

Abstandhalter & Schraubensortiment
Abstandhalter & Schraubensortiment

Wer etwas mehr investieren möchte, kann sich diese auch in Messing oder sogar Edelstahl kaufen, diese sind jedoch deutlich teuer.

zusammenstecken der Shields

Die Shields des Wemos D1 mini kann man ineinander stecken. Ein Problem gibt es nur bei recht großen Modulen auf den Shields oder aber wo es keinen Sinn ergibt zbsp. OLED Display, 8×8 LED Matrix, Button Shield. 

Jedoch kann man die hier verwendeten Shields in fast unendlichen Möglichkeiten zusammenstecken.

Auf einer mini Wetterstation mit dem Wemos D1 mini

Dadurch das ich am Power Shield die Stiftleisten ohne Buchsenleiste angelötet habe, bin ich hier etwas eingeschränkt. Aber das ist kein Problem.

Anschluss der Batterie

Die 9V Block Batterie wird mit einem Batterieclip angeschlossen. Am einfachsten ist der Batterieclip mit einem Hohlstecker, denn dieser kann in das Power Shield gesteckt werden ohne dass man auf die korrekte Polung achten. Ich verwende einen Batterieclip ohne Hohlstecker, jedoch gibt es da keine großen Unterschiede.

Programmierung

Die Programmierung des Sketches möchte ich in 6 Stufen machen.
Mit jeder Ausbaustufe wächst das kleine Projekt und wir haben nach jeder dieser Stufe ein fertiges „Produkt“.

Wichtig: Die ersten beiden Ausbaustufen werden in der dritten Ausbaustufe zusammengeführt und für alle anderen benötigt, d.h. du kannst ab der Ausbaustufe 3 jeweils zu der Stufe wechseln, welche du für dein Projekt benötigst.

Ausbaustufe 1 – Daten auf der seriellen Schnittstelle ausgeben

In der ersten Ausbaustufe werden die Daten (Temperatur und relative Luftfeuchtigkeit) des DHT11 Sensors auf der seriellen Schnittstelle ausgegeben. Dieses habe ich bereits in dem Beitrag Wemos D1 mini Shield: DHT11 Sensor behandelt.

#include "DHT.h" //DHT Bibliothek

//Pin an welchem der DHT11 Sensor angeschlossen ist.
//Beim DHT11 Shield ist es der digitale Pin D4.
#define DHTPIN D4 
 
//Festlegen welcher Typ von DHT Sensor verwendet wird.
#define DHTTYPE DHT11

//Initialisieren des Sensors mit dem Anschluss und dem Typ
DHT dht(DHTPIN, DHTTYPE);
 
void setup() {
  Serial.begin(9600); //Begin der seriellen Kommunikation mit 9600 Baud.
  //Ausgabe eines Textes auf dem seriellen Ausgang.
  Serial.println("Wemos D1 mini DHT11 Shield"); 
 
  dht.begin(); //DHT Kommunikation beginnen.
}
 
void loop() {
  //Der DHT11 Sensor liefert alle 2 Sekunden einen neuen
  //Wert daher lohnt es sich nicht die loop konstant durchlaufen 
  //zu lassen.
  delay(2000);
 
  //lesen der Luftfeuchtigkeit
  double luftfeuchtigkeit = dht.readHumidity();
  //lesen der Temperatur in Grad Celsius
  double temperaturC = dht.readTemperature();
  //lesen der Temperatur in Grad Fahrenheit
  //mit dem Boolean Parameter wird "gesteuert" ob
  //die Temperatur in Fahrenheit oder Celsius ausgegeben wird.
  double temperaturF = dht.readTemperature(true);
 
  //Prüfen ob die Werte erfolgreich gelesen wurden.
  if (isnan(luftfeuchtigkeit) || isnan(temperaturC) || isnan(temperaturF)) {
    Serial.println("Fehler beim lesen von Daten.");
    return;
  }
  
  Serial.print("Luftfeuchtigkeit: ");
  Serial.print(luftfeuchtigkeit);
  Serial.println(" %\t");
  Serial.print("Temperatur: ");
  Serial.print(temperaturC);
  Serial.print(" °C ");
  Serial.print(temperaturF);
  Serial.println(" °F\t");
}

Ausbaustufe 2 – Webserver einrichten

Im zweiten Abschnitt werden wir nun zum bestehenden Sketch die Eigenschaften für einen Webserver hinzufügen. Diese Eigenschaften benötigen wir, damit wir später mit einem Browser oder einer Anwendung auf den Webserver zugreifen und so die Daten empfangen können.

#include <ESP8266WiFi.h>

const char* ssid = ""; //SSID aus dem Router
const char* password = ""; //Passwort für den Zugang zum WLAN

WiFiServer server(80);

void setup() {
  Serial.begin(115200); //Baudrate für die Serielle Geschwindigkeit.
  delay(10); //10ms. Warten damit die Seriele Kommunikation aufgebaut wurde.

  Serial.print("Aufbau der Verbindung zu: "); //Ausgabe der SSID auf der Seriellen Schnittstelle.
  Serial.println(ssid);

  WiFi.begin(ssid, password); //Initialisieren der Wifi Verbindung.

  while (WiFi.status() != WL_CONNECTED) { //Warten bis die Verbindung aufgebaut wurde.
    delay(500);
    //Einen Punkt auf der Seriellen Schnittstelle ausgeben so das der Benutzer erkennt dass, das Sketch noch läuft.
    Serial.print(".");
  }

  //Bei erfolgreicher Verbindung wird der folgende Text ausgeben.
  Serial.print("Mit ");
  Serial.print(ssid);
  Serial.print("erfolgreich verbunden!");

  server.begin(); // Starten des Servers.
  Serial.println("Server gestartet"); //Ausgabe auf der Seriellen Schnittstelle das der Server gestartet wurde.

  // Ausgabe der IP Adresse
  Serial.print("Adresse : http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");
}

void loop() {
  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);
  }
  client.flush();
  delay(1500);
}

Es muss nun noch die SSID und das Passwort in die entsprechende Variablen eingegeben werden.

Wenn man nun den Sketch auf den Mikrocontroller hochlädt, dann sollte nach einer kleinen Wartezeit der Server sich mit dem Router verbinden.

Ausgabe des Sketches auf dem seriellen Monitor der Arduino IDE
Ausgabe des Sketches auf dem seriellen Monitor der Arduino IDE

Ausbaustufe 3 – zusammenfügen der Sketche

Als Nächstes wollen wir nun die beiden ersten geschriebenen Sketche zu einem zusammenfügen und die Daten in zwei Funktionen auslesen (einmal die Temperatur, einmal die relative Luftfeuchtigkeit). Diese Funktionen werden wir im späteren Verlauf weiter verwenden. 

#include <ESP8266WiFi.h>
#include "DHT.h"

const char* ssid = ""; //SSID aus dem Router
const char* password = ""; //Passwort für den Zugang zum WLAN

WiFiServer server(80);

#define DHT11PIN D4
#define DHT11TYPE DHT11
DHT dht11(DHT11PIN, DHT11TYPE);

void setup() {
  Serial.begin(115200); //Baudrate für die Serielle Geschwindigkeit.
  delay(10); //10ms. Warten damit die Seriele Kommunikation aufgebaut wurde.

  Serial.print("Aufbau der Verbindung zu: "); //Ausgabe der SSID auf der Seriellen Schnittstelle.
  Serial.println(ssid);

  WiFi.begin(ssid, password); //Initialisieren der Wifi Verbindung.

  while (WiFi.status() != WL_CONNECTED) { //Warten bis die Verbindung aufgebaut wurde.
    delay(500);
    //Einen Punkt auf der Seriellen Schnittstelle ausgeben so das der Benutzer erkennt dass, das Sketch noch läuft.
    Serial.print(".");
  }

  Serial.println("");

  //Bei erfolgreicher Verbindung wird der folgende Text ausgeben.
  Serial.print("Mit ");
  Serial.print(ssid);
  Serial.print(" erfolgreich verbunden!");

  server.begin(); // Starten des Servers.
  Serial.println("Server gestartet"); //Ausgabe auf der Seriellen Schnittstelle das der Server gestartet wurde.

  // Ausgabe der IP Adresse
  Serial.print("Adresse : http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");

  dht11.begin();
}

void loop() {
  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);
  }

  Serial.println(getTempCelsius());
  Serial.println(getTempFahrenheit());
  Serial.println(getHumidity());
  
  client.flush();
  delay(1500);
}

//Temperatur in Celsius vom Sensor DHT11 lesen
float getTempCelsius() {
  return getTemp(false);
}

//Temperatur in Fahrenheit vom Sensor DHT11 lesen
float getTempFahrenheit() {
  return getTemp(true);
}

//Liefert die Temperatur vom DHT11 Sensor
//der Parameter inFahrenheit steuert ob
//die Temperatur in Fahrenheit (true) oder in Celsius (false)
//geliefert wird.
float getTemp(bool inFahrenheit) {
  float tempValue = dht11.readTemperature(inFahrenheit);
  if (isnan(tempValue)) {
    Serial.println("DHT11 konnte nicht ausgelesen werden");
    tempValue = -1;
  }
  return tempValue;
}

//Lesen der relativen Luftfeuchtigkeit vom DHT11 Sensor
float getHumidity() {
  float humidity = dht11.readHumidity();
  if (isnan(humidity)) {
    Serial.println("DHT11 konnte nicht ausgelesen werden");
    humidity = -1;
  }
  return humidity;
}

Wenn wir also nun in einem Browser die IP-Adresse eingeben, welche auf dem seriellen Monitor der Arduino IDE angezeigt wird, eingeben, dann sehen wir zwar keine Ausgabe im Browser, aber wir erhalten auf dem seriellen Monitor der Arduino IDE folgende Ausgabe:

.......Mit FRITZBox7590GI24 erfolgreich verbunden!Server gestartet
Adresse : http://192.168.178.41/
Neuer Client verbunden.
24.00
75.20
45.00
Neuer Client verbunden.
24.00
75.20
45.00
Neuer Client verbunden.
24.00
75.20
43.00
Neuer Client verbunden.
24.00
75.20
43.00

In diesem Fall habe ich 3x die Seite mit der Taste „F5“ aktualisiert.

Mit diesem Sketch können wir nun die weiteren Ausbaustufen des Projektes durchführen.

Ausbaustufe 4 – Daten als JSON Bereitstellen

Wenn wir die Daten des DHT11 Sensors mit einem anderen System (zbsp. Raspberry PI oder ähnliches) benötigen wir ein einfaches, lesbares Format. Hier bieten sich XML und JSON an. Für dieses Projekt möchte das JSON Format benutzen. 

{
	"temperatur": {
		"celsius": 21.00,
		"fahrenheit": 69.80
	},
	"humidity": 39.00
}

Zunächst schreiben wir uns eine Funktion, in welcher wir eine Rückgabe / Respond an den Client senden. Dieser Respond kann von einem Browser (wie Mozilla FireFox, Google Chrome) oder aber auch einem Tool wie Postman empfangen und angezeigt werden.

Als Parameter übergeben wir dieser Funktion den bereits verbundenen WiFiClient.

In der ersten Zeile wird der HTTP Header sowie der Content-Type gesetzt. Über diese Daten kann dann das Tool bzw. der Browser ermitteln, um welche Daten es sich handelt und vor allem, ob alles richtig abgelaufen ist. Bei einem Fehler könnte man zbsp. einen anderen HTTP Fehlercode senden.

Der Content-Type wird in einigen Browsern auch verwendet um die Daten Formatiert anzeigen zu lassen.

void sendRespond(WiFiClient client){
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: application/json");
  client.println("");
  client.print("{");
  client.print("\"temperatur\":");
  client.print("{");
  client.print("\"celsius\":");
  client.print(getTempCelsius());
  client.print(",");
  client.print("\"fahrenheit\":");
  client.print(getTempFahrenheit());
  client.print("},");
  client.print("\"humidity\":");
  client.print(getHumidity());
  client.println("}");  
}

Die Funktion „sendRespond“ wird nun in der Loop eingebunden. Da wir dafür einen verbundenen Client benötigen (wo sollen wir sonst die Daten hinsenden?) muss dieses nach der Schleife “ while (!client.available())“ geschehen. Jedoch muss dieses auch vor dem Absenden der gesamten Daten an den Client passieren („client.flush();“).

Serial.println("Neuer Client verbunden.");
while (!client.available()) {
  delay(1);
}

sendRespond(client);

client.flush();

Wenn die neue Funktion implementiert wurde, kann nun der Sketch erneut auf den Wemos D1 mini geladen werden und wir können einen Test durchführen.

Ich nutze zunächst das Tool Postman. (Dieses habe ich auch bereits in anderen Beiträgen auf diesem Blog eingesetzt.)

DIY Wetterstation - JSON Respond
DIY Wetterstation – JSON Respond

Wir haben also nun unsere Daten im JSON Format vorliegen und könnten nun damit weiterarbeiten.

Arduino Sketch – DIY Wetterstation, JSON DatenHerunterladen

ein kleines Oracle Java Programm

Hier nun ein kleines Oracle Java Programm, welches die Daten vom Wemos D1 Mini empfängt und in einem Diagramm anzeigt. Es muss nur die Zieladresse und das Intervall in 100 Millisekunden Schritten eingegeben werden.

Einfache Java Anwendung - DHT11 Sensordaten
Dieses Video auf YouTube ansehen.

Wenn du möchtest, kannst du dir die Anwendung nachfolgend herunterladen.

Oracle Java App – WetterstationHerunterladen

Wenn du das Projekt gerne fortführen möchtest, dann findest du hier das gesamte Eclipse Projekt.

Eclipse – Maven Projekt – WetterstationHerunterladen

Python3 Script

Natürlich kann man das auch mit Python lösen, hier also nun ein Script welches 5 Datenpakete sammelt und diese dann in einem Liniendiagramm anzeigt.

import http.client
import json
import time
import matplotlib.pyplot as plt

dataList = []
index = 0
while index < 5:
    conn = http.client.HTTPConnection("192.168.178.41")
    conn.request("GET","/")

    response = conn.getresponse()
    ##print("Status ",response.status, response.reason)
    jsonValue = response.read()

    dht11Value_dict = json.loads(jsonValue)

    dataList.append(dht11Value_dict)
    time.sleep(2)
    index += 1

tempClist = []
tempFlist = []
humidityList = []

for d in dataList:
    tempClist.append(d['temperatur']['celsius'])
    tempFlist.append(d['temperatur']['fahrenheit'])
    humidityList.append(d['humidity'])

#Plot a line graph
plt.plot(tempClist, label='Temp. Celsius')
plt.plot(tempFlist, label='Temp. Fahrenheit')
plt.plot(humidityList, label='rel. Luftfeuchtigkeit')
 
# Add labels and title
plt.title("DHT11 Sensordaten")
plt.xlabel("Zeit")
plt.ylabel("Wert")
 
plt.legend()
plt.show()
DHT11 Sensordaten in einem Liniendiagramm
DHT11 Sensordaten in einem Liniendiagramm

Da die Temperatur in Celsius den gleichen Wert wie die relative Luftfeuchtigkeit hatte, sind diese beiden Linien übereinander und man sieht nur die zuletzt gezeichnete Linie!

Ausbaustufe 5 – Daten in einer Webseite darstellen

Die Daten eines DHT11 Sensors habe ich bereits im Beitrag WEMOS D1 – WLAN Thermometer mit DHT11 Sensor ausführlich behandelt, jedoch möchte ich dieses hier zusätzlich aufzählen da dieses zum Thema gehört.

Daten als Text darstellen

Im einfachsten Fall werden die Daten als Text auf einer Webseite angezeigt.

void sendRespond(WiFiClient client) {
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("");
  client.print("<html>");
  client.print("<body>");
  client.print("<ul>");
  client.print("<li>Temperatur");
  client.print("<ul>");
  client.print("<li>Celsius: ");
  client.print(getTempCelsius());
  client.print("&deg;C</li>");
  client.print("<li>Fahrenheit: ");
  client.print(getTempFahrenheit());
  client.print("&deg;F</li>");
  client.print("</ul>");
  client.print("</li>");
  client.print("<li>relative Luftfeuchtigkeit: ");
  client.print(getHumidity());
  client.print("%</li>");
  client.print("</ul>");
  client.print("</body>");
  client.println("</html>");
}

Wenn man nun im Browser die IP-Adresse des Wemos D1 Mini eingibt erhält man folgende Ausgabe:

Ausgabe der Daten in Textform
Ausgabe der Daten in Textform

Um die Daten zu aktualisieren muss man nun jeweils im Browser die F5 Taste betätigen. 

automatische Aktualisierung nach x Sekunden

Man kann auch die Seite nach x Sekunden aktualisieren, dazu können wir entweder ein Redirect auf dieselbe Seite machen oder die Daten per Ajax nachladen. Im einfachsten Fall (dem Redirect) brauchen wir nur folgendes hinzufügen.

client.println("<head>");
String ipAddress = WiFi.localIP().toString();
client.println("<meta http-equiv=\"refresh\" content=\"10; URL=http://"+ ipAddress +"/\"/>");
client.println("</head>");

In dem META Tag wird definiert, dass ein redirect auf die IP-Adresse des Wemos D1 Mini nach 10 sek. Durchgeführt wird.

Arduino Sketch – DIY Wetterstation, Daten auf der Webseite (Text)Herunterladen

Ausbaustufe 6 – Daten in einem Diagramm darstellen

Wie man Daten von einem DHT11 Sensor in einer kleinen Webseite anzeigt, habe ich bereits im Beitrag WEMOS D1 – WLAN Thermometer mit DHT11 Sensor ausführlich behandelt. In diesem Abschnitt möchte ich jedoch trotzdem dieses behandeln.

void sendRespond(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("<head>"); 
  client.println("<script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>"); 
  client.println("<script type='text/javascript' src='http://progs.draeger-it.blog/wemosd1/dht11/gauges.js'></script>"); 
  client.println("<link rel='stylesheet' href='http://progs.draeger-it.blog/wemosd1/dht11/styles.css'/>");   
  String ipAddress = WiFi.localIP().toString();
  client.println("<meta http-equiv=\"refresh\" content=\"10; URL=http://"+ ipAddress +"/\"/>");
  client.println("<title>DIY - Wetterstation - DHT11 Sensordaten</title>");
  client.println("</head>"); 
  client.println("<body>"); 
  client.println("<div id='tempChart' class='chartContainer'></div>"); 
  client.println("<div id='pressChart' class='chartContainer'></div>"); 
  client.println("<script>"); 
  client.println("google.charts.load('current', {'packages':['gauge']});"); 
  client.println("google.charts.setOnLoadCallback(drawCharts);"); 
  client.println("function drawCharts() {"); 
  client.print("drawTempChart(");
  client.print(getTempCelsius()); 
  client.print(");");
  client.print("drawPressChart(");
  client.print(getHumidity()); 
  client.print(");");
  client.println("}"); 
  client.println("</script>"); 
  client.println("</body>"); 
  client.println("</html>"); 
}

Ich verwende hier zusätzlich 2 Resourcen welche auf „meinem“ Server unter „http://progrs.draeger-it.blog/wemosd1/dht11“ liegen.

Wenn man nun die IP-Adresse des Wemos D1 Mini in den Browser eingibt, erhält man folgende Ausgabe.

DHT11 Sensordaten auf Google Gauges
DHT11 Sensordaten auf Google Gauges

Die Seite wird nach 10 Sekunden automatisch aktualisiert.

Arduino Sketch – DIY Wetterstation, Daten auf der Webseite (Google Gauges)Herunterladen

Liniendiagramm

Möchte man die Daten in einem Verlauf betrachten, so sollten diese Daten in einem Liniendiagramm dargestellt werden. Für dieses Liniendiagramm verwende ich die ebenfalls kostenfreie Bibliothek von Google, welche du unter https://developers.google.com/chart/interactive/docs/gallery/linechart findest.

Wir wollen zunächst die Temperatur in Celsius sowie die relative Luftfeuchtigkeit anzeigen. (Ich lasse in diesem Beispiel die Temperatur in Fahrenheit mal außen vor.) 
Diese Sensordaten müssen wir zwischenspeichern, ich nutze dazu ein mehrdimensionales Array.

float chartData[255][2] = {};

Beginnen wollen wir jedoch zunächst mit einem leeren Array. Zusätzlich benötigen wir jedoch noch eine Variable, wo wir die Einträge hochzählen wollen. 

int counter = -1;

Da Arrays mit dem Index 0 beginnen, beginnt unser Zähler bei -1.

In der Methode zum Schreiben der HTML Seite, zählen wir zunächst unsere Variable „counter“ um eins hoch. Danach prüfen wir, ober der Wert der Variable in dem maximalen Gültigkeitsbereich des Arrays liegt. Wenn dieser erreicht wurde, beginnen wir wieder bei 0.

Danach wird die Seite aufgebaut. 

void sendRespond(WiFiClient client) {
 counter++;
 if(counter > (MAX_DATA-1)){
   counter = 0;
 }
  
 chartData[counter][0] = getTempCelsius();
 chartData[counter][1] = getHumidity();
  
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("");
  client.println("<!DOCTYPE HTML>");
  client.println("<html>"); 
  client.println("<head>"); 
  client.println("<script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>"); 
  client.println("<script type='text/javascript' src='http://progs.draeger-it.blog/wemosd1/dht11/linechart.js'></script>"); 
  client.println("<link rel='stylesheet' href='http://progs.draeger-it.blog/wemosd1/dht11/styles.css'/>");   
  String ipAddress = WiFi.localIP().toString();
  client.println("<meta http-equiv=\"refresh\" content=\"1; URL=http://"+ ipAddress +"/\"/>");
  client.println("<title>DIY - Wetterstation - DHT11 Sensordaten</title>");
  client.println("</head>"); 
  client.println("<body>"); 
  client.println("<div id='chart' class='chartContainer' style='width: 900px; height: 500px'></div>"); 
  client.println("<script>"); 
  client.println("google.charts.load('current', {'packages':['line']});"); 
  client.println("google.charts.setOnLoadCallback(drawCharts);"); 
  client.println("function drawCharts() {"); 

  client.println("var data = new google.visualization.DataTable();");
  client.println("data.addColumn('number', 'Zaehler');");
  client.println("data.addColumn('number', 'Temperatur in Celsius');");
  client.println("data.addColumn('number', 'rel. Luftfeuchtigkeit');");
  
  client.println(" data.addRows([");
  for(int i=0;i<=counter;i++){
    client.print("["); 
    //client.print("'"); 
    client.print(i+1); 
    //client.print("'"); 
    client.print(","); 
    client.print(chartData[i][0]); 
    client.print(","); 
    client.print(chartData[i][1]); 
    client.print("]"); 
    if(i != counter){
      client.print(",");
    }
  }
  client.println("]);");
  
  client.println("drawLineChart(data);");
  client.println("}"); 
  client.println("</script>"); 
  client.println("</body>"); 
  client.println("</html>"); 
}

Wie bereits erwähnt verwenden wir die Google Bibliothek zum Zeichnen des Liniendiagramms, diese Bibliothek ist eine JavaScript Bibliothek und wird mit den Daten aus unserem Array befüllt.
Dieses JavaScript Objekt übergeben wird nun unserer JavaScript Funktion auf dem Server.

Arduino Sketch – DIY Wetterstation, Daten auf der Webseite (Google LineChart)Herunterladen
Daten vom DHT11 Sensor in einem Google LineChart
Dieses Video auf YouTube ansehen.
eine Tabelle mit Daten implementieren

Die Daten werden im Liniendiagramm angezeigt, jedoch wäre es noch besser, wenn die Daten zusätzlich in einer Tabelle angezeigt würden.
Hier können wir uns zusätzlich in der Schleife unsere Tabelle aufbauen und später positionieren.

 String tableData = "";

 for(int i=0;i<=counter;i++){
    client.print("["); 
    //client.print("'"); 
    client.print(i+1); 
    //client.print("'"); 
    client.print(","); 
    client.print(chartData[i][0]); 
    client.print(","); 
    client.print(chartData[i][1]); 
    client.print("]"); 
    if(i != counter){
      client.print(",");
    }

    tableData +="<tr>";
    tableData +="<td>";
    tableData +=String(i);
    tableData +="</td>";
    tableData +="<td>";
    tableData +=String(tempC);
    tableData +="&deg;C</td>";
    tableData +="<td>";
    tableData +=String(humidity);
    tableData +="%</td>";
    tableData +="</tr>";
    
  }

...

client.println("<table border='1' style='float:left;margin-left:25px;'>"); 
client.println("<thead>"); 
client.println("<tr>"); 
client.println("<th>Zaehler</th>"); 
client.println("<th>Temperatur</th>"); 
client.println("<th>rel. Luftfeuchtigkeit</th>"); 
client.println("</tr>"); 
client.println("</thead>"); 
client.println("<tbody>"); 
client.println(tableData);  
client.println("</tbody>"); 
client.println("</table>");

Es wird nun zusätzlich eine Tabelle neben dem Liniendiagramm aufgebaut.

DHT11 Sensordaten im Google LineChart inkl. Tabelle
DHT11 Sensordaten im Google LineChart inkl. Tabelle
Arduino Sketch – DIY Wetterstation, Daten auf der Webseite (Google LineChart & Tabelle)Herunterladen

7 thoughts on “ESP Weekendprojekt #1: DIY Wi-Fi Wetterstation”

  1. martin sagt:
    20. März 2020 um 10:43 Uhr

    Der 9v Block ist ungeeignet, zu schnell leer. 3x AA in selbstgedrucktem Batteriehalter..‘

    Antworten
    1. Stefan Draeger sagt:
      20. März 2020 um 10:48 Uhr

      Hi,

      da gebe ich dir recht. Jedoch ist die Dose etwas zu klein geraten so das ich darauf nicht zurück greifen konnte. Wobei man aber auch bei 3x AA Batterien nicht gerade von einer langen Lebensdauer reden kann.
      Hast du damit gute Erfahrungen gemacht? Welche Batterien (Marke) verwendest du?

      Gruß,

      Stefan

      Antworten
  2. Steve sagt:
    19. Juli 2020 um 13:55 Uhr

    Eventuell hilft es ja einen deepsleep zu integrieren, sowie das ganze nur alle 60 Minuten als json request online zu lassen.. Eventuelle Lösung? Könntet ihr das realisieren? Was sagt ihr dazu?
    Eventuell auch statt AA oder Block Batterie eine 18650er verwenden?

    Antworten
  3. Christian sagt:
    10. Januar 2021 um 23:43 Uhr

    Tolle Sache, wenn man dazu ein oder 2 kleine Solarmodule 5V 1W, mit 3,7 LiPo (1000mAh) und Miniladeregler TP4056 verbaut – in Kombination mit dem Tiefschlaf — hält ewig !

    Meine Wetterstation sendet im 24-minütigem Takt : Temperatur, Luftfeuchte und Luftdruck als Datenpaket an eine Webseite und geht danach sofort in den Tiefschlaf. Läuft seit mehreren Monaten ununterbrochen durch.

    Die Status-LED vom TP4056 habe ich sichtbar angebracht und sehe, wann mein Akku geladen, bzw voll ist.

    Antworten
  4. Pingback: ESP8266 DIY IoT Wetterstation, Webseite mit Sensordaten - Teil 2 - Technik Blog
  5. Matthias Linker sagt:
    9. Juli 2024 um 10:42 Uhr

    Kleine Frage, ist es Möglich eine zweite Wetterstation zu bauen und diese beiden dann zusammengefasst auf einer Seite angezeigt zu bekommen um einmal Innen und einmal Außentemperatur und Feuchtigkeit angezeigt zu bekommen?

    Antworten
    1. Stefan Draeger sagt:
      11. Juli 2024 um 07:42 Uhr

      Hi, ja das ist ohne weiteres möglich, du musst quasi die Daten an den einen Mikrocontroller übertragen und dort dann auf der Seite anzeigen. Ich werde das mal aufgreifen und beschreiben, hört sich gut an.

      Gruß, Stefan Draeger

      Antworten

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen

Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}