sheen.bot-Logo

← Einblicke

Warum Ihre ESP32-Wetterstation nach 24 Stunden abstürzt (und wie Sie das beheben)

6. Okt. 2026·Sheen Robotics
Warum Ihre ESP32-Wetterstation nach 24 Stunden abstürzt (und wie Sie das beheben)

ESP32-IoT-Projekte an Schulen stürzen selten wegen defekter Hardware ab. Sie frieren aufgrund von dynamischer Heap-Speicherfragmentierung, blockierenden WLAN-Wiederverbindungsschleifen und nicht abgefangenen Hardware-Watchdogs ein.

Wenn die ESP32-Wetterstation in Ihrem Unterricht in der vierten Stunde auf der Werkbank noch einwandfrei läuft, am nächsten Morgen jedoch völlig tot ist, liegt das nicht an defektem Silizium. Mikrocontroller altern nicht innerhalb von vierundzwanzig Stunden. Stattdessen scheitert dauerhaft laufende Embedded-Software fast immer an zwei unauffälligen, kumulativen Problemen: Heap-Speicherfragmentierung durch dynamische Textoperationen und unbehandelten Netzwerkabbrüchen, die den Prozessor in einer unendlichen, blockierenden Schleife gefangen halten.

Um diese Probleme zu lösen, muss man sich von schnellen Prototyping-Abkürzungen verabschieden und bewährte Praktiken der Embedded-Entwicklung anwenden: Speicherpuffer mit fester Größe, nicht-blockierende Netzwerk-Zustandsautomaten (State Machines) und einen Hardware-Watchdog-Timer.

Ursache 1: Dynamische Strings und Heap-Fragmentierung

Der ESP32 verfügt über rund 320 KB nutzbaren internen SRAM. Bei einer Wetterstation, die Sensoren alle zehn Sekunden abfragt, reserviert, vergrößert und gibt Code, der mit der standardmäßigen Arduino-String-Klasse geschrieben wurde, tausende Male am Tag kleine Speicherblöcke frei:

// Das Muster, das Ihr Projekt unbemerkt lahmlegt:
String payload = "{\"temp\": ";
payload += String(temperature);
payload += ", \"humidity\": ";
payload += String(humidity);
payload += "}";
http.POST(payload);

Jedes Mal, wenn in loop() dynamische Strings erstellt und verkettet werden, reserviert die C++-Laufzeitumgebung Speicherplatz auf dem Heap. Da andere Systemhintergrund-Tasks (wie die WLAN- und Bluetooth-Stacks) gleichzeitig Speicher belegen, verwandelt dieses ständige Alloziieren und Freigeben den Heap in einen Schweizer Käse. Der gesamte freie Speicher wird vielleicht immer noch mit 150 KB angegeben, doch der größte zusammenhängende freie Block schrumpft auf wenige hundert Bytes zusammen. Wenn der WLAN-Stack oder der JSON-Serialisierer plötzlich einen zusammenhängenden 2-KB-Block für ein TCP-Paket anfordert, schlägt die Speicherzuweisung fehl und liefert einen Nullzeiger zurück, was eine stille Kernel-Panic oder einen unbehandelten Absturz auslöst.

Die Lösung: Puffer fester Größe auf dem Stack und snprintf nutzen. Mikrocontroller-Firmware sollte statische oder Stack-basierte Puffer reservieren, deren Größe bereits zur Kompilierzeit feststeht.

// Robuste Alternative ohne jegliche Heap-Allokation:
char payload[128];
snprintf(payload, sizeof(payload), 
         "{\"temp\":%.2f,\"humidity\":%.2f}", 
         temperature, humidity);
http.POST((uint8_t*)payload, strlen(payload));

Ursache 2: Die WLAN-Wiederverbindungsschleife im Schulnetz

In Schulumgebungen ist das WLAN selten statisch. Access Points erneuern Sicherheitsschlüssel, DHCP-Leases laufen ab und lokale Stromausfälle oder Lastabwurf-Umschaltungen (Load-Shedding) trennen kurzzeitig die vorgeschalteten Router, selbst wenn die IoT-Station über eine Batterie betrieben wird. Viele Einführungstutorials schlagen vor, die WLAN-Verbindung so wiederherzustellen:

if (WiFi.status() != WL_CONNECTED) {
  WiFi.reconnect();
  while (WiFi.status() != WL_CONNECTED) {
    delay(500); // Fatal: Blockiert den Prozessor auf unbestimmte Zeit
  }
}

Wenn der Router neu startet und zwei Minuten braucht, um das lokale Subnetz bereitzustellen, blockiert diese while-Schleife die Programmausführung. Da FreeRTOS den WLAN-Stack und Systemverwaltungsaufgaben über zwei Prozessorkerne verteilt ausführt, kann das Anhalten der Hauptschleife die Hintergrund-Watchdog-Tasks aushungern, was zu einem sofortigen Hardware-Reset oder einem dauerhaften Task-Lockup führt.

Die Lösung: Konnektivität als nicht-blockierenden Zustandsautomaten behandeln. Halten Sie die Programmausführung niemals an, um auf eine Verbindung zu warten. Wenn das WLAN ausfällt, protokollieren Sie die Daten lokal im Flash-Speicher oder auf einer SD-Karte und versuchen Sie die Verbindung in festen Intervallen erneut, ohne die Sensorabfragen zu stoppen.

Ursache 3: Fehlende Watchdog-Timer

Ganz gleich, wie sauber Ihr Code geschrieben ist: Außensensoren, Spannungsspitzen von Kompressoren in der Nähe oder nicht reagierende I2C-Busleitungen (insbesondere bei den allgegenwärtigen BME280- oder DHT22-Sensoren) können einen ESP32 in einen Hardware-Deadlock zwingen. Wenn ein Sensor die I2C-Taktleitung nicht freigibt, kann sich die standardmäßige Wire-Bibliothek für immer aufhängen.

Ein Task Watchdog Timer (TWDT) überwacht kritische Schleifen. Wenn die Hauptschleife den Watchdog innerhalb eines festgelegten Zeitfensters (z. B. 8 Sekunden) nicht „füttert“ bzw. zurücksetzt, löst der ESP32 automatisch einen Hard-Reset aus und nimmt den Betrieb ohne manuellen Eingriff wieder auf.

#include <esp_task_wdt.h>

#define WDT_TIMEOUT_SECONDS 8

void setup() {
  // Watchdog für ein Timeout von 8 Sekunden initialisieren
  esp_task_wdt_init(WDT_TIMEOUT_SECONDS, true);
  esp_task_wdt_add(NULL); // Aktuellen Thread registrieren
}

void loop() {
  // Watchdog-Timer in jedem Zyklus zurücksetzen
  esp_task_wdt_reset();

  readSensors();
  sendTelemetry();
  
  // Langes delay() vermeiden; nicht-blockierende millis()-Prüfungen nutzen
}

Ein Hinweis zur Spannungsstabilität

Bevor man von einem reinen Softwarefehler ausgeht, sollte die Spannungsversorgung der Hardware überprüft werden. Ein ESP32 zieht bei WLAN-Sendeimpulsen (HF-Kalibrierung und Paket-Bursts) kurze Stromspitzen von bis zu 350–500 mA. Wenn das Board über ein dünnes USB-Kabel an einem Laptop oder einem günstigen 5V-Steckernetzteil betrieben wird, führen Spannungseinbrüche unter die Brownout-Schwelle von 2,7 V dazu, dass der interne Brownout-Detektor einen abrupten Neustart auslöst.

  • Schließen Sie einen Elektrolytkondensator mit 100 µF bis 470 µF zwischen den Pins VIN und GND an, um vorübergehende Stromspitzen abzufangen.
  • Stellen Sie sicher, dass der Brownout-Detektor in Ihrem Framework aktiviert und nicht unterdrückt ist, da Unterspannung den internen Flash-Speicher beschädigen kann.

Wenn Sie praxistaugliche Messstationen für den naturwissenschaftlichen Unterricht oder das Schulgelände bauen, bietet unsere Lehrplanentwicklung bei Sheen IoT modulare Hardware-Frameworks und produktionsreife Firmware-Muster, die diese klassischen Fallstricke im Unterricht vermeiden.

#esp32#iot#Robotik#Fehlerbehebung#Programmieren

Mehr aus Einblicke