ESP32 Sleep-Modi verstehen und testen

Mit dem ESP32 Strom zu sparen ist einfacher als gedacht. Somit können sogar batteriebetriebene Lösungen realisiert werden, die energieeffizient arbeiten, um eine möglichst lange Betriebsdauer zu erreichen. Dafür bietet das ESP32 Mikrocontrollermodul verschiedene Energiesparmodi, um genau dieses Ziel zu erreichen.

Ermöglicht wird dies durch einen integrierten Ultra-Low-Power (ULP) Coprozessor, der es dem ESP32 erlaubt, z.B. in verschiedene Schlafmodi zu wechseln und gleichzeitig einfache Aufgaben wie die Überwachung von Sensoren oder das Zählen von Ereignissen auszuführen. Dadurch kann der Energieverbrauch des Systems erheblich reduziert werden, was besonders für Netzteil unabhängige Anwendungen von Vorteil ist.

Hier habe ich mal gegenübergestellt, welche Energieersparnis er in verschiedenen Szenarien hat und warum. Weiter unten werde ich Beispiele zeigen wie das in der Praxis aussehen könnte.


Der ESP32 bietet verschiedene Energiesparmaßnahmen:

  • Active Mode: Alle Funktionen des ESP32 sind voll aktiv, daher der höchste Stromverbrauch.
  • Modem Sleep: Wi-Fi-Modul und oder Bluetooth kann im Standby sein, während CPU weiterhin arbeitet.
  • Light Sleep: Die CPU pausiert, während RealTimeClock (RTC) und andere minimale Funktionen weiterlaufen.
  • Deep Sleep: Nur der RTC und der Speicher bleiben aktiv, um z.B. einen Timer oder einen Wakeup zu ermöglichen.
  • Hibernation: Minimaler Stromverbrauch; nur sehr wenige Funktionen wie zB. ein RTC-Timer bleiben aktiv. Einige ESP32-Modelle haben leicht unterschiedliche Implementierungen.

Je nach dem welcher Modi verwendet wird, sind somit die verbauten Komponenten mehr oder wenig in Gebrauch.
Hier eine Tabelle, die die verschiedenen Modi des Standard ESP32 mit den aktivierten und deaktivierten Komponenten mit theoretischen Stromverbrauchswerten vergleicht:

Unterschiede der unterschiedlichen ESP32 Varianten:

Bei der Vielfalt der Varianten gibt es auch noch unterschiede.
Hier ist eine Übersicht über einige ESP32-Varianten und ihre Unterstützung für den Ultra-Low-Power (ULP) Coprozessor sowie die Schlafmodi:

ESP32-VarianteULP-CoprozessorUnterstützte SchlafmodiBesonderheiten
ESP32 (Standard)JaActive, Modem Sleep, Light Sleep, Deep Sleep, HibernationUnterstützt alle Schlafmodi und bietet umfassende ULP-Funktionen.
ESP32-S2JaActive, Modem Sleep, Light Sleep, Deep SleepVerbesserte Energieeffizienz, aber keine Bluetooth-Unterstützung.
ESP32-C3JaActive, Modem Sleep, Light Sleep, Deep SleepRISC-V-Architektur, energieeffizient und ideal für IoT-Anwendungen.
ESP32-S3JaActive, Modem Sleep, Light Sleep, Deep SleepUnterstützt KI-Beschleunigung und hat mehr GPIOs als der Standard-ESP32.
ESP32-C6Ja (ULP LP Core)Active, Modem Sleep, Light Sleep, Deep SleepUnterstützt Wi-Fi 6 und hat einen verbesserten ULP-Coprozessor für niedrigeren Stromverbrauch.
ESP32-P4Ja (ULP LP Core)Active, Modem Sleep, Light Sleep, Deep SleepErweiterte Funktionen mit RISC-V-Architektur, für komplexe Aufgaben und energieeffiziente Anwendungen.

Eine erweiterte Version des ULP-Coprozessors verfügt der ESP32-C6 sowie der ESP32-P4, den sogenannten ULP LP Core. Dieser bietet zusätzliche Funktionen und ist für noch niedrigeren Stromverbrauch optimiert.
Weitere Varianten und deren Unterschiede siehe Orientierungshilfe beim Kauf von ESP32 Boards


Fünf Testaufbauten zum experimentieren:

Die nun folgenden Experimente sind weit weg von professionellen Messergebnissen und sind lediglich für mich ausschlaggebend gewesen, das ich mit einfachen mitteln in Erfahrung bringen kann, ob das anwenden der Sleep Modis einen sichtbaren Vorteil bringen.

Hardware:

Wähle ESP32 in der Boardverwaltung aus oder
installiere
notwendige Bibliotheken:

  • Öffne die Arduino IDE.
  • Gehe zu Tools > Board > Boards Manager und installiere „ESP32“.

Beispiel 1: Hibernation-Modus

Schritt 1: Programmieren

Kopiere diesen Code in die Arduino IDE:

#define uS_TO_S_FACTOR 1000000  // Umrechnung von Sekunden in Mikrosekunden
#define TIME_TO_SLEEP 10        // Zeit in Sekunden für den Sleep-Modus

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("ESP32 ist aufgewacht!");

  // Hier wird Code ausgeführt
  delay(10000);  // Wert in Millisekunden, 10 Sekunden Wachzeit (tu was)

  Serial.println("ESP32 geht jetzt in den Hibernation-Modus");
  
  // Hibernation-Modus starten
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  esp_deep_sleep_start();

  // Alles, was hier steht, wird **NICHT** ausgeführt!
  Serial.println("Das wird nie ausgegeben...");
}

void loop() {
  // Die loop() wird im Hibernation-Modus nicht ausgeführt!!!
}

Schritt 2: Hochladen und Testen

  • Lade den Code auf den ESP32 hoch.
  • Der ESP32 geht nach 10 Sekunden in den Deep-Sleep-Modus und wacht nach 10 Sekunden wieder auf.

3. Stromverbrauch messen (optional)

  • Verbinde ein Multimeter zwischen Stromquelle und ESP32.
  • Vergleiche den Stromverbrauch zwischen Normalbetrieb und Deep Sleep.

Deep Sleep Modus: Stromverbrauch soll schon mal unter 10 µA.
Aktiver Modus: Stromverbrauch kann je nach Nutzung von Wi-Fi/Bluetooth zwischen 54 mA und 240 mA liegen


Beispiel 2: Deep Sleep und Hibernation-Modus

Unterschied:

Hibernation-Modus: Hier ist, je nach Modell, nur der RTC-Timer als Wake-Up-Quelle möglich:

esp_sleep_enable_timer_wakeup() // für den RTC-Timer. Die Zeit wird in Mikrosekunden angegeben
esp_deep_sleep_start(); // Funktion starten

Alle anderen Quellen wie GPIO, Touchpads oder der ULP-Coprozessor sind in diesem Modus deaktiviert.

Deep-Sleep-Modus: Es sind mehrere Wake-Up-Funktionen möglich, darunter:

esp_sleep_enable_timer_wakeup() // für den RTC-Timer. Die Zeit wird in Mikrosekunden angegeben

esp_sleep_enable_ext0_wakeup() // für externe Signale über RTC-GPIO-Pins

esp_sleep_enable_ext1_wakeup()  // Ermöglicht das Aufwachen durch mehrere externe GPIO-Signale. 
// Nutzt den RTC-Controller, sodass mehrere RTC-GPIOs als Wake-Up-Quelle verwendet werden können
// Kann auf eine bestimmte Signaländerung (HIGH oder LOW) reagieren

esp_sleep_enable_touchpad_wakeup()  // Aktiviert das Aufwachen durch Berührungssensoren

esp_sleep_enable_ulp_wakeup()  // Ermöglicht das Aufwachen durch den Ultra-Low-Power (ULP) Coprozessor
// Der ULP kann einfache Aufgaben ausführen, während der Hauptprozessor schläft, und ihn bei bestimmten Ereignissen aufwecken.

// abschließend Funktion starten:
esp_deep_sleep_start();

Durch Drücken eines externen Tasters an Pin 33 wird der im Deep Sleep befindliche ESP32 geweckt:

Als Sketch das Beispiel aus der ESP32 Bibliothek. Öffne in der Arduino-IDE, unter Datei > Beispiele > ESP32 > Deep Sleep, den ExternalWakeUp-Sketch.

/*
  Deep Sleep with External Wake Up
  =====================================
  This code displays how to use deep sleep with
  an external trigger as a wake up source and how
  to store data in RTC memory to use it over reboots

  This code is under Public Domain License.

  Hardware Connections
  ======================
  Push Button to GPIO 33 pulled down with a 10K Ohm
  resistor

  NOTE:
  ======
  Only RTC IO can be used as a source for external wake
  source. They are pins: 0,2,4,12-15,25-27,32-39.

  Author:
  Pranav Cherukupalli <cherukupallip@gmail.com>
*/
#include "driver/rtc_io.h"

#define BUTTON_PIN_BITMASK(GPIO) (1ULL << GPIO)  // 2 ^ GPIO_NUMBER in hex
#define USE_EXT0_WAKEUP          1               // 1 = EXT0 wakeup, 0 = EXT1 wakeup
#define WAKEUP_GPIO              GPIO_NUM_33     // Only RTC IO are allowed - ESP32 Pin example
RTC_DATA_ATTR int bootCount = 0;

/*
  Method to print the reason by which ESP32
  has been awaken from sleep
*/
void print_wakeup_reason() {
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch (wakeup_reason) {
    case ESP_SLEEP_WAKEUP_EXT0:     Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1:     Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER:    Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD: Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP:      Serial.println("Wakeup caused by ULP program"); break;
    default:                        Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
  }
}

void setup() {
  Serial.begin(115200);
  delay(1000);  //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
    First we configure the wake up source
    We set our ESP32 to wake up for an external trigger.
    There are two types for ESP32, ext0 and ext1 .
    ext0 uses RTC_IO to wakeup thus requires RTC peripherals
    to be on while ext1 uses RTC Controller so does not need
    peripherals to be powered on.
    Note that using internal pullups/pulldowns also requires
    RTC peripherals to be turned on.
  */
#if USE_EXT0_WAKEUP
  esp_sleep_enable_ext0_wakeup(WAKEUP_GPIO, 1);  //1 = High, 0 = Low
  // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep.
  // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs.
  // No need to keep that power domain explicitly, unlike EXT1.
  rtc_gpio_pullup_dis(WAKEUP_GPIO);
  rtc_gpio_pulldown_en(WAKEUP_GPIO);

#else  // EXT1 WAKEUP
  //If you were to use ext1, you would use it like
  esp_sleep_enable_ext1_wakeup_io(BUTTON_PIN_BITMASK(WAKEUP_GPIO), ESP_EXT1_WAKEUP_ANY_HIGH);
  /*
    If there are no external pull-up/downs, tie wakeup pins to inactive level with internal pull-up/downs via RTC IO
         during deepsleep. However, RTC IO relies on the RTC_PERIPH power domain. Keeping this power domain on will
         increase some power consumption. However, if we turn off the RTC_PERIPH domain or if certain chips lack the RTC_PERIPH
         domain, we will use the HOLD feature to maintain the pull-up and pull-down on the pins during sleep.
  */
  rtc_gpio_pulldown_en(WAKEUP_GPIO);  // GPIO33 is tie to GND in order to wake up in HIGH
  rtc_gpio_pullup_dis(WAKEUP_GPIO);   // Disable PULL_UP in order to allow it to wakeup on HIGH
#endif
  //Go to sleep now
  Serial.println("Going to sleep now");
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop() {
  //This is not going to be called
}

Test mit Schalter

Wer tiefergehende Test ausführen möchte, wird hier in diesem Sketch das Aufwachen durch externes Signal mittels RTC_CNTL oder durch Timer, Touchpad oder ULP-Programm ausprobieren können.
Bitte beachten: Der ESP32 kann mehrere Touchpads als Aufweckquelle aktivieren. Die ESP32-S2- und ESP32-S3-Modelle unterstützen jedoch nur 1 Touchpad als Aufweckquelle.



Beispiel 3: Light Sleep Modus

Der ESP32 bietet den Light Sleep Modus, um Energie zu sparen, während er trotzdem schnell auf externe Ereignisse wie Tastenanschläge reagieren kann.
Der Light Sleep Modus pausiert die CPU, während wichtige Peripheriegeräte wie GPIOs aktiv bleiben. Dadurch wird weniger Strom verbraucht, und der ESP32 kann durch Ereignisse wie Berührungen, GPIO-Signale oder Timer schnell aufwachen.
Dieses Beispiel zeigt, wie der ESP32 in den Light Sleep Modus versetzt wird und wie du ihn praktisch testen kannst.

Kopiere diesen Code in die Arduino IDE:

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("ESP32 geht in den Light Sleep Modus...");

  // GPIO 0 als Wake-Up-Quelle aktivieren
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); // Aufwachen bei LOW-Signal an GPIO 33

  // Light Sleep aktivieren
  esp_light_sleep_start();

  // Nachricht nach dem Aufwachen
  Serial.println("ESP32 wurde geweckt!");
}

void loop() {
Serial.println("Loop wird nach dem Aufwachen ausgeführt...");
delay(1000);
}

Hochladen und Testen

  1. Schließe den ESP32 an und lade den Code hoch.
  2. Der ESP32 geht in den Light Sleep Modus und wartet auf ein LOW-Signal (z. B. durch Drücken eines Tasters am GPIO 0).
  3. Drücke den Taster, um den ESP32 zu wecken. Die Konsole zeigt eine Nachricht nach dem Aufwachen an.

Teststart im Light Sleep Modus mit Schalter

Wieder Stromverbrauch messen (optional)

Light Sleep Modus: Stromverbrauch liegt im Bereich von 1 mA bis 17 mA.
Aktiver Modus: Stromverbrauch kann je nach Nutzung von Wi-Fi/Bluetooth zwischen 54 mA und 240 mA liegen


Beispiel 4: Modem Sleep Modus

Der Modem Sleep Modus des ESP32 ist ideal, wenn die CPU aktiv bleibt, aber die Wi-Fi-Funktion deaktiviert wird, um Energie zu sparen. Dieser Modus eignet sich besonders für Anwendungen, bei denen nur gelegentlich Daten übertragen werden und die restliche Zeit keine Netzwerkverbindung benötigt wird.
Im Modem Sleep Modus bleibt die CPU eingeschaltet, während das Wi-Fi-Modul deaktiviert ist. Dies spart Strom, ohne die Verarbeitung durch den Mikrocontroller zu unterbrechen.

Kopiere diesen Code in die Arduino IDE:

#include <WiFi.h>
#include "esp_wifi.h"

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("ESP32 geht in den Modem Sleep Modus...");

  WiFi.mode(WIFI_MODE_STA); // Station-Modus aktivieren
  esp_wifi_set_ps(WIFI_PS_MIN_MODEM); // Minimaler Modem Sleep Modus

  delay(10000);
  esp_wifi_set_ps(WIFI_PS_NONE); // Modem Sleep deaktivieren
  Serial.println("Wi-Fi ist wieder aktiviert!");
}

void loop() {
  Serial.println("ESP32 läuft im Modem Sleep Modus...");
  delay(2000);
}

Schritt 2: Hochladen und Testen

  1. Schließe den ESP32 an und lade den Code hoch.
  2. Der ESP32 deaktiviert das Wi-Fi-Modul und aktiviert es nach 10 Sekunden wieder.
  3. Überprüfe die Funktion durch die Meldungen in der Konsole.

Mein Ergebnis:

  1. Im Seriellen Monitor wir wie erwartet die beiden Meldungen ausgegeben
  2. Mit meinem kleinen Messgerät jedoch konnte ich keine Stromersparnisse entdecken.

Beispiel 5: Erweiterte Version des ULP-Coprozessors beim ESP32-C6

Im fünften Beispiel wollte ich mit der Arduino IDE die ULP LP Core Mode des ESP32-C6 testen.

Es gibt aktuell (Stand April 2025) wohl noch keine Bibliothek für die Arduino IDE und somit standardmäßig keine Unterstützung für den ULP LP Core des ESP32-C6.

Wer derzeit die erweiterten ULP LP Core Funktionen nutzen möchte, sollten Sie die ESP-IDF verwenden, da diese die vollständige Unterstützung für den ESP32-C6 und den ULP LP Core bietet.

Siehe ULP LP Core Coprocessor Programming – ESP32-C6 – — ESP-IDF Programming Guide v5.4.1 documentation


Anwendungsbeispiele:

Hier sind einige spannende Anwendungen, bei denen der Ultra-Low-Power Coprozessor des ESP32 genutzt werden kann:

  1. Umweltüberwachung: Ein Projekt zur Überwachung der Luftqualität oder Temperatur, bei dem der ULP Sensoren wie ein CO2-Sensor oder ein Temperatursensor ausliest und die Daten im Tiefschlafmodus speichert. Der Hauptprozessor wird nur bei bestimmten Schwellenwerten geweckt.
  2. Intelligente Bewässerungssysteme: Der ULP überprüft den Bodenfeuchtigkeitsstatus durch Sensoren und löst das Bewässerungssystem aus, wenn der Feuchtigkeitsgehalt unter einen bestimmten Wert fällt.
  3. Zähler von Ereignissen: Der ULP zählt Ereignisse wie Schläge auf eine Oberfläche, z. B. für ein Schlagzeugprojekt, oder Schritte bei einem Schrittzähler, ohne den Hauptprozessor zu aktivieren.
  4. Wearables: Der ULP kann in tragbaren Geräten eingesetzt werden, um Bewegungen und Vitaldaten kontinuierlich zu überwachen, ohne die Akkulaufzeit erheblich zu beeinträchtigen.
  5. Fernüberwachung: Ein kabelloses Sensorsystem, bei dem der ULP Daten von verschiedenen Sensoren sammelt und sie erst über Funk sendet, wenn ein kritisches Ereignis oder eine Zeitüberschreitung eintritt.
  6. Tür- und Fensterüberwachung: Der ULP kann GPIO-Pins überwachen, um zu erkennen, ob eine Tür oder ein Fenster geöffnet wurde, und bei Bedarf einen Alarm auslösen.

Diese Projekt Beispiele kombinieren Energieeffizienz mit praktischen Funktionen.


Quellen:

https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/sleep_modes.html

Im Detail: ESP32 Deep Sleep & Wakeup Quellen | Timer, Touch & Extern

Video:

Erwähnenswert sind aber durchaus die zusätzlichen Konfigurationsmöglichkeiten, wie:

  1. Power-Down-Optionen:
    Das gezielte Abschalten bestimmter Peripheriegeräte.
  2. Kombination von Wake-Up-Quellen:
    Es gibt auch die Möglichkeit, mehrere Quellen zu kombinieren, sodass der ESP32 auf verschiedene Ereignisse reagieren kann.
  3. ESP8266: Oder wer noch ältere ESP8266 verwendet, die bieten auch Schlafmodi, wenn auch weniger fortschrittlich.
  4. Optimierung der Stromsparmodi: Es gibt verschiedene Techniken zur weiteren Optimierung des Stromverbrauchs, wie das gezielte Abschalten von RAM-Bereichen oder das Nutzen externer Komponenten zur Energieverwaltung.
, ,
Datenschutz-Übersicht

Diese Website verwendet Cookies, damit wir dir die bestmögliche Benutzerkomfort bieten können. Cookie-Informationen werden in deinem Browser gespeichert und führen Funktionen aus, wie das Wiedererkennen von dir, wenn du auf unsere Website zurückkehrst und hilft uns zu verstehen, welche Abschnitte der Website für dich am interessantesten und nützlichsten sind.