
Ziele des Projekts
- zwei Mikrocontroller unabhängig von einem bestehenden Router in einem eigenständigen WLAN-Netz betreiben
- mit beliebigen Temperatursensoren (hier DHT11/DHT22) an zwei verschiedenen Orten Temperatur und Luftfeuchtigkeit messen
- die ermittelten Messwerte in einem Webbrowser anzeigen

Benötigte Bauteile
- ESP32-Mikrocontroller oder ESP8266-Mikrocontroller in beliebiger Kombination
- DHT11/DHT22 Temperatursensoren
- Leitungsdrähte
Konfiguration der Mikrocontroller
Accesspoint-Modus (AP-Modus)
Beim AP-Modus bauen die ESPs ein vom heimischen Router unabhängiges eigenständiges Netz auf. Neben dem Namen des Routers und dem Passwort musst du dem ESP einige Daten mitteilen:
|
1 2 3 4 5 |
char Router[] = "ESPServer"; char Passwort[] = "espserver"; IPAddress ip(192, 168, 4, 1); IPAddress gateway(192, 168, 4, 1); IPAddress subnet(255, 255, 255, 0) |
Der Name des Routers und das Passwort sind frei wählbar, allerdings muss das Passwort mindestens 8 Zeichen haben.
ip legt die statische IP-Adresse fest.
gateway ist das Gerät – in diesem Fall der ESP selbst – das die Kommunikation der verbundenen Geräte (der Klienten) untereinander regelt.
subnet ist der Adressbereich der zugelassenen IP-Adressen. 255 bedeutet, dass dieser Bereich jeweils unveränderlich ist, 0 am Ende heißt, dass die IP-Adressen variabel sind. Da die erste und die letzte IP-Adresse aus organisatorischen Gründen nicht vergeben werden darf, bleiben 254 IP-Adressen (192.168.4.1 bis 192.168.4.254).
Die neuere Schreibweise ist übrigens in diesem Fall 192.168.4/24.
Beachte, dass die Zahlenblöcke der IP-Adressen durch Kommata getrennt werden müssen.
Alle IP-Adressen, die mit 192.168. beginnen, sind als privat festgelegt, sie dürfen im Internet nicht verwendet werden. Die nächste Ziffer (4) bezeichnet das Subnetz. Hier sind maximal 256 Subnetze (192.168.0 bis 192.168.255) möglich. Die letzte Ziffer (1) ist die konkrete IP-Adresse des Geräts.
ip und gateway müssen gleich sein!
Du darfst kein Subnetz verwenden, das der Router für DHCP verwendet.
Du kannst dir mit einem Werkzeug einen Überblick über die im privaten Netz vorhandenen Geräte verschaffen und anhand der angezeigten IP-Adressen das vom Router für DHCP verwendete Subnetz herausfinden.
- Windows:
Eingabeaufforderung (cmd) öffnen
arp -n - Linux:
Konsole öffnen
arp -n zeigt alle über Ethernet verbundenen Geräte
arp-scan –localnet zeigt alle über WiFi und Ethernet verbundenen Geräte
(arp-scan muss eventuell über die Paketverwaltung installiert werden)
Programm zum Aufbau des Netzes
|
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 |
#ifdef ESP8266 #include "ESP8266WiFi.h" #else #include "WiFi.h" #endif // Netzwerkname und Passwort des ESP char Router[] = "ESPServer"; char Passwort[] = "espserver"; // Server und Klient IPAddress ip(192, 168, 4, 1); IPAddress gateway(192, 168, 4, 1); IPAddress subnet(255, 255, 255, 0); void setup() { Serial.begin(9600); // auf serielle Verbindung warten while (!Serial); delay(1000); // ESP als Access-Point (AP) konfigurieren WiFi.softAPConfig(ip, gateway, subnet); // Access-Point starten WiFi.softAP(Router, Passwort); // SSID des Routers anzeigen Serial.println(); Serial.print("Verbunden mit "); Serial.println(WiFi.softAPSSID()); Serial.print("IP-Adresse: "); Serial.println(WiFi.softAPIP()); } void loop() { // bleibt leer, das Programm läuft nur einmal } |


Ein Smartphone sucht über das mobile Netz im Internet nach der IP-Adresse des ESPServers (192.168.4.1). Da kein DNS-Server erreichbar ist, kann die Seite nicht angezeigt werden. Verwende stattdessen
http://192.168.4.1
Aufbau des AP-Netzes
Als Klienten können alle WLAN-fähigen Geräte verwendet werden.

Das Schaubild zeigt den Aufbau des Netzes und die Kommunikation der Geräte untereinander. Ich habe einen ESP32-WROOM gewählt, du kannst aber auch eine beliebige Kombination von ESP32 oder ESP8266-Mikrocontrollern verwenden.
Der Mikrocontroller mit der IP 192.168.4.1 baut das WLAN-Netz auf und erhebt gleichzeitig auch Daten für Temperatur und Luftfeuchtigkeit. Der zweite Mikrocontroller (Host) misst ebenfalls Temperatur und Luftfeuchtigkeit. In regelmäßigen Abständen fragt der Server seine eigenen Daten und die des Hosts ab. Die Klienten zeigen die Daten auf der Webseite an.
Manuelle Konfiguration des Klienten
Den Klienten werden keine IP-Adressen automatisch zugeteilt. Daher muss die Konfiguration händisch erledigt werden.
Zunächst musst du das als „ESPServer“ angezeigte WLAN auswählen und anschließend die Konfiguration anpassen.
Wenn du mehrere Klienten verwenden willst, musst du jeweils eine andere IP-Adresse verwenden (z. B. 192.168.4.5). Die Adresse des Routers bleibt unverändert.
iOS
Android
Windows 10



ESP als Server und Klient
Ein ESP soll als Server die Daten des anderen ESP einsammeln und gleichzeitig als Klient ebenfalls Temperatur und Luftfeuchtigkeit messen.
Daher wird für die IP-Adresse und das Gateway die gleiche IP-Adresse verwendet.
|
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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
#ifdef ESP8266 #include "ESP8266WebServer.h" ESP8266WebServer Server(80); #else #include "WiFi.h" #include "WebServer.h" WebServer Server(80); #endif #include "DHT.h" // Pin des DHT-Sensors int SENSOR_DHT = 19; // Sensortyp festlegen // DHT22 oder DHT11 #define SensorTyp DHT22 DHT dht(SENSOR_DHT, SensorTyp); // Netzwerkname und Passwort des ESP char Router[] = "ESPServer"; char Passwort[] = "espserver"; // farbige Box mit CSS String Seitenkopf = "<head><style>" ".farbigeBox {" "background-color: ivory;" "color: black;" "width: 480px;" "padding: 20px;" "text-align: left;" "font-size: 40px;" "font-family: arial;" "}" "</style>" // refresh -> Seite automatisch aktualisieren "<meta http-equiv=\"refresh\" content=\"30\"></head>"; // Wartezeit für die sichere Übermittlung der Daten unsigned long Wartezeit = 5000; // enthält die Daten des 2. ESPs String Messung; // IP-Adresse des 2. ESP const char* host = "192.168.4.2"; // Konfiguration als Server und Host IPAddress ip(192, 168, 4, 1); IPAddress gateway(192, 168, 4, 1); IPAddress subnet(255, 255, 255, 0); void setup() { Serial.begin(9600); // auf serielle Verbindung warten while (!Serial); delay(1000); // ESP als Access-Point (AP) konfigurieren WiFi.softAPConfig(ip, gateway, subnet); // Access-Point starten WiFi.softAP(Router, Passwort); // SSID des Routers anzeigen Serial.println(); Serial.print("Verbunden mit "); Serial.println(WiFi.softAPSSID()); Serial.print("IP-Adresse: "); Serial.println(WiFi.softAPIP()); // Webserver starten // / -> Aufruf der URL, SeiteBauen -> Aufruf der Funktion Server.begin(); Server.on("/", SeiteBauen); dht.begin(); } void loop() { static unsigned long Startzeit = millis(); // auf Anfragen warten Server.handleClient(); // Messdaten einsammeln if ((millis() - Startzeit) > Wartezeit) { // Daten des 2. ESPs einsammeln DatenHolen(); Startzeit = millis(); } } void SeiteBauen() { // Seite "zusammenbauen" String Seite = ""; Seite += Seitenkopf; Seite += "<h1>Messdaten</h1>"; Seite += "<hr>"; /* Messung enthält die mit / getrennten Daten String Messung mit substring am / trennen Temperatur: von Position 0 bis zum / (indexOf) Luftfeuchtigkeit von /+1 bis zur Länge des Strings (length) */ String TemperaturKlient = Messung.substring(0, Messung.indexOf("/")); String LuftfeuchtigkeitKlient = Messung.substring(Messung.indexOf("/") + 1, Messung.length()); Seite += "<h2>Daten vom Klienten ...</h2>"; Seite += "<div class=\"farbigeBox\">"; Seite += "Temperatur: "; Seite += TemperaturKlient; Seite += "<br>"; Seite += "Luftfeuchtigkeit: "; Seite += LuftfeuchtigkeitKlient; Seite += "<br>"; Seite += "</div>"; // Messwerte des Servers ermitteln // . durch , ersetzen String TemperaturServer = String(dht.readTemperature()); TemperaturServer.replace(".", ","); String LuftfeuchtigkeitServer = String(dht.readHumidity()); LuftfeuchtigkeitServer.replace(".", ","); Seite += "<h2>Daten vom Server ...</h2>"; Seite += "<div class=\"farbigeBox\">"; Seite += "Temperatur: "; Seite += TemperaturServer + " °C"; Seite += "<br>"; Seite += "Luftfeuchtigkeit: "; Seite += LuftfeuchtigkeitServer + "%"; Seite += "</div>"; // Button aktualisieren Seite += "<hr><button style=\"font-size:16pt; font-weight:bold;"; Seite += "background-color:#55A96B;"; Seite += "display:block; cursor:pointer;\">"; Seite += "</button>"; // IP für den Button aktualisieren (location.href) // muss mit dem Wert für IPAdress übereinstimmen (. statt ,) Seite += " onClick=\"location.href='http://192.168.4.1'\" value=\"aktualisieren\">"; Seite += "<hr>"; // Seite anzeigen Server.send(200, "text/html", Seite); } void DatenHolen() { WiFiClient client; // wenn Klient erfolgreich auf Port 80 verbunden wurde // wenn nicht return -> neuer Versuch if (!client.connect(host, 80)) return; /* GET-Anfrage senden /Messung -> Adresse (URL) für die zu übermittelnden Werte wird von den Klienten festgelegt host -> IP-Adresse des 2. ESPs HTTP/1.1 -> Abfrageprotokoll \r\n -> return mit anschließender neuer Zeile */ client.print(String("GET ") + "/Messung" + " HTTP/1.1\r\n" + host + "\r\n"); unsigned long LetzteZeit = millis(); // Wartezeit while (!client.available() && ((millis() - LetzteZeit) < 3000)) { delay(1); } // der Klient ist verfügbar while (client.available()) { // den mit GET erhaltenen String bis zum return (\r) lesen String Daten = client.readStringUntil('\r'); // wenn Daten vorhanden sind // Messung enthält die vom 2. ESP übermittelten Daten if(Daten != "") { Messung = Daten; Serial.println(Daten); } } } |
Darstellung der GET-Anfrage im Seriellen Monitor

ESP als Host
|
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 |
#ifdef ESP8266 #include "ESP8266WebServer.h" ESP8266WebServer Server(80); #else #include "WiFi.h" #include "WebServer.h" WebServer Server(80); #endif #include "DHT.h" // Pin des DHT-Sensors int SENSOR_DHT = 19; #define SensorTyp DHT22 // Sensor DHT einen Namen zuweisen DHT dht(SENSOR_DHT, SensorTyp); // ESP als AP char Router[] = "ESPServer"; char Passwort[] = "espserver"; // IP des 2. ESPs IPAddress ip(192, 168, 4, 2); IPAddress gateway(192, 168, 4, 1); IPAddress subnet(255, 255, 255, 0); void setup() { // WiFi starten WiFi.config(ip, gateway, subnet); WiFi.begin(Router, Passwort); // Adresse (URL)festlegen (/Messung) // SeiteBauen -> zu übermittelnde Daten Server.on("/Messung", SeiteBauen); Server.begin(); Serial.begin(9600); // DHT starten dht.begin(); } void loop() { // auf Anfragen warten Server.handleClient(); } void SeiteBauen() { String Seite =""; // Messwerte ermitteln // . durch , ersetzen String Temperatur = String(dht.readTemperature()); Temperatur.replace(".", ","); String Luftfeuchtigkeit = String(dht.readHumidity()); Luftfeuchtigkeit.replace(".", ","); // Seite zusammenbauen // / Trennzeichen zwischen Temperatur und Luftfeuchtigkeit Seite = Temperatur + " °C"; Seite += Luftfeuchtigkeit + "%"; // Seite übermitteln Server.send(200, "text/html", Seite); } |
Quellen
- Grafik Tablet/Smartphone von Pixaline
- Grafik Router/Laptop: openclipart.org
- Grafik ESP32 von fritzing
- Espressif WiFi-API
Letzte Aktualisierung: