Inhaltsverzeichnis
Wetterstation 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₂-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 + " °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₂-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();
}
}
Wettersttion mit Internetzeit (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₂-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 + " °C");
client.print(" <b>BMP:</b> " + AnzeigeTemperaturBMP + " °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₂-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: