{"id":2006,"date":"2026-03-12T19:42:59","date_gmt":"2026-03-12T18:42:59","guid":{"rendered":"https:\/\/g7itchme.wordpress.com\/?p=2006"},"modified":"2026-03-12T19:42:59","modified_gmt":"2026-03-12T18:42:59","slug":"der-vollstandige-guide-wlan-signal-monitor-mit-esp8266-und-oled","status":"publish","type":"post","link":"https:\/\/technodidact.de\/en\/der-vollstandige-guide-wlan-signal-monitor-mit-esp8266-und-oled\/","title":{"rendered":"Der vollst\u00e4ndige Guide: WLAN-Signal-Monitor mit ESP8266 und OLED"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Ein Anf\u00e4nger-Projekt Schritt f\u00fcr Schritt erkl\u00e4rt<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Einleitung<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Dieses Projekt ist der ideale Einstieg in die Welt des ESP8266 und der IoT-Entwicklung. Wir bauen einen&nbsp;<strong>WLAN-Signal-Monitor<\/strong>, der dauerhaft die Empfangsst\u00e4rke zweier Netzwerke (z.B. FRITZI und SMU) auf einem OLED-Display anzeigt. Das Besondere: Das Ger\u00e4t arbeitet v\u00f6llig autonom, erstellt einen eigenen WLAN-Access Point und bietet ein Webinterface zur Konfiguration \u2013 ganz ohne dass du daf\u00fcr einen Router oder Internetzugang ben\u00f6tigst.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr Anf\u00e4nger ist dieses Projekt perfekt geeignet, weil es:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Alle Grundlagen<\/strong>\u00a0der ESP8266-Programmierung abdeckt<\/li>\n\n\n\n<li><strong>Hardware und Software<\/strong>\u00a0sinnvoll kombiniert<\/li>\n\n\n\n<li><strong>Sofort sichtbare Ergebnisse<\/strong>\u00a0liefert<\/li>\n\n\n\n<li><strong>Erweiterbar<\/strong>\u00a0ist f\u00fcr eigene Ideen<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Ben\u00f6tigte Hardware<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Grundausstattung:<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Komponente<\/th><th class=\"has-text-align-left\" data-align=\"left\">Beschreibung<\/th><th class=\"has-text-align-left\" data-align=\"left\">Ungef\u00e4hrer Preis<\/th><\/tr><\/thead><tbody><tr><td>ESP8266 NodeMCU v3<\/td><td>Das Gehirn des Projekts<\/td><td>5-8 \u20ac<\/td><\/tr><tr><td>OLED Display 0,96&#8243;<\/td><td>SSD1306, 128&#215;64 Pixel, I2C<\/td><td>3-5 \u20ac<\/td><\/tr><tr><td>4x Jumper-Kabel<\/td><td>Female-Female<\/td><td>1-2 \u20ac<\/td><\/tr><tr><td>Micro-USB Kabel<\/td><td>Zum Programmieren und Strom<\/td><td>2-3 \u20ac<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Gesamtkosten: ca. 10-15 \u20ac<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Bezugsquellen:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ESP8266<\/strong>: Amazon, eBay, AZ-Delivery, Reichelt<\/li>\n\n\n\n<li><strong>OLED Display<\/strong>: Gleiche Quellen, oft im Set mit ESP8266<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Wichtig beim Kauf:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ESP8266<\/strong>: Achte auf &#8222;NodeMCU v3&#8220; oder &#8222;ESP-12E&#8220; \u2013 das sind die g\u00e4ngigsten Versionen mit bester Dokumentation<\/li>\n\n\n\n<li><strong>OLED<\/strong>: Stelle sicher, dass es ein &#8222;SSD1306&#8220; mit I2C-Anschluss ist (4 Pins: VCC, GND, SCL, SDA)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Verkabelung \u2013 Schritt f\u00fcr Schritt<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Die Verbindung zwischen ESP8266 und OLED ist denkbar einfach, da wir die I2C-Schnittstelle nutzen:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">OLED Pin<\/th><th class=\"has-text-align-left\" data-align=\"left\">ESP8266 Pin<\/th><th class=\"has-text-align-left\" data-align=\"left\">Kabel<\/th><\/tr><\/thead><tbody><tr><td>VCC (3.3V)<\/td><td>3.3V<\/td><td>Rot<\/td><\/tr><tr><td>GND<\/td><td>GND<\/td><td>Schwarz<\/td><\/tr><tr><td>SCL (Clock)<\/td><td>D1 (GPIO5)<\/td><td>Gelb\/Gr\u00fcn<\/td><\/tr><tr><td>SDA (Data)<\/td><td>D2 (GPIO4)<\/td><td>Blau<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Detaillierte Anleitung:<\/strong><\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Vorbereitung:<\/strong>\u00a0Lege beide Boards vor dich. Der ESP8266 hat die Pins nach oben, das OLED hat meist 4 Pins in einer Reihe.<\/li>\n\n\n\n<li><strong>Spannungsversorgung (VCC und GND):<\/strong>\n<ul class=\"wp-block-list\">\n<li>Verbinde\u00a0<strong>VCC<\/strong>\u00a0(am OLED) mit\u00a0<strong>3.3V<\/strong>\u00a0(am ESP8266) \u2013 das rote Kabel<\/li>\n\n\n\n<li>Verbinde\u00a0<strong>GND<\/strong>\u00a0(am OLED) mit\u00a0<strong>GND<\/strong>\u00a0(am ESP8266) \u2013 das schwarze Kabel<br><em>Warum?: Das OLED braucht 3.3V Betriebsspannung, genau wie der ESP8266 sie liefert<\/em><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Datenleitungen (I2C):<\/strong>\n<ul class=\"wp-block-list\">\n<li>Verbinde\u00a0<strong>SCL<\/strong>\u00a0(am OLED) mit\u00a0<strong>D1<\/strong>\u00a0(am ESP8266) \u2013 das ist GPIO5<\/li>\n\n\n\n<li>Verbinde\u00a0<strong>SDA<\/strong>\u00a0(am OLED) mit\u00a0<strong>D2<\/strong>\u00a0(am ESP8266) \u2013 das ist GPIO4<br><em>Warum?: I2C ist ein Standardprotokoll, bei dem SCL der Takt und SDA die Datenleitung ist<\/em><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Kontrolle:<\/strong>\u00a0\u00dcberpr\u00fcfe alle Verbindungen. Sie sollten fest sitzen und die richtigen Pins treffen.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>H\u00e4ufige Fehler:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>VCC mit 5V statt 3.3V verbunden \u2192 OLED kann durchbrennen<\/li>\n\n\n\n<li>SCL und SDA vertauscht \u2192 Display bleibt dunkel<\/li>\n\n\n\n<li>GND vergessen \u2192 Display funktioniert nicht<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Software vorbereiten<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Arduino IDE installieren<\/h3>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>Lade die Arduino IDE herunter:\u00a0<a href=\"https:\/\/www.arduino.cc\/en\/software\" target=\"_blank\" rel=\"noreferrer noopener\">arduino.cc\/en\/software<\/a><\/li>\n\n\n\n<li>Installiere sie mit den Standard-Einstellungen<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">ESP8266 Board-Unterst\u00fctzung hinzuf\u00fcgen<\/h3>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>\u00d6ffne die Arduino IDE<\/li>\n\n\n\n<li>Gehe zu\u00a0<strong>Datei \u2192 Voreinstellungen<\/strong>\u00a0(Strg+Komma)<\/li>\n\n\n\n<li>F\u00fcge bei &#8222;Zus\u00e4tzliche Boardverwalter-URLs&#8220; ein:texthttp:\/\/arduino.esp8266.com\/stable\/package_esp8266com_index.json<\/li>\n\n\n\n<li>Klicke auf\u00a0<strong>OK<\/strong><\/li>\n\n\n\n<li>Gehe zu\u00a0<strong>Werkzeuge \u2192 Board \u2192 Boardverwalter<\/strong><\/li>\n\n\n\n<li>Suche nach &#8222;esp8266&#8220;<\/li>\n\n\n\n<li>Installiere\u00a0<strong>&#8222;esp8266 by ESP8266 Community&#8220;<\/strong>\u00a0(Version 3.0.2 oder neuer)<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Ben\u00f6tigte Bibliotheken installieren<\/h3>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>Gehe zu\u00a0<strong>Werkzeuge \u2192 Bibliotheken verwalten<\/strong>\u00a0(Strg+Umschalt+I)<\/li>\n\n\n\n<li>Suche und installiere:\n<ul class=\"wp-block-list\">\n<li><strong>&#8222;U8g2&#8220;<\/strong>\u00a0von oliver (f\u00fcr das OLED Display)<\/li>\n\n\n\n<li><strong>&#8222;ESP8266WiFi&#8220;<\/strong>\u00a0ist bereits im Board-Paket enthalten<\/li>\n\n\n\n<li><strong>&#8222;ESP8266WebServer&#8220;<\/strong>\u00a0ebenfalls im Board-Paket<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Wichtig:<\/strong>&nbsp;Nach der Installation aller Bibliotheken die IDE einmal neu starten.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Board-Einstellungen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Schlie\u00dfe deinen ESP8266 per USB an und stelle folgende Einstellungen ein:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Board:<\/strong>\u00a0&#8222;NodeMCU 1.0 (ESP-12E Module)&#8220;<\/li>\n\n\n\n<li><strong>Upload Speed:<\/strong>\u00a0&#8222;115200&#8220;<\/li>\n\n\n\n<li><strong>CPU Frequency:<\/strong>\u00a0&#8222;80 MHz&#8220;<\/li>\n\n\n\n<li><strong>Flash Size:<\/strong>\u00a0&#8222;4MB (FS:2MB OTA:~1019KB)&#8220;<\/li>\n\n\n\n<li><strong>Port:<\/strong>\u00a0Der COM-Port, unter dem dein ESP8266 erscheint (unter Windows z.B. COM3, COM4; unter Linux \/dev\/ttyUSB0)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Der vollst\u00e4ndige Code mit ausf\u00fchrlichen Erkl\u00e4rungen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">cpp<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>\/\/ ============================================================<\/em><br><em>\/\/ WLAN SIGNAL MONITOR F\u00dcR ESP8266 MIT OLED DISPLAY<\/em><br><em>\/\/ ============================================================<\/em><br><em>\/\/ Dieser Code erstellt einen dauerhaften Signal-Monitor f\u00fcr zwei<\/em><br><em>\/\/ WLAN-Netzwerke. Die Ergebnisse werden auf einem OLED angezeigt.<\/em><br><em>\/\/ Zus\u00e4tzlich gibt es ein Webinterface zur Konfiguration.<\/em><br><em>\/\/ ============================================================<\/em><br><br><em>\/\/ -------------------- BIBLIOTHEKEN --------------------<\/em><br><em>\/\/ Hier binden wir alle ben\u00f6tigten Bibliotheken ein.<\/em><br><em>\/\/ U8g2lib.h: F\u00fcr die Ansteuerung des OLED Displays<\/em><br><em>\/\/ Wire.h: F\u00fcr die I2C-Kommunikation mit dem Display<\/em><br><em>\/\/ ESP8266WiFi.h: F\u00fcr WLAN-Funktionen (scannen, AP-Modus)<\/em><br><em>\/\/ ESP8266WebServer.h: F\u00fcr den eingebauten Webserver<\/em><br><em>\/\/ EEPROM.h: Zum Speichern von Einstellungen dauerhaft<\/em><br><br>#include &lt;U8g2lib.h&gt;<br>#include &lt;Wire.h&gt;<br>#include &lt;ESP8266WiFi.h&gt;<br>#include &lt;ESP8266WebServer.h&gt;<br>#include &lt;EEPROM.h&gt;<br><br><em>\/\/ -------------------- OLED KONFIGURATION --------------------<\/em><br><em>\/\/ Hier initialisieren wir das Display.<\/em><br><em>\/\/ U8G2_SSD1306_128X64_NONAME_F_SW_I2C bedeutet:<\/em><br><em>\/\/ - SSD1306: Der Display-Chip<\/em><br><em>\/\/ - 128x64: Aufl\u00f6sung<\/em><br><em>\/\/ - F: Full buffer (ganzer Bildspeicher)<\/em><br><em>\/\/ - SW_I2C: Software I2C (wir definieren die Pins selbst)<\/em><br><em>\/\/ Die Zahlen 14 und 12 sind die GPIO-Pins f\u00fcr SCL und SDA:<\/em><br><em>\/\/ 14 = GPIO14 (D5) aber wir wollen D1 (GPIO5) und D2 (GPIO4)!<\/em><br><em>\/\/ ACHTUNG: Hier m\u00fcssen wir anpassen!<\/em><br><br><em>\/\/ Korrekte Initialisierung f\u00fcr D1=GPIO5 (SCL) und D2=GPIO4 (SDA):<\/em><br>U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, <em>\/* clock=*\/<\/em> 5, <em>\/* data=*\/<\/em> 4, <em>\/* reset=*\/<\/em> U8X8_PIN_NONE);<br><em>\/\/ U8G2_R0: Keine Rotation (0 Grad)<\/em><br><em>\/\/ clock=5: GPIO5 = D1 (SCL)<\/em><br><em>\/\/ data=4: GPIO4 = D2 (SDA)<\/em><br><em>\/\/ reset=U8X8_PIN_NONE: Kein Reset-Pin verwendet<\/em><br><br><em>\/\/ -------------------- WEB SERVER --------------------<\/em><br><em>\/\/ Erstelle einen Webserver, der auf Port 80 lauscht<\/em><br>ESP8266WebServer server(80);<br><br><em>\/\/ -------------------- EEPROM SPEICHER --------------------<\/em><br><em>\/\/ Der ESP8266 hat einen kleinen Speicher (EEPROM), in dem wir<\/em><br><em>\/\/ Einstellungen dauerhaft speichern k\u00f6nnen, auch nach Stromausfall.<\/em><br><em>\/\/ Wir reservieren 128 Bytes daf\u00fcr.<\/em><br>#define EEPROM_SIZE 128<br><br><em>\/\/ Hier definieren wir, wo welche Daten im EEPROM liegen:<\/em><br>#define ADDR_SSID1 0    <em>\/\/ Netzwerk 1 Name: Start bei Byte 0 (max 31 Zeichen + Null)<\/em><br>#define ADDR_SSID2 32   <em>\/\/ Netzwerk 2 Name: Start bei Byte 32<\/em><br>#define ADDR_SCAN_INT 64 <em>\/\/ Scan-Intervall: Start bei Byte 64 (4 Bytes f\u00fcr int)<\/em><br>#define ADDR_THRESHOLD 68 <em>\/\/ Alarm-Schwelle: Start bei Byte 68 (4 Bytes f\u00fcr int)<\/em><br><br><em>\/\/ -------------------- STANDARDWERTE --------------------<\/em><br><em>\/\/ Falls keine Einstellungen gespeichert sind oder der EEPROM leer ist,<\/em><br><em>\/\/ verwenden wir diese Werte als Standard.<\/em><br>String network1 = \"NW1\";        <em>\/\/ Erstes zu \u00fcberwachendes Netzwerk<\/em><br>String network2 = \"NW2\";            <em>\/\/ Zweites zu \u00fcberwachendes Netzwerk<\/em><br>int scanInterval = 10;              <em>\/\/ Scan alle 10 Sekunden<\/em><br>int alarmThreshold = -80;           <em>\/\/ Alarm bei -80 dBm oder schlechter<\/em><br><br><em>\/\/ -------------------- STATUSVARIABLEN --------------------<\/em><br><em>\/\/ Diese Variablen speichern den aktuellen Zustand des Systems.<\/em><br>int rssi1 = -100;           <em>\/\/ Signalst\u00e4rke Netzwerk 1 (Startwert sehr schlecht)<\/em><br>int rssi2 = -100;           <em>\/\/ Signalst\u00e4rke Netzwerk 2<\/em><br>bool found1 = false;        <em>\/\/ Wurde Netzwerk 1 gefunden?<\/em><br>bool found2 = false;        <em>\/\/ Wurde Netzwerk 2 gefunden?<\/em><br>unsigned long lastScan = 0; <em>\/\/ Zeitpunkt des letzten Scans (in Millisekunden)<\/em><br>bool alarmActive = false;   <em>\/\/ Ist gerade ein Alarm aktiv?<\/em><br>String lastAlarmTime = \"\";  <em>\/\/ Wann war der letzte Alarm?<\/em><br><br><em>\/\/ -------------------- SIGNALST\u00c4RKE-SYMBOLE --------------------<\/em><br><em>\/\/ Hier definieren wir, wie die Signalst\u00e4rke auf dem Display dargestellt wird.<\/em><br><em>\/\/ Wir haben 11 Stufen von 0 bis 10 Balken.<\/em><br>const char* signalBars[11] = {<br>  \"\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\",  <em>\/\/ 0\/10 - Kein Empfang<\/em><br>  \"\u2593\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\",  <em>\/\/ 1\/10<\/em><br>  \"\u2593\u2593\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\",  <em>\/\/ 2\/10<\/em><br>  \"\u2593\u2593\u2593\u2591\u2591\u2591\u2591\u2591\u2591\u2591\",  <em>\/\/ 3\/10<\/em><br>  \"\u2593\u2593\u2593\u2593\u2591\u2591\u2591\u2591\u2591\u2591\",  <em>\/\/ 4\/10<\/em><br>  \"\u2593\u2593\u2593\u2593\u2593\u2591\u2591\u2591\u2591\u2591\",  <em>\/\/ 5\/10<\/em><br>  \"\u2593\u2593\u2593\u2593\u2593\u2593\u2591\u2591\u2591\u2591\",  <em>\/\/ 6\/10<\/em><br>  \"\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2591\u2591\u2591\",  <em>\/\/ 7\/10<\/em><br>  \"\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2591\u2591\",  <em>\/\/ 8\/10<\/em><br>  \"\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2591\",  <em>\/\/ 9\/10<\/em><br>  \"\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\u2593\"   <em>\/\/ 10\/10 - Exzellenter Empfang<\/em><br>};<br><br><em>\/\/ -------------------- HILFSFUNKTIONEN --------------------<\/em><br><em>\/\/ Diese Funktionen helfen uns, die Signalst\u00e4rke zu interpretieren.<\/em><br><br><em>\/**<\/em><br> * Wandelt RSSI-Wert in eine Textbeschreibung um<br> * <br> * RSSI (Received Signal Strength Indicator) ist ein Ma\u00df f\u00fcr die<br> * Empfangsst\u00e4rke in dBm (Dezibel Milliwatt).<br> * Je n\u00e4her an 0, desto besser. -30 dBm ist exzellent, -100 dBm ist nichts.<br> * <br> * Typische Werte:<br> * -30 dBm: Direkt neben dem Router (perfekt)<br> * -50 dBm: Ausgezeichnet<br> * -60 dBm: Sehr gut<br> * -70 dBm: Gut<br> * -80 dBm: Mittel<br> * -90 dBm: Schwach<br> * -100 dBm: Kein Empfang<br> *\/<br>String getSignalQuality(int rssi) {<br>  if (rssi &gt;= -50) return \"AUSGEZEICHNET\";<br>  if (rssi &gt;= -60) return \"SEHR GUT\";<br>  if (rssi &gt;= -70) return \"GUT\";<br>  if (rssi &gt;= -80) return \"MITTEL\";<br>  if (rssi &gt;= -90) return \"SCHWACH\";<br>  return \"KEIN EMPFANG\";<br>}<br><br><em>\/**<\/em><br> * Wandelt RSSI in Prozent um (0-100%)<br> * <br> * Wir nehmen an, dass -30 dBm = 100% und -100 dBm = 0% ist.<br> * Alles dazwischen wird linear interpoliert.<br> *\/<br>int getSignalPercent(int rssi) {<br>  if (rssi &gt;= -30) return 100;<br>  if (rssi &lt;= -100) return 0;<br>  return map(rssi, -100, -30, 0, 100);<br>}<br><br><em>\/**<\/em><br> * Wandelt RSSI in Balken-Stufe um (0-10)<br> * <br> * Wir teilen die 0-100% einfach in 10 Stufen auf.<br> *\/<br>int getSignalBars(int rssi) {<br>  int percent = getSignalPercent(rssi);<br>  return map(percent, 0, 100, 0, 10);<br>}<br><br><em>\/**<\/em><br> * L\u00e4dt die gespeicherten Einstellungen aus dem EEPROM<br> * <br> * Der EEPROM ist ein nicht-fl\u00fcchtiger Speicher. Das bedeutet,<br> * die Daten bleiben auch nach Stromausfall erhalten.<br> * Wir m\u00fcssen EEPROM.begin() aufrufen, bevor wir lesen\/schreiben.<br> *\/<br>void loadSettings() {<br>  EEPROM.begin(EEPROM_SIZE);<br>  <br>  <em>\/\/ Netzwerk 1 lesen (Zeichen f\u00fcr Zeichen bis zum Null-Byte)<\/em><br>  network1 = \"\";<br>  for (int i = 0; i &lt; 32; i++) {<br>    char c = EEPROM.read(ADDR_SSID1 + i);<br>    if (c == 0) break;  <em>\/\/ Null-Byte = Ende des Strings<\/em><br>    network1 += c;<br>  }<br>  if (network1.length() == 0) network1 = \"FRITZI\";  <em>\/\/ Fallback<\/em><br>  <br>  <em>\/\/ Netzwerk 2 lesen<\/em><br>  network2 = \"\";<br>  for (int i = 0; i &lt; 32; i++) {<br>    char c = EEPROM.read(ADDR_SSID2 + i);<br>    if (c == 0) break;<br>    network2 += c;<br>  }<br>  if (network2.length() == 0) network2 = \"SMU\";  <em>\/\/ Fallback<\/em><br>  <br>  <em>\/\/ Scan Intervall lesen (ganze Zahl)<\/em><br>  EEPROM.get(ADDR_SCAN_INT, scanInterval);<br>  if (scanInterval &lt; 5 || scanInterval &gt; 300) scanInterval = 10;  <em>\/\/ Plausibilit\u00e4tspr\u00fcfung<\/em><br>  <br>  <em>\/\/ Alarm Schwelle lesen<\/em><br>  EEPROM.get(ADDR_THRESHOLD, alarmThreshold);<br>  if (alarmThreshold &gt; -30 || alarmThreshold &lt; -100) alarmThreshold = -80;  <em>\/\/ Pr\u00fcfung<\/em><br>  <br>  EEPROM.end();  <em>\/\/ EEPROM freigeben<\/em><br>  <br>  <em>\/\/ Ausgabe zur Kontrolle (f\u00fcr den seriellen Monitor)<\/em><br>  Serial.println(\"Einstellungen geladen:\");<br>  Serial.println(\"  Netzwerk 1: \" + network1);<br>  Serial.println(\"  Netzwerk 2: \" + network2);<br>  Serial.println(\"  Scan Intervall: \" + String(scanInterval) + \"s\");<br>  Serial.println(\"  Alarm Schwelle: \" + String(alarmThreshold) + \"dBm\");<br>}<br><br><em>\/**<\/em><br> * Speichert die aktuellen Einstellungen im EEPROM<br> *\/<br>void saveSettings() {<br>  EEPROM.begin(EEPROM_SIZE);<br>  <br>  <em>\/\/ Netzwerk 1 speichern (jedes Zeichen einzeln, dann Null-Byte)<\/em><br>  for (int i = 0; i &lt; 32; i++) {<br>    if (i &lt; network1.length()) {<br>      EEPROM.write(ADDR_SSID1 + i, network1[i]);<br>    } else {<br>      EEPROM.write(ADDR_SSID1 + i, 0);  <em>\/\/ Mit Null-Bytes auff\u00fcllen<\/em><br>    }<br>  }<br>  <br>  <em>\/\/ Netzwerk 2 speichern<\/em><br>  for (int i = 0; i &lt; 32; i++) {<br>    if (i &lt; network2.length()) {<br>      EEPROM.write(ADDR_SSID2 + i, network2[i]);<br>    } else {<br>      EEPROM.write(ADDR_SSID2 + i, 0);<br>    }<br>  }<br>  <br>  <em>\/\/ Zahlen speichern<\/em><br>  EEPROM.put(ADDR_SCAN_INT, scanInterval);<br>  EEPROM.put(ADDR_THRESHOLD, alarmThreshold);<br>  <br>  EEPROM.commit();  <em>\/\/ \u00c4nderungen festschreiben<\/em><br>  EEPROM.end();<br>  <br>  Serial.println(\"Einstellungen gespeichert\");<br>}<br><br><em>\/**<\/em><br> * F\u00fchrt einen WLAN-Scan durch und aktualisiert die RSSI-Werte<br> * <br> * Das ist das Herzst\u00fcck des Programms. Wir scannen alle verf\u00fcgbaren<br> * WLAN-Netzwerke und suchen nach unseren beiden Ziel-Netzwerken.<br> *\/<br>void scanWifi() {<br>  <em>\/\/ In den Station-Modus wechseln und alte Verbindungen trennen<\/em><br>  WiFi.mode(WIFI_STA);<br>  WiFi.disconnect();<br>  delay(10);<br>  <br>  <em>\/\/ Netzwerke scannen (blockierend)<\/em><br>  int n = WiFi.scanNetworks();<br>  <br>  <em>\/\/ Reset der Statusvariablen<\/em><br>  rssi1 = -100;<br>  rssi2 = -100;<br>  found1 = false;<br>  found2 = false;<br>  alarmActive = false;<br>  <br>  <em>\/\/ Gefundene Netzwerke durchsuchen<\/em><br>  for (int i = 0; i &lt; n; i++) {<br>    String ssid = WiFi.SSID(i);<br>    int rssi = WiFi.RSSI(i);<br>    <br>    <em>\/\/ Pr\u00fcfen, ob es Netzwerk 1 ist<\/em><br>    if (ssid == network1) {<br>      rssi1 = rssi;<br>      found1 = true;<br>      if (rssi &lt;= alarmThreshold) {<br>        alarmActive = true;  <em>\/\/ Alarm ausl\u00f6sen<\/em><br>      }<br>    }<br>    <br>    <em>\/\/ Pr\u00fcfen, ob es Netzwerk 2 ist<\/em><br>    if (ssid == network2) {<br>      rssi2 = rssi;<br>      found2 = true;<br>      if (rssi &lt;= alarmThreshold) {<br>        alarmActive = true;<br>      }<br>    }<br>  }<br>  <br>  <em>\/\/ Scan-Ergebnisse freigeben<\/em><br>  WiFi.scanDelete();<br>  <br>  <em>\/\/ Wenn Alarm, Zeit speichern<\/em><br>  if (alarmActive) {<br>    lastAlarmTime = getTimeString();<br>  }<br>}<br><br><em>\/**<\/em><br> * Gibt einen einfachen Zeit-String zur\u00fcck (seit Systemstart)<br> * <br> * Da wir keine Echtzeituhr haben, z\u00e4hlen wir einfach die Millisekunden<br> * seit dem Start und rechnen sie in Stunden:Minuten:Sekunden um.<br> *\/<br>String getTimeString() {<br>  unsigned long seconds = millis() \/ 1000;<br>  unsigned long minutes = seconds \/ 60;<br>  unsigned long hours = minutes \/ 60;<br>  <br>  char buffer[20];<br>  snprintf(buffer, sizeof(buffer), \"%02lu:%02lu:%02lu\", <br>           hours % 24, minutes % 60, seconds % 60);<br>  return String(buffer);<br>}<br><br><em>\/**<\/em><br> * Aktualisiert die Anzeige auf dem OLED<br> * <br> * Diese Funktion ist f\u00fcr das Layout des Displays verantwortlich.<br> * Sie zeichnet Text, Linien und Symbole an die richtigen Positionen.<br> *\/<br>void updateDisplay() {<br>  u8g2.clearBuffer();  <em>\/\/ Display l\u00f6schen<\/em><br>  <br>  <em>\/\/ ----- HEADER (obere Zeile) -----<\/em><br>  u8g2.setFont(u8g2_font_6x10_tf);  <em>\/\/ Kleine Schrift<\/em><br>  u8g2.setCursor(0, 10);              <em>\/\/ Position (x=0, y=10)<\/em><br>  u8g2.print(\"WLAN SIGNAL MONITOR\");<br>  <br>  <em>\/\/ Alarm-Anzeige rechts im Header<\/em><br>  if (alarmActive) {<br>    u8g2.setCursor(100, 10);<br>    u8g2.print(\"ALARM!\");<br>  }<br>  <br>  <em>\/\/ Trennlinie unter dem Header<\/em><br>  u8g2.drawLine(0, 12, 128, 12);<br>  <br>  <em>\/\/ ----- NETZWERK 1 (oberer Bereich) -----<\/em><br>  u8g2.setFont(u8g2_font_7x13_tf);  <em>\/\/ Gr\u00f6\u00dfere Schrift f\u00fcr Netzwerkname<\/em><br>  u8g2.setCursor(0, 28);<br>  <br>  <em>\/\/ Netzwerkname k\u00fcrzen, falls zu lang (max 8 Zeichen)<\/em><br>  String displayName1 = network1;<br>  if (displayName1.length() &gt; 8) {<br>    displayName1 = displayName1.substring(0, 8) + \".\";<br>  }<br>  u8g2.print(displayName1);<br>  u8g2.print(\":\");<br>  <br>  <em>\/\/ Signal-Balken<\/em><br>  int bars1 = found1 ? getSignalBars(rssi1) : 0;<br>  u8g2.setFont(u8g2_font_unifont_t_symbols);  <em>\/\/ Spezielle Schrift f\u00fcr Symbole<\/em><br>  u8g2.setCursor(0, 42);<br>  u8g2.print(signalBars[bars1]);<br>  <br>  <em>\/\/ Qualit\u00e4ts-Text<\/em><br>  u8g2.setFont(u8g2_font_6x10_tf);<br>  u8g2.setCursor(0, 54);<br>  if (found1) {<br>    String quality = getSignalQuality(rssi1);<br>    u8g2.print(quality);<br>    <br>    <em>\/\/ Alarm-Markierung (unterer Balken)<\/em><br>    if (rssi1 &lt;= alarmThreshold) {<br>      u8g2.drawBox(0, 55, 128, 2);  <em>\/\/ Schwarzer Balken als Warnung<\/em><br>    }<br>  } else {<br>    u8g2.print(\"NICHT GEFUNDEN\");<br>  }<br>  <br>  <em>\/\/ Trennlinie zwischen den Netzwerken<\/em><br>  u8g2.drawLine(0, 56, 128, 56);<br>  <br>  <em>\/\/ ----- NETZWERK 2 (unterer Bereich) -----<\/em><br>  u8g2.setFont(u8g2_font_7x13_tf);<br>  u8g2.setCursor(0, 64);<br>  <br>  <em>\/\/ Netzwerkname k\u00fcrzen<\/em><br>  String displayName2 = network2;<br>  if (displayName2.length() &gt; 8) {<br>    displayName2 = displayName2.substring(0, 8) + \".\";<br>  }<br>  u8g2.print(displayName2);<br>  u8g2.print(\":\");<br>  <br>  <em>\/\/ F\u00fcr Netzwerk 2 haben wir weniger Platz, daher nur Kurzinfo<\/em><br>  u8g2.setFont(u8g2_font_6x10_tf);<br>  u8g2.setCursor(60, 64);<br>  if (found2) {<br>    u8g2.print(getSignalQuality(rssi2));<br>    <br>    <em>\/\/ Alarm-Markierung<\/em><br>    if (rssi2 &lt;= alarmThreshold) {<br>      u8g2.drawBox(60, 65, 68, 2);<br>    }<br>  } else {<br>    u8g2.print(\"NICHT DA\");<br>  }<br>  <br>  <em>\/\/ Bildschirm \u00fcbertragen<\/em><br>  u8g2.sendBuffer();<br>}<br><br><em>\/\/ -------------------- WEBINTERFACE --------------------<\/em><br><em>\/\/ Diese Funktionen erzeugen die HTML-Seiten f\u00fcr die Konfiguration.<\/em><br><br><em>\/**<\/em><br> * Generiert die komplette HTML-Seite f\u00fcr das Webinterface<br> *\/<br>String getWebPage() {<br>  String html = \"&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;\";<br>  html += \"&lt;meta name='viewport' content='width=device-width, initial-scale=1'&gt;\";<br>  html += \"&lt;meta charset='UTF-8'&gt;\";<br>  html += \"&lt;title&gt;WLAN Monitor Einstellungen&lt;\/title&gt;\";<br>  html += \"&lt;style&gt;\";<br>  html += \"body { font-family: Arial, sans-serif; margin: 20px; background: #f0f0f0; }\";<br>  html += \".container { max-width: 600px; margin: auto; background: white; padding: 20px; border-radius: 10px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }\";<br>  html += \"h1 { color: #333; }\";<br>  html += \"h2 { color: #555; border-bottom: 2px solid #4CAF50; padding-bottom: 5px; }\";<br>  html += \"label { display: block; margin: 10px 0 5px; font-weight: bold; }\";<br>  html += \"input, select { width: 100%; padding: 8px; margin-bottom: 15px; border: 1px solid #ddd; border-radius: 4px; }\";<br>  html += \"button { background: #4CAF50; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }\";<br>  html += \"button:hover { background: #45a049; }\";<br>  html += \".status { background: #e8f5e9; padding: 10px; border-radius: 5px; margin: 10px 0; }\";<br>  html += \".alarm { background: #ffebee; padding: 10px; border-radius: 5px; margin: 10px 0; }\";<br>  html += \"&lt;\/style&gt;\";<br>  html += \"&lt;\/head&gt;&lt;body&gt;\";<br>  html += \"&lt;div class='container'&gt;\";<br>  html += \"&lt;h1&gt;\ud83d\udcf6 WLAN Monitor Einstellungen&lt;\/h1&gt;\";<br>  <br>  <em>\/\/ Aktueller Status-Block<\/em><br>  html += \"&lt;div class='status'&gt;\";<br>  html += \"&lt;h2&gt;Aktueller Status&lt;\/h2&gt;\";<br>  html += \"&lt;p&gt;&lt;strong&gt;\" + network1 + \":&lt;\/strong&gt; \";<br>  html += found1 ? String(rssi1) + \" dBm (\" + getSignalQuality(rssi1) + \")\" : \"Nicht gefunden\";<br>  html += \"&lt;\/p&gt;\";<br>  html += \"&lt;p&gt;&lt;strong&gt;\" + network2 + \":&lt;\/strong&gt; \";<br>  html += found2 ? String(rssi2) + \" dBm (\" + getSignalQuality(rssi2) + \")\" : \"Nicht gefunden\";<br>  html += \"&lt;\/p&gt;\";<br>  html += \"&lt;p&gt;&lt;strong&gt;Letzter Scan:&lt;\/strong&gt; Vor \" + String((millis() - lastScan) \/ 1000) + \" Sekunden&lt;\/p&gt;\";<br>  <br>  <em>\/\/ Alarm-Anzeige, falls aktiv<\/em><br>  if (alarmActive) {<br>    html += \"&lt;div class='alarm'&gt;\";<br>    html += \"&lt;p&gt;&lt;strong&gt;\u26a0\ufe0f ALARM AKTIV!&lt;\/strong&gt;&lt;\/p&gt;\";<br>    html += \"&lt;p&gt;Signal unter \" + String(alarmThreshold) + \" dBm&lt;\/p&gt;\";<br>    html += \"&lt;p&gt;Letzter Alarm: \" + lastAlarmTime + \"&lt;\/p&gt;\";<br>    html += \"&lt;\/div&gt;\";<br>  }<br>  html += \"&lt;\/div&gt;\";<br>  <br>  <em>\/\/ Einstellungs-Formular<\/em><br>  html += \"&lt;h2&gt;Einstellungen&lt;\/h2&gt;\";<br>  html += \"&lt;form action='\/save' method='POST'&gt;\";<br>  <br>  html += \"&lt;label for='ssid1'&gt;Netzwerk 1 Name:&lt;\/label&gt;\";<br>  html += \"&lt;input type='text' id='ssid1' name='ssid1' value='\" + network1 + \"' maxlength='31'&gt;\";<br>  <br>  html += \"&lt;label for='ssid2'&gt;Netzwerk 2 Name:&lt;\/label&gt;\";<br>  html += \"&lt;input type='text' id='ssid2' name='ssid2' value='\" + network2 + \"' maxlength='31'&gt;\";<br>  <br>  html += \"&lt;label for='interval'&gt;Scan Intervall (Sekunden):&lt;\/label&gt;\";<br>  html += \"&lt;input type='number' id='interval' name='interval' value='\" + String(scanInterval) + \"' min='5' max='300'&gt;\";<br>  <br>  html += \"&lt;label for='threshold'&gt;Alarm Schwelle (dBm):&lt;\/label&gt;\";<br>  html += \"&lt;select id='threshold' name='threshold'&gt;\";<br>  String thresholds[] = {\"-70\", \"-75\", \"-80\", \"-85\", \"-90\"};<br>  for (String t : thresholds) {<br>    html += \"&lt;option value='\" + t + \"'\";<br>    if (t.toInt() == alarmThreshold) html += \" selected\";<br>    html += \"&gt;\" + t + \" dBm&lt;\/option&gt;\";<br>  }<br>  html += \"&lt;\/select&gt;\";<br>  <br>  html += \"&lt;button type='submit'&gt;Einstellungen Speichern&lt;\/button&gt;\";<br>  html += \"&lt;\/form&gt;\";<br>  <br>  <em>\/\/ Steuerungs-Buttons<\/em><br>  html += \"&lt;h2&gt;Steuerung&lt;\/h2&gt;\";<br>  html += \"&lt;p&gt;&lt;a href='\/scan'&gt;&lt;button&gt;Sofort Scannen&lt;\/button&gt;&lt;\/a&gt;&lt;\/p&gt;\";<br>  html += \"&lt;p&gt;&lt;a href='\/reboot'&gt;&lt;button&gt;Neustart&lt;\/button&gt;&lt;\/a&gt;&lt;\/p&gt;\";<br>  <br>  <em>\/\/ System-Informationen<\/em><br>  html += \"&lt;h2&gt;System Info&lt;\/h2&gt;\";<br>  html += \"&lt;p&gt;IP Adresse: \" + WiFi.softAPIP().toString() + \"&lt;\/p&gt;\";<br>  html += \"&lt;p&gt;ESP8266 Chip ID: \" + String(ESP.getChipId()) + \"&lt;\/p&gt;\";<br>  html += \"&lt;p&gt;Free Heap: \" + String(ESP.getFreeHeap()) + \" Bytes&lt;\/p&gt;\";<br>  <br>  html += \"&lt;\/div&gt;\";<br>  html += \"&lt;\/body&gt;&lt;\/html&gt;\";<br>  <br>  return html;<br>}<br><br><em>\/\/ -------------------- WEB SERVER HANDLER --------------------<\/em><br><em>\/\/ Diese Funktionen werden aufgerufen, wenn bestimmte URLs aufgerufen werden.<\/em><br><br><em>\/**<\/em><br> * Hauptseite (\/) anzeigen<br> *\/<br>void handleRoot() {<br>  server.send(200, \"text\/html\", getWebPage());<br>}<br><br><em>\/**<\/em><br> * Einstellungen speichern (\/save)<br> * Wird aufgerufen, wenn das Formular abgeschickt wird<br> *\/<br>void handleSave() {<br>  <em>\/\/ Werte aus dem Formular auslesen<\/em><br>  if (server.hasArg(\"ssid1\")) network1 = server.arg(\"ssid1\");<br>  if (server.hasArg(\"ssid2\")) network2 = server.arg(\"ssid2\");<br>  if (server.hasArg(\"interval\")) scanInterval = server.arg(\"interval\").toInt();<br>  if (server.hasArg(\"threshold\")) alarmThreshold = server.arg(\"threshold\").toInt();<br>  <br>  <em>\/\/ Im EEPROM speichern<\/em><br>  saveSettings();<br>  <br>  <em>\/\/ Best\u00e4tigungsseite mit automatischer Weiterleitung<\/em><br>  String html = \"&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;\";<br>  html += \"&lt;meta http-equiv='refresh' content='3;url=\/'&gt;\";<br>  html += \"&lt;title&gt;Einstellungen gespeichert&lt;\/title&gt;\";<br>  html += \"&lt;style&gt;body { font-family: Arial; text-align: center; margin-top: 50px; }&lt;\/style&gt;\";<br>  html += \"&lt;\/head&gt;&lt;body&gt;\";<br>  html += \"&lt;h1&gt;\u2705 Einstellungen gespeichert!&lt;\/h1&gt;\";<br>  html += \"&lt;p&gt;Weiterleitung in 3 Sekunden...&lt;\/p&gt;\";<br>  html += \"&lt;\/body&gt;&lt;\/html&gt;\";<br>  <br>  server.send(200, \"text\/html\", html);<br>}<br><br><em>\/**<\/em><br> * Sofort-Scan ausf\u00fchren (\/scan)<br> *\/<br>void handleScan() {<br>  scanWifi();  <em>\/\/ Neuen Scan durchf\u00fchren<\/em><br>  server.sendHeader(\"Location\", \"\/\");  <em>\/\/ Zur\u00fcck zur Hauptseite<\/em><br>  server.send(302, \"text\/plain\", \"Scan gestartet\");<br>}<br><br><em>\/**<\/em><br> * Neustart ausf\u00fchren (\/reboot)<br> *\/<br>void handleReboot() {<br>  server.send(200, \"text\/html\", \"&lt;h1&gt;Neustart...&lt;\/h1&gt;\");<br>  delay(1000);  <em>\/\/ Kurz warten, damit die Seite gesendet wird<\/em><br>  ESP.restart();  <em>\/\/ ESP8266 neu starten<\/em><br>}<br><br><em>\/\/ -------------------- SETUP-FUNKTION --------------------<\/em><br><em>\/\/ Wird einmal beim Start ausgef\u00fchrt<\/em><br><br>void setup() {<br>  <em>\/\/ Serielle Schnittstelle f\u00fcr Debug-Ausgaben starten<\/em><br>  Serial.begin(115200);<br>  Serial.println(\"\\n=== WLAN Monitor mit Webinterface ===\");<br>  <br>  <em>\/\/ Display initialisieren<\/em><br>  u8g2.begin();<br>  <br>  <em>\/\/ Startbildschirm anzeigen<\/em><br>  u8g2.clearBuffer();<br>  u8g2.setFont(u8g2_font_10x20_tf);<br>  u8g2.setCursor(10, 30);<br>  u8g2.print(\"WLAN\");<br>  u8g2.setCursor(10, 55);<br>  u8g2.print(\"MONITOR\");<br>  u8g2.sendBuffer();<br>  delay(2000);<br>  <br>  <em>\/\/ Gespeicherte Einstellungen laden<\/em><br>  loadSettings();<br>  <br>  <em>\/\/ WiFi als Access Point starten<\/em><br>  WiFi.mode(WIFI_AP);  <em>\/\/ Access Point Modus<\/em><br>  <br>  <em>\/\/ Einen eindeutigen Namen f\u00fcr den Access Point generieren<\/em><br>  String apName = \"WLAN-Monitor-\" + String(ESP.getChipId());<br>  WiFi.softAP(apName.c_str());  <em>\/\/ AP starten (ohne Passwort)<\/em><br>  <br>  Serial.println(\"Access Point gestartet:\");<br>  Serial.println(\"  SSID: \" + apName);<br>  Serial.println(\"  IP: \" + WiFi.softAPIP().toString());<br>  <br>  <em>\/\/ Web Server Routen einrichten<\/em><br>  server.on(\"\/\", handleRoot);        <em>\/\/ Hauptseite<\/em><br>  server.on(\"\/save\", handleSave);    <em>\/\/ Einstellungen speichern<\/em><br>  server.on(\"\/scan\", handleScan);    <em>\/\/ Sofort scannen<\/em><br>  server.on(\"\/reboot\", handleReboot); <em>\/\/ Neustart<\/em><br>  <br>  <em>\/\/ Web Server starten<\/em><br>  server.begin();<br>  Serial.println(\"Web Server gestartet\");<br>  <br>  <em>\/\/ Ersten Scan durchf\u00fchren<\/em><br>  scanWifi();<br>  updateDisplay();<br>  <br>  Serial.println(\"System bereit!\");<br>}<br><br><em>\/\/ -------------------- HAUPT-SCHLEIFE --------------------<\/em><br><em>\/\/ Wird immer wieder ausgef\u00fchrt<\/em><br><br>void loop() {<br>  <em>\/\/ Web Server Anfragen bearbeiten<\/em><br>  server.handleClient();<br>  <br>  unsigned long now = millis();<br>  <br>  <em>\/\/ Regelm\u00e4\u00dfig scannen (alle scanInterval Sekunden)<\/em><br>  if (now - lastScan &gt;= scanInterval * 1000) {<br>    scanWifi();           <em>\/\/ Neuen Scan durchf\u00fchren<\/em><br>    updateDisplay();      <em>\/\/ Display aktualisieren<\/em><br>    lastScan = now;       <em>\/\/ Zeitpunkt merken<\/em><br>    <br>    <em>\/\/ Debug-Ausgabe \u00fcber serielle Schnittstelle<\/em><br>    Serial.print(\"Scan: \");<br>    Serial.print(network1 + \": \");<br>    if (found1) Serial.print(String(rssi1) + \"dBm\");<br>    else Serial.print(\"nicht da\");<br>    Serial.print(\" | \" + network2 + \": \");<br>    if (found2) Serial.println(String(rssi2) + \"dBm\");<br>    else Serial.println(\"nicht da\");<br>    <br>    if (alarmActive) {<br>      Serial.println(\"\u26a0\ufe0f ALARM: Signal unter \" + String(alarmThreshold) + \"dBm!\");<br>    }<br>  }<br>  <br>  <em>\/\/ Kurze Pause, um CPU-Last zu reduzieren<\/em><br>  delay(100);<br>}<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Schritt-f\u00fcr-Schritt: Code hochladen<\/h2>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Code kopieren:<\/strong>\u00a0Markiere den gesamten Code oben und kopiere ihn (Strg+C)<\/li>\n\n\n\n<li><strong>In Arduino IDE einf\u00fcgen:<\/strong>\u00a0\u00d6ffne die Arduino IDE, erstelle eine neue Datei (Strg+N) und f\u00fcge den Code ein (Strg+V)<\/li>\n\n\n\n<li><strong>Board ausw\u00e4hlen:<\/strong>\u00a0Gehe zu\u00a0<strong>Werkzeuge \u2192 Board \u2192 ESP8266 Boards \u2192 NodeMCU 1.0 (ESP-12E Module)<\/strong><\/li>\n\n\n\n<li><strong>Port ausw\u00e4hlen:<\/strong>\u00a0Unter\u00a0<strong>Werkzeuge \u2192 Port<\/strong>\u00a0w\u00e4hlst du den COM-Port, unter dem dein ESP8266 erscheint<\/li>\n\n\n\n<li><strong>Code \u00fcberpr\u00fcfen:<\/strong>\u00a0Klicke auf den\u00a0<strong>Haken<\/strong>\u00a0(\u00dcberpr\u00fcfen) \u2013 die IDE compiliert den Code und zeigt Fehler an, falls vorhanden<\/li>\n\n\n\n<li><strong>Hochladen:<\/strong>\u00a0Klicke auf den\u00a0<strong>Pfeil<\/strong>\u00a0(Hochladen). Die IDE kompiliert erneut und l\u00e4dt den Code auf den ESP8266<\/li>\n\n\n\n<li><strong>Warten:<\/strong>\u00a0W\u00e4hrend des Uploads blinkt die LED auf dem Board. Wenn &#8222;Done uploading&#8220; erscheint, ist der Vorgang abgeschlossen<\/li>\n\n\n\n<li><strong>Neustart:<\/strong>\u00a0Der ESP8266 startet automatisch neu und f\u00fchrt den Code aus<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Typische Fehler beim Hochladen:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>&#8222;Upload fehlgeschlagen&#8220;<\/strong>: Halte den Flash-Button gedr\u00fcckt, dr\u00fccke kurz Reset, lasse Flash los \u2013 dann erneut versuchen<\/li>\n\n\n\n<li><strong>&#8222;Port nicht gefunden&#8220;<\/strong>: Pr\u00fcfe, ob der richtige USB-Treiber installiert ist (CP2102 oder CH340)<\/li>\n\n\n\n<li><strong>&#8222;Board nicht kompatibel&#8220;<\/strong>: Pr\u00fcfe, ob das richtige Board ausgew\u00e4hlt ist<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Inbetriebnahme und Test<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Erste Schritte nach dem Hochladen:<\/h3>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Display pr\u00fcfen:<\/strong>\u00a0Das OLED sollte &#8222;WLAN MONITOR&#8220; anzeigen, dann nach kurzer Zeit die Signalst\u00e4rke<\/li>\n\n\n\n<li><strong>Mit dem Access Point verbinden:<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u00d6ffne die WLAN-Einstellungen deines Smartphones\/PCs<\/li>\n\n\n\n<li>Suche nach einem Netzwerk namens\u00a0<strong>&#8222;WLAN-Monitor-XXXXXX&#8220;<\/strong>\u00a0(die Zahlen sind individuell)<\/li>\n\n\n\n<li>Verbinde dich (kein Passwort n\u00f6tig)<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Webinterface \u00f6ffnen:<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u00d6ffne einen Browser<\/li>\n\n\n\n<li>Gib ein:\u00a0<strong><a href=\"http:\/\/192.168.4.1\/\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/192.168.4.1<\/a><\/strong><\/li>\n\n\n\n<li>Du siehst nun die Webseite mit Status und Einstellungen<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Funktionstest:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Die Signalst\u00e4rke sollte angezeigt werden<\/li>\n\n\n\n<li>\u00c4ndere die Netzwerk-Namen (z.B. dein eigenes WLAN)<\/li>\n\n\n\n<li>Klicke auf &#8222;Sofort Scannen&#8220; und beobachte die \u00c4nderungen<\/li>\n\n\n\n<li>Stelle einen Alarm ein und pr\u00fcfe, ob er bei schwachem Signal ausl\u00f6st<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Detaillierte Erkl\u00e4rung des Codes<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">7.1 Grundlegende Konzepte<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Was ist ein ESP8266?<\/strong><br>Der ESP8266 ist ein Mikrocontroller mit integriertem WLAN. Er kann Sensoren auslesen, Displays ansteuern und sich mit dem Internet verbinden \u2013 alles f\u00fcr wenige Euro.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Was ist I2C?<\/strong><br>I2C (Inter-Integrated Circuit) ist ein Kommunikationsprotokoll, mit dem mehrere Ger\u00e4te \u00fcber nur zwei Leitungen (SCL und SDA) miteinander kommunizieren k\u00f6nnen. Unser OLED Display nutzt I2C.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Was ist RSSI?<\/strong><br>RSSI (Received Signal Strength Indicator) ist ein Ma\u00df f\u00fcr die Empfangsst\u00e4rke eines WLAN-Signals. Der Wert wird in dBm (Dezibel Milliwatt) angegeben und ist negativ. Je n\u00e4her an 0, desto besser: -30 dBm ist exzellent, -90 dBm ist sehr schwach.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">7.2 Die wichtigsten Code-Teile im Detail<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Bibliotheken einbinden:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">cpp<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#include &lt;U8g2lib.h&gt;      <em>\/\/ F\u00fcr das OLED Display<\/em>\n#include &lt;Wire.h&gt;         <em>\/\/ F\u00fcr I2C-Kommunikation<\/em>\n#include &lt;ESP8266WiFi.h&gt;  <em>\/\/ F\u00fcr WLAN-Funktionen<\/em>\n#include &lt;ESP8266WebServer.h&gt; <em>\/\/ F\u00fcr den Webserver<\/em>\n#include &lt;EEPROM.h&gt;       <em>\/\/ F\u00fcr dauerhafte Speicherung<\/em><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Jede Bibliothek erweitert die F\u00e4higkeiten unseres Programms. Stell dir vor, du kaufst Werkzeuge f\u00fcr deinen Werkzeugkasten \u2013 jede Bibliothek ist ein spezialisiertes Werkzeug.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Display initialisieren:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">cpp<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, <em>\/* clock=*\/<\/em> 5, <em>\/* data=*\/<\/em> 4, <em>\/* reset=*\/<\/em> U8X8_PIN_NONE);<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Hier sagen wir dem Programm: &#8222;Wir haben ein OLED mit 128&#215;64 Pixeln, das per Software-I2C an GPIO5 (SCL) und GPIO4 (SDA) angeschlossen ist.&#8220; Die Zahlen 5 und 4 sind entscheidend \u2013 sie m\u00fcssen genau den Pins entsprechen, die du verdrahtet hast.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Signalst\u00e4rke interpretieren:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">cpp<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">String getSignalQuality(int rssi) {\n  if (rssi &gt;= -50) return \"AUSGEZEICHNET\";\n  if (rssi &gt;= -60) return \"SEHR GUT\";\n  if (rssi &gt;= -70) return \"GUT\";\n  if (rssi &gt;= -80) return \"MITTEL\";\n  if (rssi &gt;= -90) return \"SCHWACH\";\n  return \"KEIN EMPFANG\";\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Diese Funktion \u00fcbersetzt den technischen RSSI-Wert in eine f\u00fcr Menschen verst\u00e4ndliche Beschreibung. Sie ist ein gutes Beispiel f\u00fcr &#8222;Abstraktion&#8220; \u2013 wir verstecken die technischen Details hinter einfachen Worten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>WLAN scannen:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">cpp<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">int n = WiFi.scanNetworks();\nfor (int i = 0; i &lt; n; i++) {\n  String ssid = WiFi.SSID(i);\n  int rssi = WiFi.RSSI(i);\n  <em>\/\/ ... pr\u00fcfen, ob es unser Netzwerk ist<\/em>\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Hier bitten wir den ESP8266, alle in Reichweite befindlichen WLANs zu suchen. Dann gehen wir die Liste durch und merken uns die Signalst\u00e4rke unserer beiden Ziel-Netzwerke.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Display ansteuern:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">cpp<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">u8g2.clearBuffer();           <em>\/\/ Display l\u00f6schen<\/em>\nu8g2.setFont(u8g2_font_...);  <em>\/\/ Schriftart w\u00e4hlen<\/em>\nu8g2.setCursor(x, y);         <em>\/\/ Position setzen<\/em>\nu8g2.print(\"Text\");           <em>\/\/ Text schreiben<\/em>\nu8g2.drawLine(x1, y1, x2, y2); <em>\/\/ Linie zeichnen<\/em>\nu8g2.sendBuffer();            <em>\/\/ Alles anzeigen<\/em><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist wie malen auf einem digitalen Blatt Papier: Zuerst l\u00f6schen wir die Leinwand, dann w\u00e4hlen wir Pinsel und Farbe (Schriftart), setzen den Pinsel an eine Position und malen (print\/zeichnen). Zum Schluss schicken wir das Bild an den Bildschirm.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">7.3 Die Hauptschleife verstehen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Die&nbsp;<code>loop()<\/code>-Funktion wird immer wieder ausgef\u00fchrt, solange das Ger\u00e4t l\u00e4uft:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Webserver bedienen:<\/strong>\u00a0<code>server.handleClient()<\/code>\u00a0pr\u00fcft, ob jemand im Browser auf unser Ger\u00e4t zugreift, und reagiert darauf.<\/li>\n\n\n\n<li><strong>Zeit pr\u00fcfen:<\/strong>\u00a0<code>if (now - lastScan &gt;= scanInterval * 1000)<\/code>\u00a0rechnet aus, ob es Zeit f\u00fcr einen neuen Scan ist.\u00a0<code>millis()<\/code>\u00a0z\u00e4hlt die Millisekunden seit dem Start,\u00a0<code>lastScan<\/code>\u00a0merkt sich den Zeitpunkt des letzten Scans.<\/li>\n\n\n\n<li><strong>Scannen und anzeigen:<\/strong>\u00a0Wenn genug Zeit vergangen ist, wird neu gescannt, das Display aktualisiert und der Zeitpunkt gemerkt.<\/li>\n\n\n\n<li><strong>Kurze Pause:<\/strong>\u00a0<code>delay(100)<\/code>\u00a0wartet 100 Millisekunden \u2013 das verhindert, dass der ESP8266 zu viel Rechenleistung verbraucht.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Fehlerbehebung \u2013 H\u00e4ufige Probleme und L\u00f6sungen<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Display bleibt dunkel:<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">M\u00f6gliche Ursache<\/th><th class=\"has-text-align-left\" data-align=\"left\">L\u00f6sung<\/th><\/tr><\/thead><tbody><tr><td>Falsche Verkabelung<\/td><td>Pr\u00fcfe: VCC \u2192 3.3V, GND \u2192 GND, SCL \u2192 D1, SDA \u2192 D2<\/td><\/tr><tr><td>I2C-Adresse falsch<\/td><td>Manche OLEDs haben 0x3C, andere 0x3D. Probiere im Code&nbsp;<code>u8g2.begin(0x3D)<\/code><\/td><\/tr><tr><td>Display defekt<\/td><td>Teste mit einem anderen I2C-Ger\u00e4t (z.B. Sensor)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Keine WLAN-Netzwerke gefunden:<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">M\u00f6gliche Ursache<\/th><th class=\"has-text-align-left\" data-align=\"left\">L\u00f6sung<\/th><\/tr><\/thead><tbody><tr><td>Zu weit vom Router entfernt<\/td><td>Gehe n\u00e4her an den Router<\/td><\/tr><tr><td>Falscher Netzwerkname<\/td><td>Pr\u00fcfe Gro\u00df-\/Kleinschreibung im Webinterface<\/td><\/tr><tr><td>WLAN deaktiviert<\/td><td>Stelle sicher, dass das Netzwerk sichtbar ist<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Webinterface nicht erreichbar:<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">M\u00f6gliche Ursache<\/th><th class=\"has-text-align-left\" data-align=\"left\">L\u00f6sung<\/th><\/tr><\/thead><tbody><tr><td>Falsches WLAN<\/td><td>Verbinde mit &#8222;WLAN-Monitor-XXXXXX&#8220;, nicht deinem Heimnetz<\/td><\/tr><tr><td>Falsche IP<\/td><td>\u00d6ffne&nbsp;<a href=\"http:\/\/192.168.4.1\/\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/192.168.4.1<\/a>&nbsp;\u2013 das ist immer die IP des Access Points<\/td><\/tr><tr><td>Ger\u00e4t nicht gestartet<\/td><td>Dr\u00fccke den Reset-Knopf am ESP8266<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Ungew\u00f6hnliche RSSI-Werte:<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">M\u00f6gliche Ursache<\/th><th class=\"has-text-align-left\" data-align=\"left\">L\u00f6sung<\/th><\/tr><\/thead><tbody><tr><td>Interferenzen<\/td><td>Andere elektronische Ger\u00e4te k\u00f6nnen st\u00f6ren<\/td><\/tr><tr><td>Metall in der N\u00e4he<\/td><td>Metall abschirmt WLAN-Signale<\/td><\/tr><tr><td>Router-Konfiguration<\/td><td>Manche Router senden mit reduzierter Leistung<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">9. Erweiterungsm\u00f6glichkeiten<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Das Grundprojekt l\u00e4sst sich vielf\u00e4ltig erweitern:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">9.1 Hardware-Erweiterungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Buzzer hinzuf\u00fcgen<\/strong>\u00a0f\u00fcr akustischen Alarm bei schwachem Signal<\/li>\n\n\n\n<li><strong>RGB-LED<\/strong>\u00a0f\u00fcr visuelle Signalqualit\u00e4t (gr\u00fcn\/gelb\/rot)<\/li>\n\n\n\n<li><strong>Batteriebetrieb<\/strong>\u00a0mit Spannungsmessung und Deep-Sleep-Modus<\/li>\n\n\n\n<li><strong>Temperatur-\/Luftfeuchtigkeitssensor<\/strong>\u00a0zus\u00e4tzlich integrieren<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">9.2 Software-Erweiterungen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Signal-Historie<\/strong>\u00a0speichern und als Grafik anzeigen<\/li>\n\n\n\n<li><strong>E-Mail-Benachrichtigung<\/strong>\u00a0bei Alarm (dann br\u00e4uchte man aber Internet)<\/li>\n\n\n\n<li><strong>Mehrere Netzwerke<\/strong>\u00a0\u00fcberwachen (bis zu 5)<\/li>\n\n\n\n<li><strong>Datenlogger<\/strong>\u00a0mit SD-Karte oder Upload zu ThingSpeak<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">9.3 Geh\u00e4use-Ideen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>3D-gedrucktes Geh\u00e4use<\/strong>\u00a0mit Platz f\u00fcr Batterien<\/li>\n\n\n\n<li><strong>Modellbaukasten<\/strong>\u00a0(z.B. mit LEGO)<\/li>\n\n\n\n<li><strong>Aufputz-Geh\u00e4use<\/strong>\u00a0f\u00fcr die Hutschiene im Sicherungskasten<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">10. Hintergrundwissen f\u00fcr Fortgeschrittene<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Warum funktioniert das ohne Internet?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Der ESP8266 erstellt einen eigenen Access Point (WLAN-Hotspot). Das ist wie ein kleines eigenes Netzwerk, das nur aus dir und dem ESP besteht. Du verbindest dich direkt mit ihm, ohne dass ein Router n\u00f6tig ist.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Wie genau funktioniert der WLAN-Scan?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn&nbsp;<code>WiFi.scanNetworks()<\/code>&nbsp;aufgerufen wird, sendet der ESP8266 eine Anfrage an alle WLAN-Kan\u00e4le. Router in der N\u00e4he antworten mit ihrer SSID und ihrer Signalst\u00e4rke. Das ist vergleichbar mit einem Scanner, der Radiowellen abh\u00f6rt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Was bedeutet die Alarm-Schwelle?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">-70 dBm ist ein guter Wert, -80 dBm ist akzeptabel. Wenn du den Alarm auf -80 setzt, warnt dich das Ger\u00e4t, sobald eines der Netzwerke schw\u00e4cher als -80 dBm wird \u2013 das kann ein Hinweis auf St\u00f6rungen oder gro\u00dfe Entfernung sein.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Warum EEPROM und nicht normale Variablen?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Normale Variablen sind fl\u00fcchtig \u2013 bei Stromausfall sind sie weg. Der EEPROM (Electrically Erasable Programmable Read-Only Memory) beh\u00e4lt seine Daten auch ohne Strom. So bleiben deine Einstellungen erhalten, selbst wenn du das Ger\u00e4t vom Strom nimmst.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Du hast gerade ein vollwertiges IoT-Ger\u00e4t gebaut \u2013 von der Verkabelung \u00fcber die Programmierung bis zur Inbetriebnahme. Der WLAN-Signal-Monitor zeigt dir nicht nur die Empfangsqualit\u00e4t deiner Netzwerke, sondern hat auch ein eigenes Webinterface zur Konfiguration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dieses Projekt ist der perfekte Einstieg in die Welt des ESP8266, weil es:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Alle Grundlagen<\/strong>\u00a0abdeckt (Hardware, I2C, WLAN, WebServer)<\/li>\n\n\n\n<li><strong>Sofort nutzbare Ergebnisse<\/strong>\u00a0liefert<\/li>\n\n\n\n<li><strong>Erweiterbar<\/strong>\u00a0ist f\u00fcr eigene Ideen<\/li>\n\n\n\n<li><strong>Praktischen Nutzen<\/strong>\u00a0im Alltag hat<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Der Code ist bewusst ausf\u00fchrlich kommentiert, damit du jede Zeile verstehen und sp\u00e4ter anpassen kannst. Experimentiere ruhig mit den Einstellungen, \u00e4ndere die Display-Darstellung oder f\u00fcge eigene Funktionen hinzu \u2013 das ist der beste Weg, um zu lernen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Viel Spa\u00df mit deinem ersten eigenen IoT-Projekt!<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Quellen<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Offizielle Dokumentationen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ESP8266 Arduino Core<\/strong>:\u00a0<a href=\"https:\/\/github.com\/esp8266\/Arduino\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/esp8266\/Arduino<\/a><\/li>\n\n\n\n<li><strong>U8g2 Bibliothek<\/strong>:\u00a0<a href=\"https:\/\/github.com\/olikraus\/u8g2\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/olikraus\/u8g2<\/a><\/li>\n\n\n\n<li><strong>Arduino Reference<\/strong>:\u00a0<a href=\"https:\/\/www.arduino.cc\/reference\/de\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.arduino.cc\/reference\/de\/<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Fachb\u00fccher<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>&#8222;ESP8266: Programmierung und Anwendung&#8220;<\/em>\u00a0von Michael Wieland, Franzis Verlag 2019<\/li>\n\n\n\n<li>*&#8220;IoT-Projekte mit ESP8266&#8243;*\u00a0von Erik Bartmann, O&#8217;Reilly 2020<\/li>\n\n\n\n<li><em>&#8222;Handbuch Elektronik&#8220;<\/em>\u00a0von Rainer K\u00f6the, Carl Hanser Verlag 2018<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Online-Ressourcen<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Random Nerd Tutorials<\/strong>:\u00a0<a href=\"https:\/\/randomnerdtutorials.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/randomnerdtutorials.com<\/a><\/li>\n\n\n\n<li><strong>ESP8266 Community Forum<\/strong>:\u00a0<a href=\"https:\/\/www.esp8266.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.esp8266.com<\/a><\/li>\n\n\n\n<li><strong>Arduino Forum<\/strong>:\u00a0<a href=\"https:\/\/forum.arduino.cc\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/forum.arduino.cc<\/a><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ein Anf\u00e4nger-Projekt Schritt f\u00fcr Schritt erkl\u00e4rt Einleitung Dieses Projekt ist der ideale Einstieg in die Welt des ESP8266 und der IoT-Entwicklung. Wir bauen einen&nbsp;WLAN-Signal-Monitor, der dauerhaft die Empfangsst\u00e4rke zweier Netzwerke (z.B. FRITZI und SMU) auf einem OLED-Display anzeigt. Das Besondere: Das Ger\u00e4t arbeitet v\u00f6llig autonom, erstellt einen eigenen WLAN-Access Point und bietet ein Webinterface zur [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[40,18,46,47,26],"tags":[222,2237,3413,4932,5078,5978,7616,7819],"class_list":["post-2006","post","type-post","status-publish","format-standard","hentry","category-denkwerkzeuge","category-im-kopf-methoden-werkzeuge","category-industrie-4-0","category-maker-praxis","category-mit-den-handen","tag-access-point","tag-esp8266","tag-iot-anfangerprojekt","tag-nodemcu","tag-oled-display","tag-rssi-monitor","tag-webinterface","tag-wlan-signalstarke"],"_links":{"self":[{"href":"https:\/\/technodidact.de\/en\/wp-json\/wp\/v2\/posts\/2006","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/technodidact.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/technodidact.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/technodidact.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/technodidact.de\/en\/wp-json\/wp\/v2\/comments?post=2006"}],"version-history":[{"count":0,"href":"https:\/\/technodidact.de\/en\/wp-json\/wp\/v2\/posts\/2006\/revisions"}],"wp:attachment":[{"href":"https:\/\/technodidact.de\/en\/wp-json\/wp\/v2\/media?parent=2006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/technodidact.de\/en\/wp-json\/wp\/v2\/categories?post=2006"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/technodidact.de\/en\/wp-json\/wp\/v2\/tags?post=2006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}