ESP32 Brownout Detector was triggered und Guru Meditation lösen
ESP32 Brownout Detector was triggered und ständige Neustarts: Netzteil, Kabel und Kondensator, rst-Codes, Guru Meditation, Task-WDT und Exception Decoder.
Die Meldung ESP32 Brownout Detector was triggered bedeutet, dass die Versorgungsspannung des Boards für einen Moment unter eine sichere Grenze gefallen ist und der Chip sich zum eigenen Schutz neu gestartet hat. Das Problem liegt fast nie im Code, sondern bei der Stromversorgung: ein schwacher USB-Port, ein dünnes und langes Kabel, ein zu kleiner Spannungsregler oder Servos und LED-Streifen, die an derselben Leitung wie der ESP32 hängen. Der zweite große Grund für ständige Neustarts sind Software-Abstürze; dann zeigt der serielle Monitor Zeilen wie Guru Meditation Error, task_wdt oder Stack canary.
Die gute Nachricht: Der ESP32 sagt dir selbst, warum er neu gestartet ist, du musst die Meldungen nur lesen können. In dieser Anleitung lernst du zuerst die rst-Codes in den Bootzeilen und die Fehlermeldungen kennen und behebst den Brownout dann dauerhaft mit Netzteil, Kabel und Kondensator. Danach geht es um Guru-Meditation-Fehler wie LoadProhibited und StoreProhibited, Stack-Überläufe, Nullzeiger und Watchdog-Timeouts, und du verfolgst einen Absturz mit dem ESP Exception Decoder bis zur Codezeile zurück. Zum Schluss schauen wir uns die Strapping-Pins (GPIO0, 2, 12 und 15) an, die den Bootvorgang stören können.

Warum startet der ESP32 ständig neu? Lies zuerst die Meldung
Bevor du mit der Fehlersuche beginnst, öffne den seriellen Monitor mit 115200 Baud und drücke die EN-Taste auf dem Board. Der ROM-Bootloader im ESP32 gibt bei jedem Start zuerst eine Datumszeile wie "ets Jun 8 2016 00:22:57" aus und danach eine Zeile wie rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT). Der rst-Teil verrät, warum das Board neu gestartet ist, der boot-Teil, in welchem Modus es startet. Hängt das Board in einer Schleife, findest du direkt über diesen Zeilen die Fehlermeldung, die letzten Worte des vorherigen Laufs. Die Tabelle fasst die Meldungen zusammen und zeigt, wo du ansetzen solltest:
| Was du im seriellen Monitor siehst | Bedeutung | Wo du suchen solltest |
|---|---|---|
| Brownout detector was triggered | Die Versorgungsspannung fiel unter die Schwelle | Netzteil, Kabel, Kondensator |
| Guru Meditation Error: Core 1 panic'ed (LoadProhibited) | Der Code wollte von einer ungültigen Adresse lesen | Nullzeiger, Array-Grenzen |
| Guru Meditation Error: Core 1 panic'ed (StoreProhibited) | Der Code wollte an eine ungültige Adresse schreiben | Nullzeiger, übergelaufener Puffer |
| Stack canary watchpoint triggered (loopTask) | Der Stack einer Task ist voll | Große lokale Arrays, Rekursion |
| task_wdt: Task watchdog got triggered | Eine Task hat die CPU länger als 5 Sekunden nicht freigegeben | Schleifen ohne Pausen, hängende Tasks |
| Interrupt wdt timeout on CPU0 / CPU1 | Ein Interrupt-Handler oder gesperrte Interrupts dauerten länger als 300 ms | Lange ISR, Serial in der ISR |
| boot:0x3 (DOWNLOAD_BOOT...) waiting for download | Das Board ist im Programmiermodus gestartet | GPIO0 beim Start LOW |
| invalid header oder flash read err | Der Flash-Speicher konnte nicht gelesen werden | GPIO12 beim Start HIGH, abgebrochener Upload |
Was bedeutet "Brownout detector was triggered" und woher kommt es?
Ein Brownout ist ein kurzer Spannungseinbruch ohne kompletten Stromausfall. Im ESP32 steckt ein Brownout-Detektor, der die Versorgung ständig überwacht; im Arduino-Core ist seine Schwelle auf die niedrigste Stufe gesetzt, etwa 2,43 V. Sobald die Spannung darunter fällt, schützt der Chip Funk und Flash-Speicher, schreibt "Brownout detector was triggered" in den seriellen Monitor und startet sich neu. Der Grund ist einfach: Bei zu niedriger Spannung kann der Flash falsch gelesen werden, gespeicherte Daten können beschädigt werden und die CPU kann zufällige Befehle ausführen. Der Detektor sorgt dafür, dass das Board sauber neu startet, statt sich unberechenbar zu verhalten. Das Modul ESP32-WROOM-32 ist für 3,0 bis 3,6 V ausgelegt; bei 2,43 V hat die Spannung den sicheren Bereich also längst verlassen.
Nach einer Brownout-Meldung zeigt die Bootzeile je nach Version des Arduino-Cores rst:0xc (SW_CPU_RESET) oder rst:0x3 (SW_RESET), weil der Interrupt des Detektors zuerst die Meldung ausgibt und den Chip dann per Software neu startet. Lass dich davon nicht täuschen: Derselbe Code vermerkt im Speicher des Chips, dass ein Brownout die Ursache war, und esp_reset_reason() liefert ESP_RST_BROWNOUT. Greift dagegen der eigene Brownout-Reset der Hardware, steht in der Zeile rst:0xf (RTCWDT_BROWN_OUT_RESET). In den 3.x-Cores, die auf ESP-IDF 5 basieren, ist diese Zeile zu einer Info-Logmeldung geworden (I BOD: Brownout detector was triggered). Weil die vorkompilierten Bibliotheken des Arduino-Cores nur Logs der Stufe Error ausgeben, erscheint die Meldung meist gar nicht und das Board startet stillschweigend neu; siehst du beim Booten ein unerklärliches rst:0x3 oder rst:0xc, prüfe den Reset-Grund mit dem Diagnose-Sketch weiter unten. Um zu verstehen, warum die Spannung einbricht, lohnt ein Blick auf den Stromverbrauch des ESP32:
| Betriebszustand | Typischer Strom (ESP32-Chip) |
|---|---|
| Deep Sleep (RTC-Timer aktiv) | Etwa 10 µA |
| Light Sleep | Etwa 0,8 mA |
| WLAN aus, CPU mit 240 MHz | 30–68 mA |
| WLAN empfangen (RX) | 95–100 mA |
| WLAN senden, 802.11b, 19,5 dBm | Etwa 240 mA |
| Funkkalibrierung beim Start und Verbindungsaufbau | Kann in Spitzen von wenigen Mikrosekunden 400 mA übersteigen |
Dieser Unterschied ist der Kern des Brownout-Problems: Bis dein Code das WLAN einschaltet, läuft das Board ruhig mit etwa 50 mA, doch in der Zeile WiFi.begin() springt der Strom innerhalb weniger Mikrosekunden auf das Fünf- bis Sechsfache. Kommen Netzteil, Kabel und Regler dieser plötzlichen Anforderung nicht hinterher, bricht die Spannung ein. Deshalb empfiehlt Espressif für den ESP32 ein Netzteil, das mindestens 500 mA liefern kann. Das Symptom kennst du bestimmt: Das Board startet, schreibt ein paar Zeilen in den seriellen Monitor, setzt sich zurück, sobald WLAN oder Bluetooth anlaufen, und das wiederholt sich endlos. Dasselbe kann passieren, wenn sich ein Servo bewegt, ein Relais schaltet oder ein LED-Streifen auf Weiß geht.
Die häufigsten Ursachen für einen Brownout
- Dünnes oder langes USB-Kabel: Die dünnen Stromadern billiger Kabel kommen hin und zurück auf bis zu 0,5 Ω. Nach dem ohmschen Gesetz kostet eine Spitze von 400 mA in so einem Kabel 0,2 V.
- Schwacher USB-Port oder Hub: Ports an Tastaturen und Monitoren, passive Hubs und die Frontanschlüsse mancher Laptops lassen die Spannung bei Stromspitzen absacken.
- Dropout des Spannungsreglers: Der AMS1117 auf den meisten Boards braucht 1,0–1,3 V Differenz zwischen Ein- und Ausgang. Fällt die Spannung am 5V-Pin unter etwa 4,3 V, kann der Ausgang die 3,3 V nicht halten.
- Akku direkt anschließen: Ein 3,7-V-Li-Ion-Akku am 5V-Pin drückt den Ausgang wegen des Dropouts unter 3 V; zwei AA-Batterien fallen unter Last schnell unter die Mindestspannung des ESP32.
- Der 3.3V-Pin des Arduino Uno: Aus diesem Pin sollten nur etwa 50 mA entnommen werden; für einen ESP32 mit aktivem WLAN reicht das bei Weitem nicht.
- Verbraucher an derselben Leitung: Hängen Servos, Relais, Summer, DC-Motoren oder ein WS2812B-Streifen an denselben 5 V wie der ESP32, zieht jede Bewegung die Spannung nach unten.
- Breadboard und Jumper-Kabel: Wackelige Kontakte und dünne Jumper fügen an jeder Verbindung etwas Widerstand hinzu; die Versorgung über das Breadboard zu führen, verschlimmert das Problem.
- ESP32-CAM: Laufen Kamera, WLAN und Blitz-LED gleichzeitig, steigt der Strom stark an; dieses Board braucht 5 V und mindestens 2 A. Mehr dazu im Artikel ESP32-CAM.
Lösung 1: Netzteil und Kabel verbessern
Der erste und wirksamste Schritt ist eine stärkere Versorgung. Schließe das Board mit einem kurzen, dicken Datenkabel, von dem du weißt, dass es gut ist, direkt an einen USB-Port auf der Rückseite deines Computers oder an ein 5-V-Netzteil mit mindestens 1 A an. USB-2.0-Ports sind für 500 mA ausgelegt, USB-3.0-Ports für 900 mA; die von Espressif empfohlenen 500 mA liegen genau an der Grenze eines USB-2.0-Ports, und mit den Kabelverlusten beginnt der Ärger. Behebt schon ein anderes Kabel den Fehler, war sehr wahrscheinlich der Kabelwiderstand schuld. Wie viel Spannung ein Kabel kostet, rechnest du mit V = I × R im Werkzeug Ohmsches Gesetz aus.

| Versorgung | Brownout-Risiko | Hinweis |
|---|---|---|
| Kurzes, dickes Kabel und USB-Port auf der Rückseite | Gering | Die einfachste Lösung beim Entwickeln |
| Langes, dünnes Kabel, Frontanschluss oder Hub | Hoch | Der Kabelwiderstand lässt die Spannung bei Stromspitzen einbrechen |
| 5-V-Netzteil mit mindestens 1 A am 5V- oder VIN-Pin | Gering | Empfohlen für dauerhafte Projekte |
| Fertige 3,3-V-Quelle direkt am 3V3-Pin | Abhängig von der Quelle | Muss mindestens 500 mA liefern und darf 3,6 V nie überschreiten |
| 3,7-V-Li-Ion-Akku über den AMS1117 | Hoch | Fällt der Akku unter etwa 4 V, sinkt der Ausgang unter 3 V |
| Li-Ion-Akku mit Low-Dropout-Regler (LDO) für 3,3 V oder Buck-Boost | Gering | Liefert auch bei sinkender Akkuspannung stabile 3,3 V |
| Zwei AA-Batterien direkt am 3V3-Pin | Sehr hoch | Unter Last fällt die Spannung schnell unter die Mindestspannung des ESP32 |
Bei Akkuprojekten musst du besonders aufpassen. Eine Li-Ion-Zelle wie die 18650 liefert voll geladen 4,2 V und leer etwa 3,0 V. Dieser Bereich passt weder direkt an den 3V3-Pin (4,2 V überschreiten die Grenze von 3,6 V) noch an den 5V-Pin mit seinem AMS1117. Richtig ist entweder, den Akku über ein 5-V-Step-up-Modul (Boost) an den 5V-Pin zu geben, oder die 3V3-Leitung direkt über einen Low-Dropout-Regler mit mindestens 500 mA (zum Beispiel ME6211 oder HT7833) und einen Kondensator zu versorgen. Wie lange dein Projekt mit einem Akku durchhält, berechnest du mit dem Werkzeug Akkulaufzeit; die Ladeschaltung erklärt der Artikel TP4056-Lademodul.
Lösung 2: Kondensator zwischen 3V3 und GND
Ein Kondensator wirkt wie ein kleiner Speicher, der bei einer Stromspitze selbst Energie liefert, bis Regler und Kabel nachkommen. Setze zwischen die Pins 3V3 und GND, möglichst nah am Board, einen Elektrolytkondensator mit 100–470 µF und daneben einen Keramikkondensator mit 100 nF. Der Elko fängt Einbrüche im Millisekundenbereich ab, der Keramikkondensator sehr kurze, hochfrequente Schwankungen. Die Wirkung siehst du grob mit ΔV = I × Δt / C: Selbst wenn ein 470-µF-Kondensator allein 200 µs lang zusätzliche 200 mA liefert, sinkt die Spannung nur um 0,085 V. Die Aufschrift 104 auf einem Keramikkondensator bedeutet 100 nF; andere Codes entschlüsselst du mit dem Werkzeug Kondensator-Code.

Lösung 3: Servos, Motoren und LED-Streifen getrennt versorgen
Auch wenn der ESP32 selbst richtig versorgt ist, können Verbraucher an derselben Leitung die Spannung nach unten ziehen. Schon ein kleiner Servo wie der SG90 zieht beim Anlaufen einige hundert mA; eine WS2812B-LED verbraucht bei vollem Weiß etwa 60 mA, ein Streifen mit 30 LEDs kommt also auf bis zu 1,8 A. Versorge diese Verbraucher nicht über den 5V- oder 3V3-Pin des ESP32, sondern aus einer eigenen 5-V-Quelle; zum Beispiel kannst du ein 12-V-Netzteil mit einem LM2596-Step-down-Modul auf 5 V bringen. Die wichtigste Regel: Verbinde die GND-Anschlüsse beider Quellen miteinander; ohne gemeinsame Masse hat die Signalleitung keinen Bezug, und Servo oder Streifen verhalten sich zufällig. Ausführlich behandeln wir das in Arduino startet ständig neu? und GND und gemeinsame Masse.

Ist das Abschalten des Brownout-Detektors eine Lösung?
Die im Netz am häufigsten empfohlene "Lösung" ist, den Detektor mit einer einzigen Zeile abzuschalten. Der folgende Code deaktiviert den Detektor, indem er das Brownout-Register des ESP32 auf null setzt, und die Fehlermeldung verschwindet. Die Spannungseinbrüche bleiben aber; es warnt dich nur niemand mehr. Nutze diesen Code nur zur Diagnose: Läuft das Board mit abgeschaltetem Detektor problemlos, hast du bestätigt, dass das Problem eindeutig an der Versorgung liegt. Danach löschst du die Zeile wieder und reparierst die Versorgung.
1#include "soc/soc.h"
2#include "soc/rtc_cntl_reg.h"
3
4void setup() {
5 // YALNIZ TEŞHİS İÇİN: brownout dedektörünü kapat / DIAGNOSIS ONLY: disable the brownout detector
6 WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
7
8 Serial.begin(115200);
9 Serial.println("Brownout dedektoru kapali / brownout detector disabled");
10}
11
12void loop() {
13}rst-Codes: Der ESP32 verrät, warum er neu gestartet ist
Der rst:-Wert, den das ROM bei jedem Start ausgibt, zeigt, wie der vorherige Lauf geendet hat. Bei einem normalen Start ist der boot-Wert 0x13 (SPI_FAST_FLASH_BOOT), das Board startet sein Programm also aus dem Flash. Die Tabelle fasst die häufigsten Codes zusammen. ROM-Codes allein reichen nicht immer: ESP.restart() und ein Neustart nach einer Guru Meditation erscheinen beide als 0xc, ein Brownout je nach Core-Version als 0xc oder 0x3. Um sie zu unterscheiden, nutze den Sketch mit esp_reset_reason() im nächsten Abschnitt.
| rst-Code | Name | Bedeutung |
|---|---|---|
| 0x1 | POWERON_RESET | Erstmals Strom angelegt oder EN-Taste gedrückt |
| 0x3 | SW_RESET | Die Software hat das gesamte digitale System zurückgesetzt; neuere Core-Versionen zeigen das auch nach einem Brownout |
| 0x5 | DEEPSLEEP_RESET | Das Board ist aus dem Deep Sleep aufgewacht (normal) |
| 0x7 / 0x8 | TG0WDT_SYS_RESET / TG1WDT_SYS_RESET | Ein Timer-Group-Watchdog hat das System per Hardware zurückgesetzt; Interrupts waren zu lange gesperrt oder selbst der Panic-Handler konnte nicht laufen |
| 0x9 | RTCWDT_SYS_RESET | Der RTC-Watchdog hat den Digitalkern zurückgesetzt |
| 0xc | SW_CPU_RESET | Neustart per Software: ESP.restart(), nach einer Guru Meditation oder nach einem Brownout im Arduino-Core |
| 0xf | RTCWDT_BROWN_OUT_RESET | Brownout-Reset der Hardware: instabile Versorgungsspannung |
| 0x10 | RTCWDT_RTC_RESET | Der RTC-Watchdog hat den ganzen Chip samt RTC zurückgesetzt; meist bei Boards, die beim Start hängen |
Diagnose-Sketch: Reset-Grund, Speicher und Stack ausgeben
Lade den folgenden Code als eigenen Sketch hoch oder übernimm seine Zeilen in setup() und loop() deines Problemprojekts. Bei jedem Start schreibt das Board den Reset-Grund als lesbaren Text, die Anzahl der Starts und den Speicherzustand in den seriellen Monitor. Der mit RTC_DATA_ATTR markierte Zähler liegt im RTC-Speicher und übersteht daher Software-Resets und Deep Sleep; er wird erst gelöscht, wenn der Strom komplett weg ist. Steigt der Zähler alle paar Sekunden, weißt du sofort, dass das Board in einer Reset-Schleife steckt.
1#include <esp_system.h>
2
3RTC_DATA_ATTR uint32_t bootCount = 0; // yazılım resetinde korunur / survives software resets
4
5// Reset nedenini okunabilir yazıya çevir / turn the reset reason into readable text
6const char* reasonText(esp_reset_reason_t r) {
7 switch (r) {
8 case ESP_RST_POWERON: return "POWERON: guc acilisi ya da EN / power-on or EN button";
9 case ESP_RST_SW: return "SW: ESP.restart()";
10 case ESP_RST_PANIC: return "PANIC: Guru Meditation";
11 case ESP_RST_INT_WDT: return "INT_WDT: kesme watchdog'u / interrupt watchdog";
12 case ESP_RST_TASK_WDT: return "TASK_WDT: gorev watchdog'u / task watchdog";
13 case ESP_RST_WDT: return "WDT: diger watchdog / other watchdog";
14 case ESP_RST_DEEPSLEEP: return "DEEPSLEEP: derin uykudan uyanma / deep sleep wake-up";
15 case ESP_RST_BROWNOUT: return "BROWNOUT: gerilim dusmesi / supply voltage dropped";
16 default: return "UNKNOWN: bilinmiyor / unknown";
17 }
18}
19
20void setup() {
21 Serial.begin(115200);
22 delay(1000); // Seri Monitör'ün açılmasını bekle / wait for the Serial Monitor
23 bootCount++;
24 Serial.printf("Acilis sayisi / boot count: %u\n", (unsigned)bootCount);
25 Serial.printf("Reset nedeni / reset reason: %s\n", reasonText(esp_reset_reason()));
26}
27
28void loop() {
29 // Bellek durumu / memory status
30 Serial.printf("Bos heap / free heap: %u B, en dusuk / minimum: %u B, en buyuk blok / largest block: %u B\n",
31 (unsigned)ESP.getFreeHeap(), (unsigned)ESP.getMinFreeHeap(), (unsigned)ESP.getMaxAllocHeap());
32 // loopTask yığınında hiç kullanılmamış en küçük alan / smallest unused space on the loopTask stack
33 Serial.printf("loopTask bos yigin / free stack: %u B\n", (unsigned)uxTaskGetStackHighWaterMark(NULL));
34 delay(5000);
35}Die Werte, die der Code in der Schleife ausgibt, decken auch stille Probleme auf. Sinkt der freie Heap bei jedem Durchlauf ein wenig, hat dein Programm ein Speicherleck, und das Board wird früher oder später abstürzen. Ist der größte Block viel kleiner als der freie Heap, ist der Speicher fragmentiert; das kommt meist von String-Objekten, die in der Schleife ständig wachsen und schrumpfen. Fällt der freie Stack von loopTask unter ein paar hundert Bytes, steht ein Stack-Überlauf vor der Tür. Lautet der Reset-Grund BROWNOUT, konzentriere dich auf die Abschnitte zur Versorgung; bei PANIC, TASK_WDT oder INT_WDT auf die Software-Abschnitte weiter unten.
Was ist ein Guru Meditation Error? Die Absturzmeldung Zeile für Zeile lesen
Ein Guru Meditation Error ist der Absturzbericht, den der Panic-Handler ausgibt, wenn die CPU des ESP32 auf einen Fehler stößt, von dem sie sich nicht erholen kann; der Name stammt vom Fehlerbildschirm alter Amiga-Computer. Der Bericht sieht zuerst bedrohlich aus, aber nur wenige Zeilen sind wichtig. Core 1 sagt dir, auf welchem Kern der Fehler auftrat: Bei Arduino laufen setup() und loop() auf Kern 1, der WLAN-Stack auf Kern 0. Der Name in Klammern ist die Art der Ausnahme. Am Ende des Berichts schreibt das Board "Rebooting..." und startet neu; in der Bootzeile siehst du rst:0xc.
| Zeile | Bedeutung |
|---|---|
| Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. | Code auf Kern 1 wollte von einer ungültigen Adresse lesen, und der Fehler wurde nicht abgefangen |
| PC : 0x400d1a2c | Adresse des Befehls, bei dem es abstürzte; beginnt sie mit 0x400d, lief dein Code oder eine Bibliothek aus dem Flash |
| EXCCAUSE: 0x0000001c | Ausnahmecode; 0x1c, also 28, bedeutet LoadProhibited |
| EXCVADDR: 0x00000000 | Die angesprochene Adresse; 0 oder eine sehr kleine Zahl deutet auf einen Nullzeiger hin |
| Backtrace: 0x400d1a29:0x3ffb2270 0x400d0f6e:0x3ffb2290 ... | Aufrufkette; jedes Paar hat die Form PC:SP und wird mit dem Decoder in eine Codezeile übersetzt |
| ELF file SHA256: ... | Fingerabdruck des abgestürzten Programms; der Decoder braucht genau denselben Build |
| Rebooting... | Der Panic-Handler startet den Chip per Software neu |
LoadProhibited, StoreProhibited und andere Ausnahmetypen
| Ausnahme | EXCCAUSE | Was ist passiert? | Häufige Ursache |
|---|---|---|---|
| LoadProhibited | 28 (0x1c) | Lesen von einer ungültigen Adresse | Nullzeiger oder nicht initialisierter Zeiger, gelöschtes Objekt |
| StoreProhibited | 29 (0x1d) | Schreiben an eine ungültige Adresse | Schreiben über einen Nullzeiger, Puffer über die Array-Grenze hinaus |
| InstrFetchProhibited | 20 (0x14) | Befehl von ungültiger Adresse geholt | Nicht zugewiesener Funktionszeiger oder Callback |
| IllegalInstruction | 0 (0x0) | Ungültiger Befehl | Beschädigter Stack, fehlendes return in einer Funktion mit Rückgabewert |
| LoadStoreAlignment | 9 (0x9) | Nicht ausgerichteter Speicherzugriff | Byte-Array in einen Typ wie uint32_t* umgewandelt |
| IntegerDivideByZero | 6 (0x6) | Ganzzahl durch null geteilt | Division durch einen Zähler, der null sein kann |
| Unhandled debug exception | - | Debug-Ausnahme | Stack canary watchpoint triggered: Stack-Überlauf |
| Interrupt wdt timeout on CPU0/CPU1 | - | Interrupt-Watchdog abgelaufen | Lange ISR, Serial oder delay in der ISR |
| Cache disabled but cached memory region accessed | - | Zugriff auf Code im Flash, während der Flash belegt war | Interrupt-Handler ohne IRAM_ATTR |
Der häufigste dieser Fehler ist ein Nullzeiger. NULL ist die Adresse 0, und beim ESP32 gibt es rund um Adresse 0 keinen lesbaren Speicher; Lesen an der Stelle, auf die ein leerer Zeiger zeigt, ergibt deshalb LoadProhibited, Schreiben StoreProhibited. EXCVADDR ist dabei ein perfekter Hinweis: 0x00000000 steht für den Zeiger selbst, kleine Werte wie 0x00000004 oder 0x00000010 für ein Feld innerhalb eines leeren Zeigers (NULL plus Offset des Feldes). In Arduino-Projekten ist die häufigste Ursache eine Funktion, die NULL für "nicht gefunden" zurückgibt, und dieser Wert wird ohne Prüfung benutzt. Im folgenden Beispiel liefert strstr() NULL, wenn der gesuchte Text fehlt; ohne Prüfung stürzt das Board mit EXCVADDR 0x00000005 ab.
1const char* response = "temp=23.5;hum=40"; // sunucudan gelen yanıt / reply from a server
2
3void setup() {
4 Serial.begin(115200);
5 delay(500);
6
7 // YANLIŞ: "pres=" yoksa strstr NULL döner ve kart çöker (EXCVADDR 0x00000005)
8 // WRONG: if "pres=" is missing strstr returns NULL and the board crashes (EXCVADDR 0x00000005)
9 // float pressure = atof(strstr(response, "pres=") + 5);
10
11 // DOĞRU: işaretçiyi kullanmadan önce NULL kontrolü yap / RIGHT: check for NULL before using the pointer
12 const char* found = strstr(response, "pres=");
13 if (found != nullptr) {
14 float pressure = atof(found + 5);
15 Serial.println(pressure);
16 } else {
17 Serial.println("pres alani bulunamadi / pres field not found");
18 }
19}
20
21void loop() {
22}Stack-Überlauf: der Fehler "Stack canary watchpoint triggered"
Beim ESP32 hat jede Task einen Stack fester Größe, in dem lokale Variablen, Funktionsaufrufe und Rücksprungadressen liegen. Bei Arduino hat die loopTask, die setup() und loop() ausführt, einen Stack von 8192 Bytes. Ein lokales Array mit 10.000 Bytes in loop(), eine Funktion, die sich selbst aufruft (Rekursion), oder eine Bibliotheksfunktion mit vielen lokalen Variablen sprengt diese Grenze. Am Ende des Stacks liegt ein Wächterbereich (Canary); erreicht der Stack ihn, schreibt das Board Guru Meditation Error: Core 1 panic'ed (Unhandled debug exception) und direkt darunter Debug exception reason: Stack canary watchpoint triggered (loopTask). Der Name in Klammern ist die Task, deren Stack übergelaufen ist. Manchmal zeigt sich dasselbe Problem auch als ***ERROR*** A stack overflow in task loopTask has been detected. So behebst du es:
- Große Arrays vom Stack holen: Deklariere das Array global oder schreibe static davor; dann liegt es im festen RAM statt auf dem Stack.
- Den Stack von loopTask vergrößern: Mit SET_LOOP_TASK_STACK_SIZE(16 * 1024); ganz oben im Sketch vergrößerst du den Stack von loop() auf 16 KB.
- Eigenen Tasks genug Platz geben: Beim ESP32 wird die Stackgröße für xTaskCreate und xTaskCreatePinnedToCore in Bytes angegeben, nicht in Words wie bei FreeRTOS auf anderen Plattformen. 1024 Bytes sind selbst für eine Task mit Serial.printf zu wenig; fang mit 4096 an.
- Messen: uxTaskGetStackHighWaterMark(NULL) liefert in Bytes den kleinsten Teil des Stacks, den die Task bisher nie benutzt hat; fällt der Wert unter ein paar hundert Bytes, vergrößere den Stack.
- Rekursion vermeiden: Wandle Funktionen, die sich selbst aufrufen, in Schleifen um oder begrenze ihre Tiefe.
Task-Watchdog: der Fehler "task_wdt: Task watchdog got triggered"
Ein Watchdog ist ein Timer, der ein hängendes Programm bemerkt und das Board rettet. Der Task-Watchdog (Task WDT) des ESP32 erwartet, dass die bei ihm angemeldeten Tasks in regelmäßigen Abständen "ich lebe noch" melden. Im Arduino-Core überwacht er standardmäßig die Leerlauf-Task (IDLE) von Kern 0, mit einer Zeit von 5 Sekunden. Gibt eine Task auf Kern 0 die CPU 5 Sekunden lang nicht frei, kann die IDLE-Task nicht laufen, und im seriellen Monitor erscheint eine Meldung, die mit E (10257) task_wdt: Task watchdog got triggered. beginnt. Danach folgen die Liste der Tasks, die den Watchdog nicht rechtzeitig zurückgesetzt haben (meist - IDLE (CPU 0)), und unter Tasks currently running: die gerade laufenden Tasks. Im Arduino-Core löst das mit der Zeile task_wdt: Aborting. eine Panic aus, und das Board startet neu.
Die häufigsten Ursachen sind: eine mit xTaskCreatePinnedToCore auf Kern 0 gelegte Schleife ohne ein einziges vTaskDelay(), eine while-Schleife, die ohne Timeout auf die Antwort eines Sensors wartet, oder delay() und lange Operationen in den Callbacks von Bibliotheken wie AsyncWebServer. Im letzten Fall siehst du in der Liste statt IDLE die Task async_tcp. Die Lösung: lange Aufgaben in kleine Stücke aufteilen und in Schleifen kurze Pausen wie vTaskDelay(1) einbauen. loop() selbst wird standardmäßig nicht überwacht; wenn du willst, rufst du in setup() enableLoopWDT() auf, damit das Board auch neu startet, wenn loop() länger als 5 Sekunden hängt. Den Watchdog mit disableCore0WDT() abzuschalten, versteckt den Fehler, repariert aber den hängenden Code nicht. Mehr über Tasks und Kerne findest du in ESP32 FreeRTOS und Dual-Core. Der folgende Code zeigt eine saubere Task-Struktur und die Vorkehrungen gegen einen Stack-Überlauf:
1SET_LOOP_TASK_STACK_SIZE(16 * 1024); // loop() yığını 8 KB yerine 16 KB / loop() stack 16 KB instead of 8 KB
2
3volatile uint32_t sampleCount = 0;
4
5// 0. çekirdekte çalışan görev / task running on core 0
6void sensorTask(void* parameter) {
7 for (;;) {
8 sampleCount = sampleCount + 1; // sensörünü burada oku / read your sensor here
9 vTaskDelay(pdMS_TO_TICKS(10)); // IDLE görevine sıra ver, task_wdt tetiklenmez / let IDLE run, no task_wdt
10 }
11}
12
13void setup() {
14 Serial.begin(115200);
15 // Yığın boyutu bayt cinsindendir: 4096 bayt / stack size is in bytes: 4096 bytes
16 xTaskCreatePinnedToCore(sensorTask, "sensorTask", 4096, NULL, 1, NULL, 0);
17}
18
19void loop() {
20 static uint8_t buffer[10000]; // static: yığında değil kalıcı RAM'de / static: in RAM, not on the stack
21 memset(buffer, 0, sizeof(buffer));
22
23 Serial.printf("Ornek / samples: %u, loopTask bos yigin / free stack: %u B\n",
24 (unsigned)sampleCount, (unsigned)uxTaskGetStackHighWaterMark(NULL));
25 delay(1000);
26}Interrupt wdt timeout und IRAM_ATTR: Abstürze in Interrupts
Der Interrupt-Watchdog (Interrupt WDT) ist viel ungeduldiger: Braucht ein Interrupt-Handler (ISR) oder ein Codeabschnitt mit gesperrten Interrupts länger als 300 ms, stürzt das Board mit Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1) ab. Serial.print, delay(), I2C oder WLAN-Funktionen in einer ISR sind die häufigste Ursache. Eine weitere Falle ist der Flash: Während Preferences, EEPROM oder LittleFS in den Flash schreiben, ist der Flash-Cache für einen Moment abgeschaltet. Kommt in dieser Zeit ein Interrupt und liegt sein Handler im Flash, meldet das Board Cache disabled but cached memory region accessed. Die Lösung: ISRs mit IRAM_ATTR markieren, damit sie im RAM liegen, und darin nur ein Flag setzen; die eigentliche Arbeit erledigt loop(). Variablen, die ISR und loop() teilen, müssen volatile sein.
1const int BUTTON_PIN = 27; // buton GPIO 27 ile GND arasında / button between GPIO 27 and GND
2volatile bool buttonPressed = false; // ISR ile loop arasında paylaşılan bayrak / flag shared by the ISR and loop
3uint32_t pressCount = 0;
4
5void IRAM_ATTR onButton() { // IRAM_ATTR: fonksiyon flaşta değil RAM'de durur / the function lives in RAM, not flash
6 buttonPressed = true; // yalnızca bayrak kaldır, Serial yok / only set a flag, no Serial
7}
8
9void setup() {
10 Serial.begin(115200);
11 pinMode(BUTTON_PIN, INPUT_PULLUP);
12 attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), onButton, FALLING);
13}
14
15void loop() {
16 if (buttonPressed) {
17 buttonPressed = false;
18 pressCount++;
19 Serial.printf("Butona basildi / button pressed: %u\n", (unsigned)pressCount); // yavaş iş burada / slow work here
20 }
21}Backtrace mit dem ESP Exception Decoder in eine Codezeile übersetzen
Die Adressen in der Backtrace-Zeile sagen allein nichts; das Werkzeug, das sie in Datei, Funktion und Zeilennummer deines Quellcodes übersetzt, heißt ESP Exception Decoder. In der alten Arduino IDE 1.8 war es ein Plugin im Menü Werkzeuge. In der Arduino IDE 2 nutzt du eine gleichnamige Erweiterung aus der Community:
- Lade die Datei mit der Endung .vsix aus dem Bereich Releases des Projekts dankeboy36/esp-exception-decoder auf GitHub herunter. Wähle für die Arduino IDE 2 eine 1.x-Version; die neueren 2.x-Versionen sind für VS Code gedacht.
- Schließe die Arduino IDE und kopiere die Datei unter Windows nach %UserProfile%\.arduinoIDE\plugins, unter macOS und Linux nach ~/.arduinoIDE/plugins; lege den Ordner an, falls er fehlt.
- Öffne die IDE und den abstürzenden Sketch, kompiliere ihn mit Überprüfen und lade ihn auf das Board.
- Öffne den seriellen Monitor und warte, bis der Absturz erneut auftritt.
- Öffne mit Strg+Umschalt+P (unter macOS Cmd+Shift+P) die Befehlspalette und führe ESP Exception Decoder: Show Decoder Terminal aus.
- Kopiere den Guru-Meditation-Block samt Backtrace-Zeile aus dem seriellen Monitor und füge ihn in das geöffnete Terminal ein; das Werkzeug zeigt zu jeder Adresse Dateiname, Funktion und Zeilennummer.
Kannst du die Erweiterung nicht installieren, geht es auch von Hand. Das Menü Sketch > Export Compiled Binary legt im build-Ordner innerhalb deines Sketch-Ordners eine Datei mit der Endung .elf ab. Der Befehl xtensa-esp32-elf-addr2line -pfiaC -e sketch.ino.elf 0x400d1a29 0x400d0f6e aus der ESP32-Toolchain übersetzt diese Adressen in Funktionsnamen und Zeilennummern. Mit PlatformIO genügt die Zeile monitor_filters = esp32_exception_decoder in der platformio.ini; die Absturzmeldung wird dann im seriellen Monitor automatisch entschlüsselt.
Strapping-Pins: Wie GPIO0, GPIO2, GPIO12 und GPIO15 den Start stören
Beim Start liest der ESP32 den Pegel bestimmter Pins, um zu entscheiden, wie er bootet. Diese Pins heißen Strapping-Pins, und nur ihr Pegel im Moment des Resets zählt; nach dem Start kannst du sie wie normale GPIOs nutzen. Das Problem entsteht, wenn ein angeschlossener Sensor, Taster oder ein Modul den Pin beim Start auf den falschen Pegel zieht. Dann startet das Board sein Programm gar nicht, geht in den Programmiermodus oder kann den Flash nicht lesen; von außen sieht auch das aus wie "der ESP32 startet nicht" oder "er setzt sich ständig zurück". Die vollständige Pinbelegung deines Boards findest du im Werkzeug Pinout.
| Pin | Interner Widerstand | Aufgabe beim Start | Was passiert beim falschen Pegel? |
|---|---|---|---|
| GPIO0 | Pull-up | LOW wählt den Programmiermodus (Download), HIGH den normalen Start | boot:0x3 (DOWNLOAD_BOOT) und waiting for download; das Programm läuft nicht |
| GPIO2 | Pull-down | Muss für den Programmiermodus LOW oder offen sein; beim normalen Start egal | Eine Schaltung, die ihn auf HIGH zieht, verhindert den Upload |
| GPIO12 (MTDI) | Pull-down | Wählt die Versorgungsspannung des Flash: LOW 3,3 V, HIGH 1,8 V | Bei HIGH wird ein 3,3-V-Flash nicht richtig versorgt; das Board startet nicht oder hängt in einer Reset-Schleife |
| GPIO15 (MTDO) | Pull-up | LOW unterdrückt die Bootmeldungen des ROM | Im seriellen Monitor fehlen die Bootzeilen, die Diagnose wird schwerer |
| GPIO5 | Pull-up | Legt das SDIO-Timing fest | Macht auf Entwicklungsboards selten Probleme |
Neuere Boards haben andere Strapping-Pins: Beim ESP32-S3 beeinflussen GPIO0, GPIO3, GPIO45 und GPIO46 den Start, beim ESP32-C3 GPIO2, GPIO8 und GPIO9. Der ESP32-S3 verwendet dieselben Xtensa-Ausnahmenamen wie der klassische ESP32. Beim ESP32-C3 mit RISC-V-Kern siehst du dagegen Load access fault statt LoadProhibited und Store access fault statt StoreProhibited, und das Register MTVAL übernimmt die Rolle von EXCVADDR. Die Brownout-Meldung ist bei allen Modellen gleich.
ESP32 und Raspberry Pi Pico mit MicroPython
Programmierst du den ESP32 mit MicroPython, tritt der Brownout genauso auf, denn das Problem steckt in der Hardware, nicht in der Software. Fehler im Python-Code erscheinen dagegen als lesbarer Traceback statt als Guru Meditation, und das Board stürzt nur selten ab. Den Reset-Grund liest du mit machine.reset_cause(), aber Vorsicht: Die ESP32-Version von MicroPython liefert für einen Brownout keinen eigenen Wert, sondern meldet ihn zusammen mit dem Einschalten als PWRON_RESET. Startet das Board ständig mit PWRON_RESET, obwohl du es nicht angefasst hast, verdächtige wieder die Versorgung. Der folgende Code ist für den ESP32; beim Raspberry Pi Pico kennt das machine-Modul weniger Reset-Arten. Beim Pico arbeitet der Buck-Boost-Regler am VSYS-Eingang mit allem zwischen 1,8 und 5,5 V, daher sind Brownout-Probleme viel seltener; mehr zum Board in Was ist der Raspberry Pi Pico?
1import machine, gc, time
2
3# Reset nedenleri (ESP32 için) / reset causes (for ESP32)
4causes = {
5 machine.PWRON_RESET: "PWRON: guc acilisi ya da brownout / power-on or brownout",
6 machine.HARD_RESET: "HARD: cokme ya da machine.reset() / crash or machine.reset()",
7 machine.WDT_RESET: "WDT: watchdog",
8 machine.DEEPSLEEP_RESET: "DEEPSLEEP: derin uykudan uyanma / deep sleep wake-up",
9 machine.SOFT_RESET: "SOFT: Ctrl+D ile yazilim reseti / soft reset with Ctrl+D",
10}
11print("Reset nedeni / reset cause:", causes.get(machine.reset_cause(), "bilinmiyor / unknown"))
12
13while True:
14 gc.collect() # çöp toplayıcıyı çalıştır / run the garbage collector
15 print("Bos RAM / free RAM:", gc.mem_free(), "bayt / bytes")
16 time.sleep(5)Häufige Fehler und Lösungen
| Symptom | Mögliche Ursache | Lösung |
|---|---|---|
| Brownout detector was triggered beim WLAN-Start | Kabel, Port oder Regler kommen dem Spitzenstrom nicht hinterher | Kurzes dickes Kabel, 1-A-Netzteil, 470 µF + 100 nF zwischen 3V3 und GND |
| Reset, wenn sich ein Servo dreht oder ein Relais schaltet | Der Verbraucher hängt an der Leitung des ESP32 | Verbraucher aus eigener 5-V-Quelle versorgen, GNDs verbinden |
| Resets beginnen, wenn der Akku etwas leerer ist | Dropout des AMS1117 | LDO oder Buck-Boost-Wandler verwenden |
| Guru Meditation, EXCVADDR 0x00000000 | Nullzeiger | Zeiger vor der Benutzung prüfen |
| Stack canary watchpoint triggered (loopTask) | Der Stack von loop() ist voll | Große Arrays static machen oder SET_LOOP_TASK_STACK_SIZE nutzen |
| task_wdt: - IDLE (CPU 0) | Schleife ohne Pausen auf Kern 0 | vTaskDelay in die Schleife einbauen |
| Interrupt wdt timeout on CPU1 | ISR dauert zu lange | In der ISR nur ein Flag setzen, IRAM_ATTR verwenden |
| Board stumm, boot:0x3 und waiting for download | GPIO0 beim Start LOW | Schaltung an GPIO0 entfernen, EN drücken |
| Board startet gar nicht, Fehler beim Lesen des Flash | GPIO12 beim Start HIGH | Pull-up oder Modul an GPIO12 auf einen anderen Pin verlegen |
| Failed to connect to ESP32 beim Hochladen | GPIO2 HIGH oder das Board kommt nicht in den Programmiermodus | GPIO2 freimachen, beim Start des Uploads BOOT gedrückt halten |
Dein Board läuft stabil: Wie geht es weiter?
- Akkufreundliches Gerät: Lege das Board mit ESP32 Deep Sleep zwischen den Messungen schlafen und senke den Strom in den Mikroampere-Bereich.
- Drahtlose Updates: Lade Code mit ESP32 OTA ohne USB-Kabel hoch.
- Echtzeit-Dashboard: Verfolge Sensordaten mit ESP32 WebSocket live im Browser.
- Benachrichtigungen senden: Mit einem ESP32-Telegram-Bot bekommst du bei jedem Neustart des Boards den Reset-Grund aufs Handy.
- Lichtshow: Steuere einen WS2812B-NeoPixel-Streifen sicher mit getrennter Versorgung.
Die meisten Neustart-Probleme des ESP32 sind entweder ein Versorgungsproblem oder ein paar Zeilen fehlerhafter Code; liest du die Meldung richtig, sind beide schnell gelöst. Um die Grundlagen des Boards aufzufrischen, wirf einen Blick auf Was ist der ESP32? In der BlueGrays-App findest du ESP32-Projekte mit LEDs, Servos, NeoPixel-Streifen, WLAN-Verbindung, Webserver, OTA-Updates und Deep Sleep, jeweils mit Schritt-für-Schritt-Schaltplan und Code, sodass du die hier gelernten Versorgungs- und Diagnosetechniken in echten Projekten ausprobieren kannst.
Häufige Fragen
Wie behebe ich ESP32 Brownout Detector was triggered?
Dieser Fehler bedeutet, dass die Versorgungsspannung des ESP32 kurz unter etwa 2,43 V gefallen ist. Nutze zuerst ein kurzes, dickes USB-Kabel mit einer 5-V-Quelle, die mindestens 1 A liefert, und setze dann einen 100–470-µF-Elko und einen 100-nF-Keramikkondensator zwischen 3V3 und GND. Versorge Verbraucher wie Servos, Relais und LED-Streifen aus einer eigenen Quelle und verbinde die GNDs.
Warum startet mein ESP32 ständig neu?
Die häufigsten Ursachen sind eine zu schwache Versorgung (Brownout), Software-Abstürze (Guru Meditation), Watchdog-Timeouts und Strapping-Pins, die beim Start auf dem falschen Pegel liegen. Öffne den seriellen Monitor mit 115200 Baud und drücke EN; die letzte Meldung vor dem Reset und der rst-Code beim Start zeigen die Ursache. Mit esp_reset_reason() kannst du sie auch im Code auslesen.
Was bedeutet Guru Meditation Error LoadProhibited?
Es bedeutet, dass Code auf dem ESP32 von einer ungültigen Speicheradresse lesen wollte. Ist EXCVADDR 0 oder eine sehr kleine Zahl, wurde fast sicher ein Nullzeiger benutzt. Füge die Backtrace-Zeile in den ESP Exception Decoder ein, um Datei und Zeile des Fehlers zu finden.
Kann man den Brownout-Detektor des ESP32 abschalten?
Ja, mit der Zeile WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0), aber damit verstummt nur die Warnung. Da die Spannungseinbrüche bleiben, können Daten im Flash beschädigt werden und das Board kann mit anderen Fehlern abstürzen. Nutze das nur kurz, um zu bestätigen, dass das Problem an der Versorgung liegt.
Wie behebe ich ESP32 Task watchdog got triggered?
Die Meldung bedeutet, dass eine überwachte Task die CPU 5 Sekunden lang nicht freigegeben hat; bei Arduino steht in der Liste meist die IDLE-Task von Kern 0. Baue vTaskDelay() in die Schleifen deiner eigenen Tasks ein, nutze Timeouts beim Warten auf Sensoren und vermeide delay() oder lange Operationen in Webserver-Callbacks. Den Watchdog abzuschalten, versteckt den Fehler, behebt aber nicht die Ursache.
Welches Netzteil braucht ein ESP32?
Espressif empfiehlt für den ESP32 ein Netzteil, das mindestens 500 mA liefern kann; in der Praxis lässt ein 5-V-Netzteil mit 1 A eine sichere Reserve. Nutzt du einen ESP32-CAM oder hängst Verbraucher wie Servos oder LED-Streifen an, wähle eine Quelle mit 2 A oder mehr und versorge diese Verbraucher möglichst über eine eigene Leitung.
Projekte, die du danach bauen kannst
Alle Projekte ansehen
LED Blinken mit ESP32
Lehrt die grundlegende Verwendung von GPIO-Ausgängen mit ESP32. Wir erreichen einen Blinkeffekt, indem wir eine LED über einen digitalen Pin ein- und ausschalten. ESP32-Version des klassischen Blink-Projekts auf Arduino UNO; die grundlegenden Blink-Befehle in der Arduino-Umgebung bleiben gleich, aber die Pinbelegung und die GPIO-Pegel von 3,3 V des ESP32 unterscheiden sich von denen des Arduino UNO.

ESP32-WLAN-STA-Verbindung (mit LCD-Display)
In diesem Projekt verbinden wir den ESP32 im Station-Modus (STA) sicher und fehlertolerant mit dem heimischen WLAN. Wir lagern SSID und Passwort in eine separate secrets.h-Datei aus, um Leaks zu Git zu verhindern, richten einen Auto-Reconnect-Mechanismus ein und zeigen RSSI-Signalpegel und IP-Adresse auf einem I2C-LCD-Display an. Die interne LED dient als Statusanzeige. Ein Verbindungsmanager auf Produktionsniveau.

ESP32-Servomotor (Steuerung über Potentiometer)
In diesem Projekt steuern wir einen SG90-Servomotor mit einem Potentiometer. Wir stellen den Servowinkel ein, indem wir den vom Potentiometer gelesenen Analogwert auf den Bereich von 0 bis 180 Grad abbilden. Die ESP32Servo-Bibliothek erzeugt Servosignale an geeigneten GPIO-Pins des ESP32, die als Ausgang verwendet werden können; in diesem Projekt wird GPIO 18 verwendet. Dies ist eine grundlegende Steuerungsmethode für Roboterarme, Kamera-Gimbals und automatische Türmechanismen.

Steuerung des ESP32 WS2812B NeoPixel-Streifens
WS2812B (NeoPixel) adressierbare LEDs sind intelligente RGB-LEDs, die über einen einzigen Datenpin in Reihe geschaltet gesteuert werden können. In diesem Projekt werden wir einen WS2812B-Streifen mit 8 LEDs mithilfe der Adafruit_NeoPixel-Bibliothek steuern und eine fließende Regenbogenanimation erzeugen. Obwohl der 3,3-V-Logikpegel des ESP32 bei den meisten WS2812B-Bausteinen problemlos funktioniert, zeigen wir im Falle von Instabilität die Lösung mit einem 470-Ω-Reihenwiderstand und einem 1000-

ESP32 Async-Webserver (mit IP-Anzeige auf dem LCD)
In diesem Projekt verwandeln wir den ESP32 in einen asynchronen Webserver, den Sie über Ihr Smartphone oder Ihren Computer im selben WLAN-Netzwerk steuern können. Dank der ESPAsyncWebServer-Bibliothek kann der Server mehrere Anfragen gleichzeitig bearbeiten (im Gegensatz zum klassischen WebServer.h, der bei einer einzigen Anfrage blockiert). Sie können über den Browser die IP-Adresse des ESP32 öffnen und durch Drücken der ON/OFF-Schaltflächen (Routen /on und /off) die an GPIO 5 anges

ESP32 Deep Sleep – Batteriesparmodus (OLED + RTC-RAM-Zähler)
Der Deep-Sleep-Modus des ESP32 senkt den Stromverbrauch auf etwa 10 µA, indem er die CPU und die meisten Peripheriegeräte abschaltet, und ist für batteriebetriebene IoT-Geräte von entscheidender Bedeutung. In diesem Projekt verwenden wir drei verschiedene Weckquellen: den Timer (15 s), einen externen Pin (EXT0 – Taste GPIO 33) und die Berührungserkennung (T0/GPIO 4). Mit RTC_DATA_ATTR markierte Variablen bleiben während des Deep-Sleep-Modus erhalten – der Boot-Zähler, der Timer-Wake-Zähler und

ESP32-OTA-Update – Drahtlose Firmware-Installation (mit LCD-Display)
In diesem Projekt lernst du, wie du auf dem ESP32 ohne USB-Kabel über WLAN neue Firmware installieren kannst. Mit der ArduinoOTA-Bibliothek wird der ESP32 im Netzwerk sichtbar und wird im Reiter „Network port“ der Arduino-IDE automatisch als bluegrays-ota aufgelistet. Die erste Installation erfolgt über USB, alle nachfolgenden Updates erfolgen drahtlos – eine äußerst wichtige Funktion für Feldgeräte. Auf dem I2C-LCD-Display werden der WLAN-Status, die IP-Adresse, der Hostname, der Fortschrit

ESP32 Bewegungsalarmsystem (PIR + Buzzer + LED + Telegram)
Ein intelligentes Sicherheitsalarmsystem, das Buzzer und LED aktiviert, sobald der PIR-Sensor Bewegung erkennt, und gleichzeitig eine sofortige Benachrichtigung per Telegram an den Besitzer sendet. Ein 30-sekündiger Cooldown begrenzt die Häufigkeit wiederholter Alarme; dieser Mechanismus überprüft weder die Gültigkeit der PIR-Erkennungen noch verhindert er Fehlauslösungen. Geeignet für Heimsicherheit, Garagenüberwachung, Lagerräume oder Arbeitszimmer. Mit ESP32-CAM sind Foto-Benachrichtigungen m
Weitere Artikel
BlueGrays-App
Diese Schaltung Schritt für Schritt auf dem Handy nachbauen
Schaltplan, Code und Teileliste auf einem Bildschirm. Über 200 Arduino-, ESP32- und Pico-Projekte zum Nachbauen.
Mit dem Handy scannen
Richte die Kamera auf den Code, dann öffnet sich der App-Store deines Handys.
oder im Store öffnen

