Wet­ter­sta­ti­on mit Wemos D1

Wet­ter­sta­ti­on mit RTC-Modul 3231

# include <ESP8266WebServer.h>
# include <Arduino.h>
# include <MHZ19.h>
# include <SoftwareSerial.h>
# include <RTClib.h>
# include <DHT.h>
# include <Adafruit_BMP280.h>

// Router: Name des Routers
// Passwort: WLAN-Passwort
char Router[] = "FRITZ!Box 7590 LB";
char Passwort[] = "xxxxxxxx";

// festeIP = false -> IP-Adresse über DHCP vergeben
// festeIP = true -> IP Gateway und Subnetz festlegen
bool festeIP = false;
// IP, Gateway und Subnetz festlegen
IPAddress ip(192, 168, 1, 200);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WiFiServer server(80);
WiFiClient client;

// Pin des DHT22
int SENSOR_DHT = D5;

// Sensortyp festlegen
// DHT22
# define SensorTyp DHT22

// Sensor DHT einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp);

// Name des RTC-Moduls (rtc)
RTC_DS3231 rtc;

// RX/TX Pins zuordnen
// TX MH-Z19C auf D6, RX-Pin MH_Z19C auf D7 (überkreuz)
#define RX D6
#define TX D7

// Name des Moduls MH-Z19
MHZ19 MHZCO2;

// Name des bmp-Sensors
Adafruit_BMP280 bmp;

// SoftwareSerial -> Name zuordnen
SoftwareSerial MHZSerial(RX, TX);
unsigned long VerstricheneZeit = 0;

void setup()
{
  Serial.begin(9600);
  delay(500);

  // WiFi starten
  WiFi.begin(Router, Passwort);
  if (festeIP) WiFi.config(ip, gateway, subnet);

  // verbinden
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  server.begin();

  // IP des Servers/des verbunden Computers anzeigen
  Serial.print("Server: ");
  Serial.println(WiFi.SSID());

  // IP des Arduinos anzeigen
  if (festeIP) Serial.print("Statische IP Adresse: ");
  else Serial.print("IP Adresse DHCP: ");
  Serial.println(WiFi.localIP());
  MHZSerial.begin(9600);
  MHZCO2.begin(MHZSerial);

  // automatische Kalibrierung ausschalten
  MHZCO2.autoCalibration(false);

  // RTC-Modul starten
  rtc.begin();

  // Datum/Zeit einmalig setzen, beim nächsten Starten auskommentieren
  // rtc.adjust(DateTime(2023, 4, 23, 8, 50, 30));

  // Sensor DHT starten
  dht.begin();

  // bmp starten
  bmp.begin();
}

void loop()
{
  VerstricheneZeit = millis();
  client = server.available();
  if (client)
  {
    String SchaltungLesen = "";
    while (client.connected())
    {
      if (client.available())
      {
        char Zeichen = client.read();
        if (Zeichen == '\n')
        {
          if (SchaltungLesen.length() == 0) {
            // HTTP-Anforderung senden
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            // Leerzeile zwingend erforderlich
            client.println();

            /*
              HTML-Seite aufbauen
              die folgenden Anweisungen müssen mit print oder println gesendet werden
              println "verschönert" den Quelltext
              " muss mit \" maskiert werden
            */
            client.println("<!doctype html>");
            client.println("<html>");
            client.println("<body>");

            // alle 60 Sekunden aktualisieren mit meta-Tag
            client.println("<meta http-equiv=\"refresh\" content=\"60\">");
            client.println("<h1> Temperatur, Luftfeuchtigkeit und CO&#8322;-Gehalt in der Luft messen</h1>");
            client.println("<hr />");
            client.print("<h2>Letzte Messung: ");
            DateTime aktuell = rtc.now();
            char Datum[] = "DD.MM.YYYY ";
            char Zeit[] = "hh:mm:ss Uhr";

            switch (aktuell.dayOfTheWeek())
            {
              case 0:
                client.print(F("Sonntag"));
                break;
              case 1:
                client.print(F("Montag"));
                break;
              case 2:
                client.print(F("Dienstag"));
                break;
              case 3:
                client.print(F("Mittwoch"));
                break;
              case 4:
                client.print(F("Donnerstag"));
                break;
              case 5:
                client.print(F("Freitag"));
                break;
              case 6:
                client.print(F("Samstag"));
                break;
            }
            client.print(", ");
            client.print(aktuell.toString(Datum));
            client.println(aktuell.toString(Zeit));
            client.println("</h2>");
            client.println("<hr />");

            // Daten lesen
            String AnzeigeTemperaturDHT = String(dht.readTemperature());
            AnzeigeTemperaturDHT.replace(".", ",");
            String AnzeigeLuftfeuchtigkeit = String(dht.readHumidity());
            AnzeigeLuftfeuchtigkeit.replace(".", ",");

            // CO2-Wert ermitteln
            int CO2 = MHZCO2.getCO2();

            /* 
              readPressure() Luftdruck messen und Messergebnis formatieren
              readPressure() liest in Pascal, ausgabe in hPa (Hekto-Pascal)
              Ergebnis durch 100 teilen
            */
            String Luftdruck = String(bmp.readPressure() / 100);
            Luftdruck.replace(".", ",");

            // Daten anzeigen
            client.print("<b>Temperatur:</b><blockquote>");
            client.println(AnzeigeTemperaturDHT + " &deg;C</blockquote>");
            client.println("<br>");
            client.print("<b>Luftfeuchtigkeit:</b><blockquote>");
            client.println(AnzeigeLuftfeuchtigkeit + " %</blockquote>");

            client.print("<b>Luftdruck:</b><blockquote>");
            client.println(Luftdruck + " hPa</blockquote>");
            client.println("<br>");

            client.print("<b>CO&#8322-Gehalt:</b><blockquote>");
            client.println(String(CO2) + " ppm</blockquote>");
            client.println("<form>");
            client.println(F("<hr />"));

            // Button formatieren
            client.print("<input style=\"font-size:16pt; font-weight:bold;");
            client.print("background-color:#55A96B;");
            client.print("display:block; cursor:pointer;\"type=\"button\"");
            client.println(" onClick=\"location.href='WiFi.localIP()'\" value=\"aktualisieren\">");
            client.println("</form>");
            client.println("<hr />");

            // IPs anzeigen
            client.print(F("<b>Eigene IP: "));
            client.print(client.remoteIP());
            client.print(F("</b>"));
            client.print(F("<br><b>IP Klient: "));
            client.print(WiFi.localIP());
            client.print(F("</b>"));
            client.println("</b>");
            client.println("</body>");
            client.print("</html>");
            // HTTP-Antwort endet mit neuer Zeile
            client.println();
            // Seite vollständig geladen -> loop verlassen
            break;
          }
          else
          {
            SchaltungLesen = "";
          }
        }
        // bei einem anderen Zeichen als return (\r)
        // -> Zeichen dem String SchaltungLesen hinzufügen
        else if (Zeichen != '\r')
        {
          SchaltungLesen += Zeichen;
        }
      }
    }
    client.stop();
  }
}

Wet­terst­ti­on mit Inter­net­zeit (NTP)

#include <ESP8266WebServer.h>
#include <MHZ19.h>
#include <SoftwareSerial.h>
#include <DHT.h>
#include <Adafruit_BMP280.h>
#include <WiFiUdp.h>
#include <NTP.h>

// Router: Name des Routers
// Passwort: WLAN-Passwort
char Router[] = "FRITZ!Box 7590 LB";
char Passwort[] = "xxxxxxxx";

WiFiUDP wifiUdp;
NTP ntp(wifiUdp);

// festeIP = false -> IP-Adresse über DHCP vergeben
// festeIP = true -> IP Gateway und Subnetz festlegen
bool festeIP = false;

// IP, Gateway und Subnetz festlegen
IPAddress ip(192, 168, 1, 200);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WiFiServer server(80);
WiFiClient client;

// Pin des DHT22
int SENSOR_DHT = D5;

// Sensortyp festlegen
// DHT22
#define SensorTyp DHT22

// Sensor DHT einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp);

// RX/TX Pins zuordnen
// TX MH-Z19C auf D6, RX-Pin MH_Z19C auf D7 (überkreuz)
#define RX D6
#define TX D7

// Name des Moduls MH-Z19
MHZ19 MHZCO2;

// Name des bmp-Sensors
Adafruit_BMP280 bmp;

// SoftwareSerial -> Name zuordnen
SoftwareSerial MHZSerial(RX, TX);

void setup() {
  Serial.begin(9600);
  delay(500);

  // WiFi starten
  WiFi.begin(Router, Passwort);
  if (festeIP) WiFi.config(ip, gateway, subnet);

  // verbinden
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  server.begin();

  // IP des Servers/des verbunden Computers anzeigen
  Serial.println("Verbunden: ");
  Serial.println("Server: ");
  Serial.println(WiFi.SSID());

  // IP des Arduinos anzeigen
  if (festeIP) Serial.print("Statische IP Adresse: ");
  else Serial.print("IP Adresse DHCP: ");
  Serial.println(WiFi.localIP());
  MHZSerial.begin(9600);
  MHZCO2.begin(MHZSerial);

  // automatische Kalibrierung ausschalten
  MHZCO2.autoCalibration(false);

  // Sensor DHT starten
  dht.begin();

  // bmp starten
  bmp.begin();

  // CEST: Beginn europäische Sommerzeit; letzter Sonntag im März 2 Uhr GMT + 2 Stunden
  ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120);

  // CET: Beginn Normalzeit letzter Sonntag im Oktober 3 Uhr GMT + 1 Stunde
  ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60);    // last sunday in october 3:00, timezone +60min (+1 GMT)

  // ntp starten
  ntp.begin();
}

void loop() 
{
  client = server.available();
  if (client) 
  {
    String SchaltungLesen = "";
    while (client.connected()) 
    {
      if (client.available()) 
      {
        char Zeichen = client.read();
        if (Zeichen == '\n') 
        {
          if (SchaltungLesen.length() == 0) 
          {
            // HTTP-Anforderung senden
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            // Leerzeile zwingend erforderlich
            client.println();

            /*
              HTML-Seite aufbauen
              die folgenden Anweisungen müssen mit print oder println gesendet werden
              println "verschönert" den Quelltext
              " muss mit \" maskiert werden
            */
            client.println("<!doctype html>");
            client.println("<html>");
            client.println("<body>");

            // alle 60 Sekunden aktualisieren mit meta-Tag
            client.println("<meta http-equiv=\"refresh\" content=\"60\">");
            client.println("<h1> Temperatur, Luftfeuchtigkeit und CO&#8322;-Gehalt in der Luft messen</h1>");
            client.println("<hr />");
            client.print("<h2>Letzte Messung: ");

            // Zeit-Server kontaktieren
            ntp.update();
            
            // Wochentag anzeigen
            switch (ntp.weekDay()) 
            {
              case 0:
                client.println("Sonntag ");
                break;
              case 1:
                client.println("Montag ");
                break;
              case 2:
                client.println("Dienstag ");
                break;
              case 3:
                client.println("Mittwoch ");
                break;
              case 4:
                client.println("Donnerstag ");
                break;
              case 5:
                client.print("Freitag ");
                break;
              case 6:
                client.print("Samstag ");
                break;
            }
            client.print(ntp.day());
            client.print(". ");

            // Moant anzeigen
            switch (ntp.month()) 
            {
              case 1:
                client.print("Januar ");
                break;
              case 2:
                client.print("Februar ");
                break;
              case 3:
                client.print("März ");
                break;
              case 4:
                client.print("April ");
                break;
              case 5:
                client.print("Mai ");
                break;
              case 6:
                client.print("Juni ");
                break;
              case 7:
                client.print("Juli ");
                break;
              case 8:
                client.print("August ");
                break;
              case 9:
                client.print("September ");
                break;
              case 10:
                client.print("Oktober ");
                break;
              case 11:
                client.print("November ");
                break;
              case 12:
                client.print("Dezember ");
                break;
            }
            client.print(ntp.year());
            client.print(" ");

            // führende 0 ergänzen
            if (ntp.hours() < 10) client.print("0");
            client.print(String(ntp.hours()) + ":");

            if (ntp.minutes() < 10) client.print("0");
            client.println(String(ntp.minutes()) + " Uhr");

            client.println("</h2>");
            client.println("<hr />");

            // Daten lesen DHT und . durch , ersetzetn
            String AnzeigeTemperaturDHT = PunktErsetzen(String(dht.readTemperature()));

            String AnzeigeLuftfeuchtigkeit = PunktErsetzen(String(dht.readHumidity()));

            // Daten lesen BMP und . durch , ersetzetn
            String AnzeigeTemperaturBMP = String(bmp.readTemperature());

            /* 
              readPressure() Luftdruck messen und Messergebnis formatieren
              readPressure() liest in Pascal, ausgabe in hPa (Hekto-Pascal)
              Ergebnis durch 100 teilen
            */

            // Luftdruck BMP280 lesen und . durch , ersetzetn
            String Luftdruck = PunktErsetzen(String(bmp.readPressure() / 100));

            // Temperatur DHT und BMP280 anzeigen
            client.print("<b>Temperatur:</b><blockquote>");
            client.print("<b>DHT:</b> " + AnzeigeTemperaturDHT + " &deg;C");
            client.print("    <b>BMP:</b> " + AnzeigeTemperaturBMP + " &deg;C</blockquote>");

            // DHT Luftfeuchtigkeit
            client.print("<b>Luftfeuchtigkeit:</b><blockquote>");
            client.println(AnzeigeLuftfeuchtigkeit + " %</blockquote>");

            client.print("<b>Luftdruck:</b><blockquote>");
            client.print(Luftdruck + " hPa</blockquote>");

            // CO2 messen und anzeigen
            int CO2 = MHZCO2.getCO2();

            // kurzes delay -> Messwert stabilisieren
            delay(500);
            client.print("<b>CO&#8322-Gehalt:</b><blockquote>");
            client.println(String(CO2) + " ppm</blockquote>");
            client.println("<form>");
            client.println(F("<hr />"));

            // Button formatieren
            client.print("<input style=\"font-size:16pt; font-weight:bold;");
            client.print("background-color:#55A96B;");
            client.print("display:block; cursor:pointer;\"type=\"button\"");
            client.println(" onClick=\"location.href='WiFi.localIP()'\" value=\"aktualisieren\">");
            client.println("</form>");
            client.println("<hr />");

            // IPs anzeigen
            client.print(F("<b>Eigene IP: "));
            client.print(client.remoteIP());
            client.print(F("</b>"));
            client.print(F("<br><b>IP Klient: "));
            client.print(WiFi.localIP());
            client.print(F("</b>"));
            client.println("</b>");
            client.println("</body>");
            client.print("</html>");

            // HTTP-Antwort endet mit neuer Zeile
            client.println();

            // Seite vollständig geladen -> loop verlassen
            break;
          } 
          else SchaltungLesen = "";
        }
        // bei einem anderen Zeichen als return (\r)
        // -> Zeichen dem String SchaltungLesen hinzufügen
        else if (Zeichen != '\r') SchaltungLesen += Zeichen;
      }
    }
    client.stop();
  }
}

String PunktErsetzen(String ErsatzString)
{
  ErsatzString.replace(".", ",");
  return ErsatzString;
}

Letzte Aktualisierung: 4. Jun 2023 @ 9:20