Seit etwas über einem halben Jahr überwache ich jetzt mein Raumklime mit Naemon und Grafana. Die ganze Zeit habe ich die Daten über einen Raspberry Pi gesammelt, an dem ein DHT22 Sensor angeschlossen war.

Nun habe ich das umgebaut, auf einen NodeMCU mit ESP8266 Chip.

NodeMCU mit ESP8266 und DHT22 Sensor

Hier nochmal der Link, zum alten Beitrag.

Der ESP8266 kann, dank seines WLAN Chips, die Aufgabe des Raspberry Pi perfekt übernehmen. Dabei umgehe ich dann auch gleich das Problem, das die SD-Karte des Raspberry Pi früher oder später versagen wird.

Schaltplan

Der Schaltplan ist sehr einfach und auch hier finden sich wieder unzählige Beispiele im Internet. Das Gute ist, dass der DTH22 mit 3.3 Volt und 5 Volt Arbeiten kann.

Wichtig: Nicht den 4,7kΩ Pullup-Widerstand vergessen. Schaltplan für NodeMCU mit ESP8266 und DHT22 Sensor Ihr könnt diese Library verwenden.

Daten abfragen

Die Daten (Temperatur und Luftfeuchtigkeit) frage ich über einen Web Server auf dem ESP8266 ab. Anstelle von HTML gibt dieser die Daten als XML zurück. Die Abfrage macht wieder ein Naemon Plugin, welches in PHP geschrieben ist. Temperatur und Luftfeuchtigkeit als XML

Die magic number *0.8 wie beim Raspberry Pi benötige ich beim ESP8266 übrigends nicht mehr.

Naemon übernimmt jetzt wieder die Überwachung für mich, und schickt mir eine Benachrichtigung aufs Handy, sobald die Luftfeuchtigkeit zu hoch ist.

Darstellung in Grafana

An der Darstellung der Daten habe ich nichts verändert. Diese erfolgt weiterhin über Grafana. Temperatur und Luftfeuchtigkeit in Grafana

WLAN Stabilität

Obwohl der ESP8266 nur eine sehr kleine Antenne hat, habe ich überhaupt keine Probleme mit dem WLAN Signal. Ganz im Gegenteil. Ich habe einmal in den Graph geschaut, der die WLAN Verbindung vom Monitoring zum ESP8266 überwacht.

Es sieht so aus, als ob sich Round Trip Time und Packet Loss deutlich verringert haben, seitdem ich den ESP8266 nutze - im Vergleich zum Raspberry Pi mit einem WLAN USB Stick Raspberry Pi lan ping vs ESP8266

Ausbau

Da der ESP8266 so schön billig ist, habe ich mir mitlerweile für mehre Räume kleine "Messstationen" gebaut. Besonders praktisch, im Schlafzimmer nutze ich den FireTV zur Stromversorgung und benötige so kein eigenes Netzteil.

Luftfeuchtigkeit ESP8266 Statusengine 3

Programmcode

Den größten Teile habe ich einfach aus dem Beispiel ESPWiFiWebServer für das NodeMCU übernommen. Ich habe lediglich den WLAN Access Point deaktiviert, und die DHT Sachen mit eingebaut. Die Antwort habe ich von HTML auf XML umgebaut.

// DHT22 Struct
struct Humidity {
  int humidity;
  unsigned int humidityFrac;

  int temperature;
  unsigned int temperatureFrac;
};

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

const char* ssid = "EUER_WLAN_NAME_HIER";
const char* password = "EUER_SUPER_WLAN_PASSWORT_HIER";

#define DHTTYPE DHT22
const int DHTPin = 5;
DHT dht(DHTPin, DHTTYPE);

//Static IP
IPAddress ip(192, 168, 1, 6);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(10);

  dht.begin();

  // prepare GPIO2
  pinMode(2, OUTPUT);
  digitalWrite(2, 0);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  //Disable WiFi AP
  WiFi.mode(WIFI_STA);

  //Set Static IP
  WiFi.config(ip, gateway, subnet);

  //Connect to WiFi
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());

}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }

  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();

  Humidity humidity = getHumidityAndTemperature();

  Serial.print("Humidity: ");
  Serial.print(humidity.humidity);
  Serial.print(".");
  Serial.print(humidity.humidityFrac);
  Serial.println("%");

  Serial.print("Temperature: ");
  Serial.print(humidity.temperature);
  Serial.print(".");
  Serial.print(humidity.temperatureFrac);
  Serial.println("*C");

  // Prepare the response
  String response = "HTTP/1.1 200 OK\r\nContent-Type: application/xml\r\n\r\n<?xml version='1.0'?><document>";
    response += "<humidity>";
    response += humidity.humidity;
    response += ".";
    response += humidity.humidityFrac;
    response += "</humidity>";

    response += "<temperature>";
    response += humidity.temperature;
    response += ".";
    response += humidity.temperatureFrac;
    response += "</temperature>";

  response += "</document>\n";

  // Send the response to the client
  client.print(response);
  delay(1);
  Serial.println("Client disonnected");

  // The client will actually be disconnected
  // when the function returns and 'client' object is detroyed
}

Humidity getHumidityAndTemperature() {
  struct Humidity humidityStruct;
  float humidity =  dht.readHumidity();
  float temperature = dht.readTemperature();

  humidityStruct.humidity = int(humidity);
  humidityStruct.humidityFrac = (humidity - int(humidity)) * 100;

  humidityStruct.temperature = int(temperature);
  humidityStruct.temperatureFrac = (temperature - int(temperature)) * 100;

  return humidityStruct;
}