Der ESP8266 ist ein vielseitiger und preiswerter Mikrocontroller mit integrierter WiFi-Funktionalität. Eine seiner bemerkenswertesten Funktionen ist jedoch der Deep-Sleep-Modus, der es ermöglicht, den Stromverbrauch drastisch zu senken, wenn der Mikrocontroller nicht aktiv ist. Dies ist besonders nützlich in batteriebetriebenen IoT-Projekten, in denen die Energieeffizienz entscheidend ist.
So kann dein ESP zum Beispiel alle 20 Minuten aufwachen, einen Sensorwert übermitteln und sich dann wieder schlafen legen. In diesem Tutorial erfährst du, wie du dabei vorgehst: vom ersten Test mit wenigen Zeilen Code bis zur fertigen Sensor-Station, die per WLAN Daten verschickt. Und du erfährst, warum die Stromersparnis auf einem NodeMCU deutlich kleiner ausfällt, als du vielleicht denkst.
Nutzt du einen ESP32? In diesem Tutorial erfährst du alles über den ESP32 Deep Sleep.
Wie der Deep Sleep funktioniert
Wenn du den Deep Sleep startest, schaltet der Chip fast alles ab: Prozessor, WLAN, RAM. Nur eine winzige Uhr – der sogenannte RTC-Timer – läuft weiter und zählt. Ist die eingestellte Zeit abgelaufen, löst diese Uhr einen Reset aus. Der ESP8266 bootet also komplett neu, so als hättest du den Reset-Knopf gedrückt.
Daraus folgen zwei Dinge, die dich sonst später Nerven kosten:
- Dein Programm läuft nach dem Aufwachen wieder von vorne los – bei
setup(). Die Funktionloop()wird nie ein zweites Mal durchlaufen. Der Code für den Deep Sleep gehört deshalb insetup(). - Alle deine Variablen sind weg. Ein Zähler, den du hochzählst, steht nach dem Aufwachen wieder auf null. Wie du das umgehst, zeige ich dir weiter unten im Abschnitt zum RTC-Speicher.
Diese Bauteile brauchst du
- 1× ESP8266-Entwicklungsboard Zum Beispiel NodeMCU oder Wemos D1 Mini; für den ersten Deep-Sleep-Test.
- 1× Female-Female-Jumper-Kabel Ein Kabel verbindet D0 (GPIO16) mit RESET.
- 1× USB-Kabel Passend zum verwendeten ESP8266-Board, zum Programmieren und zur Stromversorgung.
Affiliate-Links: Kaufst du über diese Links, erhält Pollux Labs eine kleine Provision – für dich ohne Mehrkosten.
Übrigens – falls du es noch nicht weißt – bei uns erfährst du, wie du deinen ESP8266 mit der Arduino IDE programmierst.
Verkabelung für den ESP8266 Deep Sleep
Die gute Nachricht, du benötigst nur ein einziges Kabel: Um den Deep-Sleep-Modus zu nutzen, muss der RESET-Pin des ESP8266 mit dem D0-Pin verbunden werden. Entweder verwendest du hier ein Female-Female-Kabel, das du direkt an die Pins des ESP steckst – oder du verwendest ein Breadboard. Mehr musst du für den Schlafmodus nicht tun.
Warum ausgerechnet diese beiden Pins? Wenn der Timer abgelaufen ist, schickt der Chip einen kurzen Impuls über den Pin D0 (intern GPIO16). Dieser Impuls muss beim RESET-Pin ankommen, damit der ESP8266 neu startet. Ohne dieses Kabel legt sich dein ESP schlafen – und wacht nie wieder auf.
Wichtiger Hinweis zum Hochladen: Diese Verbindung kann das Flashen stören. Falls der Upload plötzlich fehlschlägt oder die Arduino IDE deinen ESP nicht mehr findet, ziehe das Kabel einfach ab, lade den Sketch hoch und stecke es danach wieder auf. Das ist kein Defekt, sondern normal.
Der erste Sketch
Lege in der Arduino IDE einen neuen Sketch an, füge den folgenden Code ein und lade ihn auf deinen ESP8266.
void setup() {
// Beginne die serielle Kommunikation
// 74880 Baud ist die Geschwindigkeit, mit der auch der ESP8266
// selbst seine Boot-Meldungen ausgibt – so bleibt alles lesbar
Serial.begin(74880);
Serial.println();
// Ausgabe einer Nachricht, wenn der ESP8266 aufwacht
Serial.println("Der ESP8266 ist aufgewacht!");
// Hier würde im echten Projekt deine Arbeit passieren:
// Sensor auslesen, Daten senden ...
delay(2000);
Serial.println("Der ESP8266 geht in den Deep-Sleep-Modus...");
// Warte, bis die Nachricht wirklich gesendet wurde
Serial.flush();
// ESP8266 in den Deep-Sleep-Modus versetzen
// Die Zeit ist in Mikrosekunden angegeben
// 1 Sekunde = 1.000.000 Mikrosekunden
// In diesem Fall schläft der ESP8266 10 Sekunden lang
ESP.deepSleep(10e6);
}
void loop() {
// Bleibt leer: Nach dem Deep Sleep startet der ESP8266 neu
// und beginnt wieder bei setup(). Hier kommt er nie an.
}
Öffne nun den seriellen Monitor und stelle ihn auf 74880 Baud. Dein ESP8266 ist jetzt 2 Sekunden lang wach und schläft danach 10 Sekunden – der komplette Zyklus dauert also rund 12 Sekunden. Das ist ein Punkt, den man leicht übersieht: Die Schlafdauer kommt zur Wachzeit hinzu, sie enthält sie nicht. Soll dein ESP wirklich exakt alle 10 Sekunden aufwachen, musst du die Zeit abziehen, die er für seine Arbeit braucht.
Wie viel Strom sparst du wirklich?
Der nackte ESP8266-Chip zieht im Deep Sleep etwa 20 Mikroampere. Aktiv mit eingeschaltetem WLAN sind es grob 70 Milliampere, bei Sendespitzen kurzzeitig auch mal 170 mA. Das ist ein Faktor von ungefähr 3.500 – klingt fantastisch.
Auf einem NodeMCU oder Wemos D1 Mini wirst du diese 20 µA aber nie messen. Der Grund: Auf diesen Entwicklerboards sitzt nicht nur der Chip. Da sind auch ein USB-Seriell-Wandler (CH340 oder CP2102), ein Spannungsregler und meistens noch eine Power-LED. Diese Bauteile wissen nichts vom Deep Sleep und ziehen munter weiter Strom. In der Praxis landest du damit eher bei 0,3 bis 20 Milliampere, je nach Board – also beim Tausendfachen dessen, was der Chip allein bräuchte.
Was das konkret bedeutet: Eine 2.000-mAh-Powerbank hält einen schlafenden NodeMCU vielleicht ein paar Wochen am Leben. Denselben Chip als nacktes ESP-12F-Modul mit einem sparsamen Spannungsregler betreibst du damit theoretisch jahrelang.
Die Konsequenz für deine Projekte:
- Zum Lernen und Entwickeln ist ein NodeMCU oder D1 Mini genau richtig. Der Deep Sleep funktioniert dort einwandfrei, du sparst nur nicht das Maximum.
- Für ein echtes Batterieprojekt, das monatelang laufen soll, brauchst du ein reines ESP-12F-Modul – oder du entfernst auf deinem Board die Power-LED und ersetzt den Spannungsregler. Der Wemos D1 Mini ist hier übrigens deutlich sparsamer als die meisten NodeMCU-Varianten und ein guter Kompromiss.
Und noch ein Tipp, der oft mehr bringt als alles andere: Die Wachzeit ist entscheidend. Der WLAN-Verbindungsaufbau dauert je nach Router 3 bis 10 Sekunden – in dieser Zeit zieht dein ESP Vollgas. Wenn du diese Phase von 8 auf 3 Sekunden drückst, sparst du oft mehr Energie als durch ein längeres Schlafintervall.
Wie lange kann der ESP8266 schlafen?
Nicht beliebig lange. Der RTC-Timer hat ein Limit, und wenn du es überschreitest, passieren seltsame Dinge: Dein ESP wacht sofort wieder auf oder gar nicht mehr.
Die konkrete Zahl hängt von deiner Version des ESP8266-Cores ab. Früher lag die Grenze bei rund 71 Minuten, aktuelle Versionen schaffen etwa 3,5 Stunden. Statt dich auf eine Zahl aus dem Internet zu verlassen, kannst du deinen Chip einfach selbst fragen:
void setup() {
Serial.begin(74880);
Serial.println();
// Fragt den Chip nach seiner maximalen Schlafdauer
uint64_t maxSchlaf = ESP.deepSleepMax();
Serial.print("Maximale Schlafdauer: ");
Serial.print((uint32_t)(maxSchlaf / 1000000));
Serial.println(" Sekunden");
}
void loop() {}
Für unser Beispiel mit 20 Minuten ist das kein Problem. Willst du deinen ESP aber nur zweimal am Tag aufwecken, musst du ihn mehrfach hintereinander schlafen legen und dabei mitzählen. Und dafür brauchst du einen Speicher, der den Neustart überlebt.
Werte über den Schlaf retten: der RTC-Speicher
Wie oben beschrieben sind nach dem Aufwachen alle Variablen zurückgesetzt. Es gibt aber einen kleinen Bereich, der weiterläuft: den RTC-Speicher. Er ist 512 Byte groß und behält seinen Inhalt, solange die Stromversorgung nicht unterbrochen wird.
Damit kannst du zum Beispiel zählen, wie oft dein ESP schon aufgewacht ist. Eine Kleinigkeit ist dabei zu beachten: Beim allerersten Start (also nachdem du den Strom angeschlossen hast) steht in diesem Speicher zufälliger Müll. Deshalb schreiben wir eine selbst ausgedachte Kennzahl mit hinein – finden wir sie beim Aufwachen wieder, wissen wir, dass die Daten von uns stammen.
// Diese Struktur landet im RTC-Speicher
struct RtcDaten {
uint32_t kennzahl; // erkennt, ob die Daten von uns stammen
uint32_t zyklen; // unser Zähler
};
RtcDaten daten;
// Eine beliebige, aber unwahrscheinliche Zahl
const uint32_t KENNZAHL = 0xC0FFEE42;
void setup() {
Serial.begin(74880);
Serial.println();
// Daten aus dem RTC-Speicher lesen
ESP.rtcUserMemoryRead(0, (uint32_t*)&daten, sizeof(daten));
if (daten.kennzahl != KENNZAHL) {
// Kaltstart: Der Speicher enthält Müll, also alles zurücksetzen
daten.kennzahl = KENNZAHL;
daten.zyklen = 0;
Serial.println("Kaltstart – Zaehler zurueckgesetzt.");
}
daten.zyklen++;
Serial.print("Aufwachen Nr. ");
Serial.println(daten.zyklen);
// Daten zurückschreiben, damit sie den Schlaf überleben
ESP.rtcUserMemoryWrite(0, (uint32_t*)&daten, sizeof(daten));
Serial.flush();
ESP.deepSleep(10e6);
}
void loop() {}
Im seriellen Monitor siehst du nun, wie der Zähler bei jedem Aufwachen um eins steigt. Drückst du den Reset-Knopf, zählt er weiter. Ziehst du den Strom ab, beginnt er von vorne.
Damit kannst du zwei Dinge bauen, die vorher nicht möglich waren: sehr lange Intervalle (schlafe zwölfmal je 30 Minuten, dann sind sechs Stunden vorbei) und sparsames Senden (miss jede Minute, aber schicke die Daten nur bei jedem zehnten Aufwachen per WLAN – das spart massiv Energie, weil der stromhungrige Verbindungsaufbau entfällt).
Das Praxisbeispiel: alle 20 Minuten einen Sensorwert senden
Jetzt bauen wir das zusammen, was in der Einleitung versprochen wurde. Der folgende Sketch weckt deinen ESP8266 alle 20 Minuten, verbindet ihn mit dem WLAN, schickt einen Sensorwert an einen Server und legt ihn wieder schlafen.
Zwei Details lohnen einen Blick. Erstens die Notbremse: Wenn der Router mal nicht antwortet, würde dein ESP ewig auf eine Verbindung warten und dabei die Batterie leersaugen. Nach 15 Sekunden geben wir deshalb auf und schlafen einfach weiter – beim nächsten Mal klappt es bestimmt wieder. Zweitens rechnen wir die Wachzeit heraus, damit das Intervall wirklich bei 20 Minuten bleibt.
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
const char* ssid = "DEIN_WLAN_NAME";
const char* password = "DEIN_WLAN_PASSWORT";
const char* serverUrl = "http://example.com/daten";
// Das gewünschte Intervall in Sekunden (20 Minuten)
const uint32_t INTERVALL = 20 * 60;
// Nach so vielen Millisekunden geben wir den Verbindungsversuch auf
const uint32_t WLAN_TIMEOUT = 15000;
void setup() {
Serial.begin(74880);
Serial.println();
Serial.println("Aufgewacht.");
// 1. Sensor auslesen
// Hier liest du deinen echten Sensor aus – zum Testen
// nehmen wir den analogen Eingang des ESP8266
int sensorwert = analogRead(A0);
Serial.print("Sensorwert: ");
Serial.println(sensorwert);
// 2. Mit dem WLAN verbinden
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
uint32_t startZeit = millis();
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
// Die Notbremse: Nach 15 Sekunden ohne Erfolg schlafen wir weiter
if (millis() - startZeit > WLAN_TIMEOUT) {
Serial.println();
Serial.println("Keine WLAN-Verbindung – neuer Versuch beim naechsten Mal.");
schlafen();
}
}
Serial.println();
Serial.print("Verbunden. IP: ");
Serial.println(WiFi.localIP());
// 3. Den Wert senden
WiFiClient client;
HTTPClient http;
http.begin(client, serverUrl);
http.addHeader("Content-Type", "application/json");
String daten = "{\"wert\":" + String(sensorwert) + "}";
int statusCode = http.POST(daten);
Serial.print("Antwort des Servers: ");
Serial.println(statusCode);
http.end();
// 4. Wieder schlafen legen
schlafen();
}
void schlafen() {
// Die Zeit abziehen, die wir wach waren – so bleibt das
// Intervall tatsächlich bei 20 Minuten
uint32_t wachSekunden = millis() / 1000;
uint32_t schlafSekunden = INTERVALL;
if (wachSekunden < INTERVALL) {
schlafSekunden = INTERVALL - wachSekunden;
}
Serial.print("Schlafe fuer ");
Serial.print(schlafSekunden);
Serial.println(" Sekunden.");
Serial.flush();
// Sekunden in Mikrosekunden umrechnen
ESP.deepSleep((uint64_t)schlafSekunden * 1000000ULL);
}
void loop() {
// Bleibt leer – siehe oben
}
Zum Testen setzt du INTERVALL am besten erst einmal auf 30 – 20 Minuten auf ein Ergebnis zu warten macht die Fehlersuche zäh.
Aufwecken ohne Timer
Nicht jedes Projekt braucht ein festes Intervall. Ein Briefkastenmelder soll sich nicht alle 20 Minuten melden, sondern genau dann, wenn die Klappe aufgeht.
Dafür übergibst du dem Deep Sleep eine 0:
// Schlafe unbegrenzt – bis ein Signal am RESET-Pin ankommt
ESP.deepSleep(0);
Dein ESP8266 schläft nun endlos. Aufwecken lässt er sich nur noch, indem der RESET-Pin auf GND gezogen wird – zum Beispiel durch einen Reed-Kontakt am Briefkastendeckel oder einen simplen Taster. Der Vorteil: Zwischen zwei Ereignissen verbraucht dein Projekt sehr wenig. Der Nachteil: Ohne Ereignis meldet sich dein ESP nie, du erfährst also auch nicht, ob er überhaupt noch lebt.
Wenn es nicht funktioniert
Die drei häufigsten Stolpersteine:
- Der ESP wacht nie wieder auf: In fast allen Fällen fehlt die Verbindung zwischen D0 und RST, oder das Kabel sitzt nicht richtig.
- Der Upload schlägt fehl: Ziehe das Kabel zwischen D0 und RST ab, lade den Sketch hoch und stecke es wieder auf.
- Im seriellen Monitor steht nur Zeichensalat: Stelle die Baudrate auf 74880 – das ist die Geschwindigkeit, mit der der ESP8266 seine eigenen Boot-Meldungen ausgibt.
Fazit
Der Deep Sleep des ESP8266 ist mit einem einzigen Kabel und einer Zeile Code eingerichtet – die eigentliche Kunst liegt woanders. Merke dir vor allem diese drei Dinge: Dein Programm startet nach jedem Aufwachen neu bei setup(). Werte, die den Schlaf überleben sollen, gehören in den RTC-Speicher. Und die größte Energieersparnis holst du nicht aus einem längeren Schlaf, sondern aus einer kürzeren Wachzeit und der passenden Hardware.