ESP32 Deep Sleep Tutorial: Stromverbrauch senken & monatelang mit Akku laufen
Dein ESP32 läuft am Netzteil tadellos – aber am Akku ist nach zwei Tagen Schluss? Dann fehlt deinem Projekt genau ein Feature: Deep Sleep. Im Tiefschlaf braucht der ESP32 statt über 100 Milliampere nur noch etwa 10 Mikroampere – das ist der Unterschied zwischen \"zwei Tage\" und \"viele Monate\" Batterielaufzeit. In diesem Tutorial lernst du alle Schlafmodi kennen, weckst den ESP32 per Timer, Knopfdruck und Touch-Pin wieder auf, rettest Daten über den Neustart hinweg in den RTC-Speicher und baust am Ende einen kompletten batteriebetriebenen Wetterlogger, der nur wenige Sekunden pro Stunde wach ist.
Warum Deep Sleep das wichtigste Feature für Akkuprojekte ist
Ein ESP32 mit aktivem WLAN zieht je nach Board zwischen 100 und 240 mA. Ein üblicher 18650-Akku mit 2500 mAh wäre damit rechnerisch nach gut einem Tag leer. Das Entscheidende dabei: Die meiste Zeit tut dein Projekt nichts. Ein Sensorknoten, der stündlich die Temperatur meldet, arbeitet pro Stunde vielleicht fünf Sekunden – und verbrennt die restlichen 3595 Sekunden Strom fürs Warten.
Genau hier setzt Deep Sleep an: Der ESP32 schaltet CPU, WLAN, Bluetooth und den Großteil des RAM komplett ab. Übrig bleibt nur der winzige RTC-Bereich (Real Time Clock) mit Timer, ein paar speziellen Pins und 8 KB Spezial-RAM. Der Verbrauch des Chips fällt dadurch auf rund 10 µA – das ist ein Zehntausendstel des Normalbetriebs. Nach dem Aufwachen startet der Chip neu, arbeitet seine Aufgabe ab und legt sich wieder schlafen.
💡 Eine Beispielrechnung: Ein Sensorknoten ist pro Stunde 5 Sekunden wach (Ø 120 mA) und schläft 3595 Sekunden (Ø 0,05 mA mit Board-Drumherum). Das ergibt im Mittel rund 0,2 mA – mit einem 2500-mAh-Akku theoretisch über ein Jahr Laufzeit. Ohne Deep Sleep wäre derselbe Akku nach etwa einem Tag leer.
Die Schlafmodi des ESP32 im Überblick
Deep Sleep ist nicht der einzige Sparmodus. Der ESP32 kennt mehrere Stufen, die sich darin unterscheiden, was weiterläuft und wie schnell der Chip wieder einsatzbereit ist:
| Modus | Was läuft weiter? | Typ. Strom (Chip) | Aufwachen |
|---|---|---|---|
| Aktiv (WLAN an) | alles | 100–240 mA | – |
| Modem-Sleep | CPU läuft, WLAN schläft zwischen Beacons | 20–70 mA | sofort |
| Light-Sleep | RAM & Zustand bleiben erhalten, CPU pausiert | ca. 0,8 mA | in Millisekunden, Programm läuft weiter |
| Deep Sleep | nur RTC-Timer, RTC-GPIOs, 8 KB RTC-RAM | ca. 10 µA | Neustart des Programms |
ℹ️ Wichtigster Unterschied: Nach Light-Sleep läuft dein Programm einfach in der nächsten Zeile weiter. Nach Deep Sleep startet der ESP32 dagegen komplett neu – setup() wird wieder von vorn ausgeführt und alle normalen Variablen sind weg. Wie du trotzdem Daten über den Schlaf rettest, zeigt Schritt 2.
Das brauchst du
Wie du aus TP4056, Step-Up-Wandler und 18650-Zelle eine saubere Akkuversorgung baust, erklärt ausführlich der Artikel Akkubetriebene ESP32-Projekte mit 18650-Zellen.
1Timer-Wakeup: dein erster Deep-Sleep-Sketch
Der häufigste Anwendungsfall: Der ESP32 soll in festen Intervallen aufwachen. Dafür stellst du vor dem Einschlafen den RTC-Timer – er läuft im Tiefschlaf weiter und weckt den Chip nach Ablauf. Die Zeit gibst du in Mikrosekunden an, deshalb der Umrechnungsfaktor:
#define uS_ZU_S 1000000ULL // Mikrosekunden -> Sekunden
#define SCHLAFZEIT 10 // Sekunden schlafen
void setup() {
Serial.begin(115200);
delay(500); // Zeit, damit der Serial Monitor mitkommt
Serial.println("Bin wach! Ich arbeite kurz ...");
delay(2000); // hier steht spaeter deine eigentliche Aufgabe
// Timer stellen und schlafen gehen
esp_sleep_enable_timer_wakeup(SCHLAFZEIT * uS_ZU_S);
Serial.println("Gute Nacht fuer 10 Sekunden.");
Serial.flush(); // Puffer leeren, bevor der Strom weg ist
esp_deep_sleep_start(); // ab hier ist alles aus
}
void loop() {
// wird nie erreicht: nach Deep Sleep startet setup() neu
}
Lade den Sketch hoch und öffne den Serial Monitor: Alle 12 Sekunden (10 s Schlaf + 2 s Arbeit) meldet sich das Board neu. Beachte, dass die gesamte Logik im setup() steht – loop() wird bei Deep-Sleep-Projekten praktisch nie benutzt, weil der Chip ja bei jedem Aufwachen neu startet.
ℹ️ ULL nicht vergessen: Der Faktor 1000000ULL ist als unsigned long long deklariert. Rechnest du mit normalen int-Werten, läuft die Multiplikation bei längeren Schlafzeiten über und dein ESP32 schläft statt 2 Stunden nur ein paar Sekunden – ein klassischer, schwer zu findender Fehler.
2RTC-Memory: Daten über den Schlaf retten
Nach dem Aufwachen sind alle Variablen weg – außer du legst sie in den 8 KB großen RTC-Speicher, der im Tiefschlaf weiterversorgt wird. Dafür genügt das Schlüsselwort RTC_DATA_ATTR vor der Variablendeklaration. Außerdem kannst du abfragen, warum der ESP32 aufgewacht ist:
#define uS_ZU_S 1000000ULL
RTC_DATA_ATTR int bootZaehler = 0; // ueberlebt den Deep Sleep
void zeigeWeckgrund() {
esp_sleep_wakeup_cause_t grund = esp_sleep_get_wakeup_cause();
switch (grund) {
case ESP_SLEEP_WAKEUP_TIMER: Serial.println("Geweckt vom Timer"); break;
case ESP_SLEEP_WAKEUP_EXT0: Serial.println("Geweckt vom Taster (EXT0)"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD: Serial.println("Geweckt vom Touch-Pin"); break;
default: Serial.println("Normaler Start (Reset oder Strom an)"); break;
}
}
void setup() {
Serial.begin(115200);
delay(500);
bootZaehler++;
Serial.printf("Aufwachen Nr. %d\n", bootZaehler);
zeigeWeckgrund();
esp_sleep_enable_timer_wakeup(15 * uS_ZU_S);
Serial.flush();
esp_deep_sleep_start();
}
void loop() {}
Der Zähler zählt bei jedem Aufwachen weiter hoch, obwohl der Chip dazwischen komplett aus war. Genau so speicherst du später z. B. Messwerte zwischen, um sie nur bei jedem zehnten Aufwachen gesammelt zu versenden – das spart nochmal kräftig Strom, weil WLAN der größte Verbraucher ist.
3Praxisprojekt: Batterie-Wetterlogger mit DHT22
Jetzt wird es praktisch: Ein DHT22 misst Temperatur und Luftfeuchte, der ESP32 gibt die Werte aus und schläft dann 10 Minuten. Verkabelung: DHT22-VCC an 3V3, GND an GND, DATA an GPIO 4 (mit 10-kΩ-Pull-up nach 3V3, bei den meisten Modulen schon eingebaut). Du brauchst die Bibliothek \"DHT sensor library\" von Adafruit.
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT22
#define uS_ZU_S 1000000ULL
#define SCHLAF_MIN 10 // alle 10 Minuten messen
DHT dht(DHTPIN, DHTTYPE);
RTC_DATA_ATTR int messungNr = 0;
void setup() {
Serial.begin(115200);
delay(300);
dht.begin();
delay(2000); // DHT22 braucht nach dem Start kurz Zeit
float temp = dht.readTemperature();
float feuchte = dht.readHumidity();
messungNr++;
if (isnan(temp) || isnan(feuchte)) {
Serial.println("Sensorfehler - schlafe und versuche es spaeter erneut.");
} else {
Serial.printf("Messung %d: %.1f Grad C, %.1f %% rF\n",
messungNr, temp, feuchte);
// Hier wuerdest du die Werte per WLAN, MQTT oder ESP-NOW senden
}
esp_sleep_enable_timer_wakeup(SCHLAF_MIN * 60ULL * uS_ZU_S);
Serial.flush();
esp_deep_sleep_start();
}
void loop() {}
Damit ist der Knoten pro Messung nur etwa 3 Sekunden wach. Willst du die Daten funken, hast du zwei stromsparende Wege: ESP-NOW (verbindet sich in Millisekunden, ideal für Batterieknoten) oder klassisch WLAN mit MQTT ans Smart Home – dann solltest du die WLAN-Zugangsdaten samt Kanal im RTC-Speicher cachen, um die Verbindungszeit zu verkürzen.
💡 Die goldene Regel für Batterieknoten: Wachzeit minimieren schlägt jede andere Optimierung. Erst messen, dann einmal kurz senden, sofort schlafen. Kein delay(5000) zur Sicherheit, keine Debug-Warteschleifen im Produktivbetrieb.
4Aufwecken per Taster und Touch-Pin
Nicht jedes Projekt soll stur nach Zeitplan aufwachen. Mit EXT0-Wakeup weckt ein Tastendruck den ESP32, mit Touch-Wakeup reicht eine Berührung eines Touch-Pins. Für EXT0 verbindest du einen Taster zwischen GPIO 33 und 3V3 sowie einen 10-kΩ-Widerstand von GPIO 33 nach GND (Pull-down):
#define uS_ZU_S 1000000ULL
void setup() {
Serial.begin(115200);
delay(500);
Serial.println("Wach! Entweder Timer oder Taster war's.");
// Weg 1: Taster an GPIO 33 weckt bei HIGH-Pegel
esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 1);
// Weg 2: zusaetzlich Sicherheits-Timer (1 Stunde)
esp_sleep_enable_timer_wakeup(3600ULL * uS_ZU_S);
Serial.flush();
esp_deep_sleep_start();
}
void loop() {}
Für Touch-Wakeup nutzt du einen der Touch-Pins (z. B. GPIO 4 = T0) und hängst einfach ein Stück Draht oder eine Metallfläche daran:
#define SCHWELLE 40 // je kleiner, desto unempfindlicher
void beruehrungCallback() {
// muss existieren, darf leer sein
}
void setup() {
Serial.begin(115200);
delay(500);
Serial.println("Wach durch Beruehrung oder Start.");
touchAttachInterrupt(T0, beruehrungCallback, SCHWELLE);
esp_sleep_enable_touchpad_wakeup();
Serial.flush();
esp_deep_sleep_start();
}
void loop() {}
ℹ️ Nur RTC-GPIOs können wecken: Im Tiefschlaf sind normale GPIOs tot. Für EXT0/EXT1 funktionieren nur die RTC-fähigen Pins – beim klassischen ESP32 sind das u. a. GPIO 0, 2, 4, 12–15, 25–27 und 32–39. GPIO 33 ist eine sichere Wahl. Mehr über kapazitive Berührungssensorik liest du im Artikel TTP223 Touch-Sensor mit Arduino.
Warum dein Board trotzdem mehr verbraucht – und was du tun kannst
Die 10 µA gelten für den Chip. Ein Dev-Board bringt aber Nebenverbraucher mit: Die Power-LED leuchtet dauerhaft (~1–3 mA), der USB-Serial-Chip zieht Strom und der Spannungsregler hat einen Eigenverbrauch. Typische Dev-Boards landen deshalb im Deep Sleep bei 0,1 bis 10 mA – immer noch um Größenordnungen besser als der Aktivbetrieb, aber weit weg vom Datenblattwert.
- Power-LED: größter Einzelposten – für Langläufer-Projekte auslöten oder den Vorwiderstand entfernen
- Direkt versorgen: den Akku (über eine Schutzschaltung) möglichst am 3V3-Pin einspeisen statt über den 5V/USB-Weg, dann schläft auch der USB-Chip stromlos
- Sensoren mitschlafen legen: Sensoren über einen GPIO oder MOSFET nur zum Messen einschalten – ein DHT22 zieht sonst dauerhaft Ruhestrom
- Nachmessen: ein Multimeter im mA/µA-Bereich in die Versorgungsleitung schalten – nur so weißt du, was dein Aufbau wirklich verbraucht
🔋 Ideen zum Weiterbauen
- Funk-Außensensor: DHT22-Werte per ESP-NOW an eine Basisstation senden – siehe ESP-NOW Funkstrecke
- Briefkastenmelder: Reed-Kontakt an einem RTC-GPIO weckt den ESP32, der eine Nachricht schickt
- Pflanzenwächter: stündlich Bodenfeuchte messen – Grundlagen im Artikel Kapazitiver Bodenfeuchte-Sensor
- Smart-Home-Knoten: Messwerte beim Aufwachen per MQTT melden – siehe MQTT mit ESP32 & Home Assistant
Perfekt für: Außensensoren, Wildkameras, Briefkasten- & Türmelder, alles ohne Steckdose
Troubleshooting
⚠️ Board wacht sofort wieder auf: Meist floatet der Wakeup-Pin. Bei EXT0 mit HIGH-Trigger braucht der Pin einen Pull-down-Widerstand (10 kΩ nach GND), sonst weckt schon elektrisches Rauschen den Chip.
⚠️ Serial Monitor zeigt Zeichensalat: Direkt nach dem Aufwachen sendet der ESP32 Boot-Meldungen mit anderer Baudrate. Stelle den Monitor auf 115200 und ignoriere die ersten kryptischen Zeilen – sie sind normal.
⚠️ Schlafzeit stimmt nicht: Fast immer ein Integer-Überlauf. Rechne konsequent mit ULL-Konstanten (3600ULL * 1000000ULL), sobald Schlafzeiten über ~35 Minuten liegen.
⚠️ Upload schlägt fehl, Board scheint tot: Ein tief schlafender ESP32 meldet sich kaum am USB. Halte die BOOT-Taste beim Start des Uploads gedrückt oder drücke Reset, sobald die IDE \"Connecting...\" zeigt.
⚠️ Touch-Wakeup löst ständig aus: Schwellwert (SCHWELLE) verkleinern und den Touch-Draht kurz halten. Luftfeuchtigkeit und lange Leitungen verändern die Kapazität deutlich.
🚀 Alles für dein stromsparendes Projekt
Diese Teile aus dem Shop bringen deinen Sensorknoten auf Monate Laufzeit:
- ESP32 Entwicklungsboard (USB-C) – der Klassiker für alle Deep-Sleep-Projekte
- DHT22 Temperatur- & Feuchtigkeitssensor – präzise Messwerte für den Wetterlogger
- TP4056 USB-C Lademodul (3er-Set) – sicheres Laden mit Schutzschaltung
- MT3608 Step-Up Modul – stabile 5 V aus der Akkuzelle
- Breadboard 400 Kontakte – zum Aufbau und Testen
Fazit
Deep Sleep verwandelt den ESP32 vom Stromfresser in einen Marathonläufer: 10 µA statt 100+ mA bedeuten Monate statt Tage Batterielaufzeit. Du hast gelernt, den Chip per Timer, Taster und Touch-Pin zu wecken, mit RTC_DATA_ATTR Daten über den Neustart zu retten und mit dem DHT22-Wetterlogger ein komplettes Batterieprojekt aufzubauen. Ebenso wichtig: das Wissen, warum Dev-Boards mehr verbrauchen als das Datenblatt verspricht – und wie du mit Power-LED, direkter 3V3-Versorgung und schaltbaren Sensoren gegensteuerst.
Merke dir die drei Grundregeln: Erstens gehört bei Deep-Sleep-Projekten die gesamte Logik ins setup(). Zweitens entscheidet die Wachzeit über die Laufzeit – messen, senden, schlafen, nichts anderes. Drittens ist WLAN der größte Verbraucher, also so kurz wie möglich verbinden oder gleich auf ESP-NOW ausweichen. Damit steht deinem ersten Außensensor, der eine ganze Saison ohne Steckdose durchhält, nichts mehr im Weg. Viel Spaß beim Bauen!