
Ziele des Projekts
Die Messdaten sollen auf einem LCD und im nächsten Schritt zusätzlich auf einer Webseite dargestellt werden.
Die Programme funktioniert nur mit einem ESP32, es wird die properitäre, nicht quelloffene Bibliothek von Bosch verwendet.
Die Hardware
Der Bosch Sensor BME680 misst Temperatur, Luftfeuchtigkeit und den Luftdruck. Außerdem enthält er einen MOX (Metalloxid)-Sensor. Das beheizte Metalloxid ändert seinen Widerstand je nach Konzentration der flüchtigen organischen Verbindungen (VOC = Volatile Organic Compounds) in der Luft.
Viele Materialien in Innenräumen setzen Gase frei:
- Reinigungs- und Pflegemittel
- Möbel, Einrichtungsgegenstände
- Teppiche, Tapeten
- Baumaterialien (Farben)
- elektronische Geräte (Computer, Drucker)
- Heizgeräte (Herde, Öfen)
- menschliche Atemluft, Schweiß
Die Luftqualität wird zunächst als Widerstand in Ohm gemessen. Je höher die Konzentration von VOC, desto geringer ist der Widerstandswert.
Ein interner Algorithmus der proprietären Bosch-Software (BSEC) wandelt diesen Rohwert in einen Wert für die Luftqualität (IAQ = Index for Air Quality) um.
Die Tabelle zeigt den IAQ und die Bewertung der Luftqualität:

Das Umweltbundesamt bewertet den CO2 Gehalt in der Raumluft in verschiedenen Stufen:
Luftqualität in Innenräumen
| Raumluftkategorie IDA (indoor Air) | Beschreibung | Konzentration CO2 in ppm |
|---|---|---|
| IDA 1 | Hohe Raumluftqualität | ≤ 800 |
| IDA 2 | Mittlere Raumluftqualität | > 800 — 1000 |
| IDA 3 | Mäßige Raumluftqualität | > 1000 — 1400 |
| IDA 4 | Niedrige Raumluftqualität | > 1400 |
Quelle: https://www.umweltbundesamt.de/sites/default/files/medien/pdfs/kohlendioxid_2008.pdf
Darstellung der Messwerte
alle Messwerte zu verschiedenen Zeitpunkten im gut durchlüftetem Raum
Auf dem LCD

Im Seriellen Monitor

Auf einer Webseite

Natürlich kommt die Genauigkeit dieser Messwerte nicht an die Präzision professioneller Messgeräte heran. Sie können aber zuverlässige Hinweise auf die Qualität der Raumluft geben. Die Daten für Temperatur, Luftfeuchtigkeit und Luftdruck stehen kurz nach der Aktivierung des Sensors zur Verfügung. Der MOX-Sensor benötigt bis zu 30 Minuten, um erste Messdaten anzuzeigen. Stabilität und Zuverlässigkeit der Messdaten sind erst nach mehreren Tagen gewährleistet.
Der Wert für die Genauigkeit IAQ muss 3 erreichen.
Benötigte Bauteile
- BME680
- 4‑zeiliges LCD mit I²C-Schnittstelle
- Leitungsdrähte
Board installieren
Installiere mit dem Boardverwalter das passende Board:
Hardware anschließen
BME680 (Breakout)

rot -> VCC
schwarz -> GND
gelb -> SCL: 22
grün -> SDA: 21
Die Hex-Adresse ist 0x77 (BME68X_I2C_ADDR_HIGH).
Ein Verbindung von SDO zu GND ändert die Adresse auf 0x76 (BME68X_I2C_ADDR_LOW).
Quelle: https://joy-it.net/files/files/Produkte/SEN-BME680/SEN-BME680_Anleitung_2024-04–11.pdf
BME680 (Grove-Anschluss)

schwarz -> GND
rot -> VCC
gelb -> SDA: 21
weiß -> SCL: 22
Der BME680 mit Grove-Anschluss hat die Adresse 0x76 (BME68X_I2C_ADDR_LOW).
LCD

VCC -> 5 V
GND -> GND
SDA -> 21
SCL -> 22
Benötigte Bibliotheken

Die Bibliothek BSEC ist eine proprietäre Bibliothek, der Quelltext steht nicht zur Verfügung.
Der Compiler zeigt eine entsprechende Meldung:
Bibliothek BSEC Software Library wurde als vorkompiliert angegeben:
Außerdem steht sie nur für die Architekturen SAMD (UNO R4/UNO R4 WiFi ) und ESP (ESP32 oder ESP8266) zur Verfügung.

Funktionen der Bibliothek BSEC
| Schlüsselwort | Aktion | Ausgabe |
|---|---|---|
| runInStatus() | Status des Sensors feststellen | 0 = noch nicht bereit, 1 = bereit |
| iaqAccuracy() | Genauigkeit des IAQ-Wertes | 0 — 3 |
| temperature() | Temperatur messen | Messbereich: ‑40 — 85°C |
| humidity() | Luftfeuchtigkeit messen | 0 — 100% |
| pressure() | Luftdruck messen | 300 – 1100 hPa |
| gasResistance() | Widerstandswert in kOhm des MOX-Sensors | Je niedriger der Wert, desto höher ist die Konzentration der VOCs |
| breathVocEquivalent() | VOC-Konzentration auf Basis des statischen IAQs schätzen | Angabe in ppm (parts per million) 0,5 — 15 |
| iaq() | Luftqualität berechnen | 0 — 500 |
| staticIaq() | Statische Luftqualität berechnen | 0 ‑500 |
| co2Equivalent() | CO2 auf Basis des statischen IAQs schätzen | Angabe in ppm (parts per million) |
Der Wert für staticIaq ist für stationäre Geräte optimiert. Er berechnet auf der Basis der bisherigen Daten den Messwert. iaq() ist für mobile Anwendungen gedacht.
Das Programm für die Darstellung der Messwerte auf dem LCD
Bibliotheken einbinden und Variable definieren
1 2 3 4 5 6 7 8 | #include “bsec.h” #include “LCDIC2.h” // 4‑zeiliges LCD LCDIC2 lcd(0x27, 20, 4); // Objekt (iaqSensor) der Klasse Bsec definieren Bsec iaqSensor; |
Der setup-Teil
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | void setup() { Serial.begin(9600); // auf Serielle Verbindung warten while (!Serial); delay(1000); // LCD starten lcd.begin(); // Cursor “verstecken” lcd.setCursor(false); // Hex-Adresse des BME680 // BME68X_I2C_ADDR_HIGH = 0x77 (Standard) // BME68X_I2C_ADDR_LOW = 0x76 (Verbindung SDO zu GND) iaqSensor.begin(BME68X_I2C_ADDR_HIGH, Wire); // Array der verfügbaren Sensoren bsec_virtual_sensor_t sensorList[13] = { BSEC_OUTPUT_IAQ, BSEC_OUTPUT_STATIC_IAQ, BSEC_OUTPUT_CO2_EQUIVALENT, BSEC_OUTPUT_BREATH_VOC_EQUIVALENT, BSEC_OUTPUT_RAW_TEMPERATURE, BSEC_OUTPUT_RAW_PRESSURE, BSEC_OUTPUT_RAW_HUMIDITY, BSEC_OUTPUT_RAW_GAS, BSEC_OUTPUT_STABILIZATION_STATUS, BSEC_OUTPUT_RUN_IN_STATUS, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY, BSEC_OUTPUT_GAS_PERCENTAGE }; // BSEC_SAMPLE_RATE_ULP: Ultra Low Powermode -> Messung alle 5 Minuten // BSEC_SAMPLE_RATE_LP: Low Powermode -> Messung alle 3 Sekunden iaqSensor.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP); } |
Der loop-Teil
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | void loop() { // wenn der Sensor arbeitet … if (iaqSensor.run()) { // Messwerte ermitteln, in Strings umwandeln, . durch , ersetzen String Temperatur = String(iaqSensor.temperature); Temperatur.replace(“.”, “,”); String Luftfeuchtigkeit = String(iaqSensor.humidity); Luftfeuchtigkeit.replace(“.”, “,”); String Luftdruck = String(iaqSensor.pressure / 100); Luftdruck.replace(“.”, “,”); String IAQ = String(iaqSensor.iaq); IAQ.replace(“.”, “,”); String StatischerIAQ = String(iaqSensor.staticIaq); StatischerIAQ.replace(“.”, “,”); String CO2 = String(iaqSensor.co2Equivalent); CO2.replace(“.”, “,”); String VOC = String(iaqSensor.breathVocEquivalent); VOC.replace(“.”, “,”); String GasInProzent = String(iaqSensor.gasPercentage); GasInProzent.replace(“.”, “,”); String WiderstandMOXSensor = String(iaqSensor.gasResistance / 1000); WiderstandMOXSensor.replace(“.”, “,”); // Ausgabe Serieller Monitor Serial.print(“IP-Adresse: ”); Serial.println(WiFi.localIP()); Serial.println(“—————————–”); Serial.println(“Statusmeldungen:”); Serial.println(“—————————–”); Serial.println(“Sensor bereit (0–1): ” + String(int(iaqSensor.runInStatus))); Serial.println(“Genauigkeit IAQ (0–3): ” + String(int(iaqSensor.iaqAccuracy))); Serial.println(“—————————–”); Serial.println(“Messwerte:”); Serial.println(“—————————–”); Serial.println(“Temperatur: ” + Temperatur + ” °C”); Serial.println(“Feuchtigkeit: ” + Luftfeuchtigkeit + ” %”); Serial.println(“Luftdruck: ” + Luftdruck + ” hPa”); Serial.println(“IAQ: ” + IAQ); Serial.println(“Statischer IAQ: ” + StatischerIAQ); Serial.println(“Schätzung CO2: ” + CO2 + ” ppm”); Serial.println(“Gas (0–100): ” + GasInProzent + ” %”); Serial.println(“Widerstandswert MOX-Sensor: ” + WiderstandMOXSensor + ” kOhm”); Serial.println(“VOC: ” + VOC); Serial.println(“—————————–”); // Ausgabe LCD lcd.setCursor(0, 0); lcd.print(“Temperatur: ” + Temperatur + “\337C”); lcd.setCursor(0, 1); lcd.print(“Feuchtigkeit: ” + Luftfeuchtigkeit + “%”); lcd.setCursor(0, 2); lcd.print(“IAQ: ” + IAQ); lcd.setCursor(0, 3); lcd.print(“CO2: ” + CO2 + ” ppm”); } } |
Das Programm mit der Darstellung der Messwerte auf einer Webseite
Bibliotheken einbinden und Variable definieren
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #include “bsec.h” #include “WiFi.h” #include “WebServer.h” #include “time.h” // Objekt (iaqSensor) der Klasse Bsec definieren Bsec iaqSensor; char Router[] = “Router_SSID”; char Passwort[] = “xxxxxxxx”; // ip und gateway müssen an das lokale Netz angepasst werden IPAddress ip(192, 168, 1, 100); IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); /* öffentliche DNS-Server ———————————————– OpenDNS 208, 67, 222, 222 (USA) Google 8, 8, 8, 8 (USA) Cloudfare 1, 1, 1, 1 (USA) DNSWWatch 84, 200, 69, 80 (Deutschland) Quad9 9, 9, 9, 9 (Schweiz) Neustar UltraDNS 56, 154, 70, 3 (USA, gefiltert) Deutsche Telekom 217, 5,100, 185 ———————————————— oder die im Router eingetragene IP im Beispiel: 192, 168, 1, 20 */ IPAddress primaryDNS(192, 168, 1, 20); IPAddress secondaryDNS(9, 9, 9, 9); // statischeIP = false -> IP-Adresse über DHCP vergeben // statischeIP = true -> statische IP festlegen bool statischeIP = true; // NTP-Server aus dem Pool #define Zeitserver “de.pool.ntp.org” /* Liste der Zeitzonen https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv Zeitzone CET = Central European Time ‑1 -> 1 Stunde zurück CEST = Central European Summer Time von M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr */ #define Zeitzone “CET-1CEST,M3.5.0/02,M10.5.0/03” // time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr time_t aktuelleZeit; /* Struktur tm tm_hour -> Stunde: 0 bis 23 tm_min -> Minuten: 0 bis 59 tm_sec -> Sekunden 0 bis 59 tm_mday -> Tag 1 bis 31 tm_wday -> Wochentag (0 = Sonntag, 6 = Samstag) tm_mon -> Monat: 0 (Januar) bis 11 (Dezember) tm_year -> Jahre seit 1900 tm_yday -> vergangene Tage seit 1. Januar des Jahres tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time) */ tm Zeit; WebServer server(80); // benötigte Strings String Nachricht; String Temperatur; String Luftfeuchtigkeit; String Luftdruck; String CO2; String IAQ; String StatischerIAQ; |
Der setup-Teil

Beim Start des Programms zeigen die Meldungen ob Datum und Zeit korrekt sind. Wenn in 90 Sekunden keine Verbindung zu einem Zeitserver hergestellt werden konnte, wird das Programm beendet. Nach einem erneuten Hochladen kommt zumeist die Verbindung schnell zustande.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | void setup() { WiFi.mode(WIFI_STA); // Zeitzone: Parameter für die zu ermittelnde Zeit configTzTime(Zeitzone, Zeitserver); // localtime_r -> Zeit in die lokale Zeitzone setzen localtime_r(&aktuelleZeit, &Zeit); Serial.begin(9600); // auf Serielle Verbindung warten while (!Serial); delay(1000); // WiFi starten WiFi.begin(Router, Passwort); // statische IP vergeben if (statischeIP) { WiFi.config(ip, gateway, subnet, primaryDNS, secondaryDNS); Serial.print(“Verbunden mit ”); Serial.println(Router); // IP anzeigen Serial.print(“Statische IP: ”); } // IP über DHCP ermitteln else { while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print(“.”); } Serial.println(); Serial.print(“Verbunden mit ”); Serial.println(Router); Serial.print(“IP über DHCP: ”); } // IP anzeigen Serial.println(WiFi.localIP()); // beim Start entspricht das Datum der Unixtime: 1.1.1970 // Datum/Kalender sollen erst angezeigt werden, wenn das Datum korrekt ist String Jahr = String(Zeit.tm_year + 1900); int Zaehler = 0; // String Jahr nach “1970” durchsuchen int Suche = Jahr.indexOf(“1970”); Serial.println(“————————-”); Serial.println(“Datum und Zeit holen (maximal 90 Sekunden)…”); // solange die Suche nicht erfolgreich ist while (Suche != -1) { // aktuelle Zeit holen time(&aktuelleZeit); // localtime_r -> Zeit in die lokale Zeitzone setzen localtime_r(&aktuelleZeit, &Zeit); Jahr = String(Zeit.tm_year + 1900); // String Jahr nach “1970” durchsuchen Suche = Jahr.indexOf(“1970”); // Zeit in Stunden, Minuten und Sekunden // Stunden = int(Zeit.tm_hour), Minuten = int(Zeit.tm_min), Sekunden = int(Zeit.tm_sec); delay(1000); Zaehler ++; if (Zaehler >= 90) { Serial.println(); Serial.println(“Datum und Zeit konnte innerhalb von ” + String(Zaehler) + ” Sekunden nicht geholt werden”); Serial.println(“Programm wird beendet”); // Programm beenden while(1); } Serial.print(“.”); } Serial.println(); // Datum/Zeit erfolgreich synchronisiert if (Suche == -1) { Serial.println(“————————-”); Serial.println(“Datum/Zeit erfolgreich synchronisiert …”); if (Zeit.tm_mday < 10) Serial.print(“0”); Serial.print(Zeit.tm_mday); Serial.print(“.”); // Monat: führende 0 ergänzen if (Zeit.tm_mon < 9) Serial.print(“0”); // Zählung beginnt mit 0 -> +1 Serial.print(Zeit.tm_mon + 1); Serial.print(“.”); // Anzahl Jahre seit 1900 Serial.println(Zeit.tm_year + 1900); if (Zeit.tm_hour < 10) Serial.print(“0”); Serial.print(Zeit.tm_hour); Serial.print(“:”); if (Zeit.tm_min < 10) Serial.print(“0”); Serial.println(Zeit.tm_min); Serial.println(“————————-”); if (Zeit.tm_hour < 10) { Serial.print(“0”); } Serial.print(Zeit.tm_hour); Serial.print(“:”); if (Zeit.tm_min < 10) { Serial.print(“0”); } Serial.print(Zeit.tm_min); Serial.println(“ Uhr”); } server.begin(); server.on(“/”, SeiteBauen); // Hex-Adresse des BME680 // BME68X_I2C_ADDR_HIGH = 0x77 // BME68X_I2C_ADDR_LOW = 0x76 iaqSensor.begin(BME68X_I2C_ADDR_HIGH, Wire); // Array der verfügbaren Sensoren bsec_virtual_sensor_t sensorList[13] = { BSEC_OUTPUT_IAQ, BSEC_OUTPUT_STATIC_IAQ, BSEC_OUTPUT_CO2_EQUIVALENT, BSEC_OUTPUT_BREATH_VOC_EQUIVALENT, BSEC_OUTPUT_RAW_TEMPERATURE, BSEC_OUTPUT_RAW_PRESSURE, BSEC_OUTPUT_RAW_HUMIDITY, BSEC_OUTPUT_RAW_GAS, BSEC_OUTPUT_STABILIZATION_STATUS, BSEC_OUTPUT_RUN_IN_STATUS, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY, BSEC_OUTPUT_GAS_PERCENTAGE }; // BSEC_SAMPLE_RATE_ULP: Ultra Low Powermode -> Messung alle 5 Minuten // BSEC_SAMPLE_RATE_LP: Low Powermode -> Messung alle 3 Sekunden iaqSensor.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP); } |
Der loop-Teil
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | void loop() { // wenn der Sensor arbeitet … if (iaqSensor.run()) { // aktuelle Zeit holen time(&aktuelleZeit); // localtime_r -> Zeit in die lokale Zeitzone setzen localtime_r(&aktuelleZeit, &Zeit); // es kann bis zu 30 Sekunden dauern // bis die Zeit ermittelt wird // Name des Wochentages 0–6 switch (Zeit.tm_wday) { case 0: Serial.print(“Sonntag”); break; case 1: Serial.print(“Montag”); break; case 2: Serial.print(“Dienstag”); break; case 3: Serial.print(“Mittwoch”); break; case 4: Serial.print(“Donnerstag”); break; case 5: Serial.print(“Freitag”); break; case 6: Serial.print(“Samstag”); break; } Serial.print(“,”); if (Zeit.tm_mday < 10) Serial.print(“0”); Serial.print(Zeit.tm_mday); Serial.print(“.”); // Monat: führende 0 ergänzen if (Zeit.tm_mon < 10) Serial.print(“0”); // Zählung beginnt mit 0 -> + 1 Serial.print(Zeit.tm_mon + 1); Serial.print(“.”); // Anzahl Jahre seit 1900 Serial.print(Zeit.tm_year + 1900); Serial.print(“ ”); // Stunde: wenn Stunde 10 -> 0 davor setzen if (Zeit.tm_hour < 10) Serial.print(“0”); Serial.print(Zeit.tm_hour); Serial.print(“:”); // Minuten if (Zeit.tm_min < 10) Serial.print(“0”); Serial.println(Zeit.tm_min); server.handleClient(); // Messwerte ermitteln, in Strings umwandeln, . durch , ersetzen Temperatur = String(iaqSensor.temperature); Temperatur.replace(“.”, “,”); Luftfeuchtigkeit = String(iaqSensor.humidity); Luftfeuchtigkeit.replace(“.”, “,”); Luftdruck = String(iaqSensor.pressure / 100); Luftdruck.replace(“.”, “,”); IAQ = String(iaqSensor.iaq); IAQ.replace(“.”, “,”); StatischerIAQ = String(iaqSensor.staticIaq); StatischerIAQ.replace(“.”, “,”); CO2 = String(iaqSensor.co2Equivalent); CO2.replace(“.”, “,”); String VOC = String(iaqSensor.breathVocEquivalent); VOC.replace(“.”, “,”); String GasInProzent = String(iaqSensor.gasPercentage); GasInProzent.replace(“.”, “,”); String WiderstandMOXSensor = String(iaqSensor.gasResistance / 1000); WiderstandMOXSensor.replace(“.”, “,”); // Ausgabe Serieller Monitor Serial.print(“IP-Adresse: ”); Serial.println(WiFi.localIP()); Serial.println(“Statusmeldungen:”); Serial.println(“—————————–”); Serial.println(“Sensor bereit (0–1): ” + String(int(iaqSensor.runInStatus))); Serial.println(“Genauigkeit IAQ (0–3): ” + String(int(iaqSensor.iaqAccuracy))); Serial.println(“—————————–”); Serial.println(“Messwerte:”); Serial.println(“—————————–”); Serial.println(“Temperatur: ” + Temperatur + ” °C”); Serial.println(“Feuchtigkeit: ” + Luftfeuchtigkeit + ” %”); Serial.println(“Luftdruck: ” + Luftdruck + ” hPa”); Serial.println(“IAQ: ” + IAQ); Serial.println(“Statischer IAQ: ” + StatischerIAQ); Serial.println(“Schätzung CO2: ” + CO2 + ” ppm”); Serial.println(“Gas (0–100): ” + GasInProzent + ” %”); Serial.println(“Widerstandswert MOX-Sensor: ” + WiderstandMOXSensor + ” kOhm”); Serial.println(“VOC: ” + VOC); Serial.println(“—————————–”); } } |
HTML-Seite erstellen und senden
Wenn du eine dynamische IP-Adresse verwenden willst (statischeIP = false), kannst du mit diesem Programm die IP-Adresse ermitteln.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include “WiFi.h” #include “time.h” // WiFi-Daten char Router[] = “Router_SSID”; char Passwort[] = “xxxxxxxx”; void setup() { Serial.begin(9600); // auf Serielle Verbindung warten while (!Serial); delay(1000); // WiFi starten WiFi.mode(WIFI_STA); WiFi.begin(Router, Passwort); Serial.print(“Verbindung herstellen ”); while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print(“.”); } Serial.println(); // Aufbau der Verbindung erfolgreich if (WiFi.status() == 3) { Serial.print(“Verbunden mit ”); Serial.println(WiFi.SSID()); Serial.print(“IP über DHCP: ”); Serial.println(WiFi.localIP()); Serial.print(“Gateway: ”); Serial.println(WiFi.gatewayIP()); } else Serial.println(“Es konnte keine Verbindung aufgebaut werden”); } void loop() { // bleibt leer, Programm läuft nur einmal } |
Du musst in Zeile 75 die angezeigte dynamische IP-Adresse einsetzen.
Wenn du eine statische Adresse (statischeIP = false) verwenden willst, musst in Zeile 75 die IP-Adresse aus Zeile 14 übernehmen. Du musst , durch . ersetzen.
Für die Darstellung im Browser sind zwei Änderungen nötig:
| Zeile 57 ° -> ° Zeile 62 ä -> ä |
|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | void SeiteBauen() { // Seite zusammenbauen // Kopf der HTML-Seite: aktualisierung alle 60 Sekunden // kann angepasst werden Nachricht = “<head><meta http-equiv=\“refresh\” content=\“60\”></head>”; Nachricht += “<h1>Messwerte BME680</h1><hr>”; // Datum anzeigen // formatieren: Schrift 14pt, ohne Serifen, Zeilenhöhe Nachricht += “<div style = \“font-size:14pt; font-family:sans-serif; line-height:1.8em\”>”; Nachricht += “Letzte Aktualisierung: “; switch (Zeit.tm_wday) { case 0: Nachricht += “Sonntag”; break; case 1: Nachricht += “Montag”; break; case 2: Nachricht += “Dienstag”; break; case 3: Nachricht += “Mittwoch”; break; case 4: Nachricht += “Donnerstag”; break; case 5: Nachricht += “Freitag”; break; case 6: Nachricht +=“Samstag”; break; } Nachricht += “, “; // wenn der Tag < 10 if (Zeit.tm_mday < 10) Nachricht += “0”; Nachricht += String(Zeit.tm_mday) + “.”; // wen der Monat < 10, Zählung beginnt mit 0 if ((Zeit.tm_mon + 1) < 10) Nachricht += “0”; Nachricht += String(Zeit.tm_mon + 1) + “. “; // Zeit anzeigen // wenn die Stunde < 10 if (Zeit.tm_hour < 10) Nachricht += “0”; Nachricht += String(Zeit.tm_hour) + “:”; // wenn die Minute < 10 if (Zeit.tm_min < 10) Nachricht += “0”; Nachricht+= String(Zeit.tm_min) + ” Uhr<br><hr>”; Nachricht += “Temperatur: ” + Temperatur + ” °C<br>”; Nachricht += “Luftfeuchtigkeit: ” + Luftfeuchtigkeit + ” %<br>”; Nachricht += “Luftdruck: ” + Luftdruck + ” hPa<br>”; Nachricht += “IAQ: ” + IAQ + “<br>”; Nachricht += “Statischer IAQ: ” + StatischerIAQ + “<br>”; Nachricht += “Schätzung CO2: ” + CO2 + ” ppm<br>”; Nachricht += “Genauigkeit IAQ (0–3): ” + String(int(iaqSensor.iaqAccuracy)) + “</div>”; // Button aktualisieren Nachricht += “<hr><input style=\“font-size:16pt; font-weight:bold;”; Nachricht += “background-color:#55A96B;”; Nachricht += “display:block; cursor:pointer;\“type=\“button\””; // IP für den Button aktualisieren (location.href) // muss mit dem Wert für IPAdress übereinstimmen (. statt ‚) // oder der mit DHCP ermittelten IP-Adresse Nachricht += ” onClick =\“location.href=‘http://192.168.1.100’\” value=\“aktualisieren\”>”; Nachricht += “<hr>”; // Nachricht senden -> Seite anzeigen server.send(200, “text/html”, Nachricht); } |

Verwandte Anleitungen:
- BME280 ‑Messdaten anzeigen
- DHT — Messdaten und Zeit auf TFT anzeigen
- DHT11/DHT22 — Durchschnittstemperatur berechnen und auf einem OLED-Display anzeigen
- DHT11/DHT22 — Wetterdaten aufzeichnen
- DHT11/DHT22 — Wetterdaten mit Bluetooth-Modul übermitteln
- DHT11/DHT22 — Wetterstation LAN
- DHT11/DHT22 — Wetterstation Anzeige auf einem LCD
- DHT11/DHT22 — Wetterstation WiFi
- ESP — DHT Messdaten auf Waveshare 1,54 Zoll E‑Ink anzeigen
- ESP32-Wroom – BMP280/DHT Zeit und Messdaten auf TFT anzeigen
letzte Aktualisierung:





