Der ESP32 verbraucht je nach Betriebsmodus relativ viel Energie. Bei Stromversorgung über eine Steckdose ist der Energieverbrauch kein großes Problem. Bei Betrieb mit Akku ist jedoch Energieeinsparung wichtig, um die Lebensdauer unserer Energiequelle so lange wie möglich zu erhalten.
Der ESP32-Chip enthält einen Dual-Core-32-Bit-Mikroprozessor mit integrierter WiFi- und Bluetooth-Unterstützung, was ihn zu einem noch energieintensiveren Mikrocontroller macht.
Wenn das ESP32-Projekt nicht ständig aktiv sein muss, kann es eine gute Lösung sein, einen der Schlafmodi des ESP32 zu nutzen, um den Energieverbrauch zu senken und die Lebensdauer des Akkus deutlich zu verlängern.
Werbung
Die auf dieser Website angezeigten Werbung hilft bei der Aufrechterhaltung der Website.
Dank seines fortschrittlichen Energiemanagements bietet der ESP32 fünf konfigurierbare Energiemanagementmodi. Je nach Energiebedarf der Anwendung kann zwischen fünf verschiedenen Energiemanagementmodi des Chips gewählt werden. Der Wechsel zwischen den Modi ist sogar während der Programmausführung möglich.
Die ESP32 Betriebsarten sind wie folgt:
ESP32-Aktivmodus
Der aktive Modus des ESP32 ist der normale Betriebsmodus, in dem die CPU-Kerne arbeiten, das WiFi- und Bluetooth-Modul aktiviert sind und alle Peripheriegeräte aktiv sind.
Blockdiagramm des ESP32-Chips im aktiven Modus:

Da in diesem Modus alles aktiv ist, liegt der Stromverbrauch des ESP32 zwischen 95 und 240 mA, abhängig von der Nutzung von WLAN und Bluetooth sowie der CPU-Taktfrequenz. Es ist wichtig zu beachten, dass sich dieser Stromverbrauchswert auf den ESP32-Chip bezieht und nicht auf die gesamte ESP32-Entwicklerkarte.
Im aktiven Modus besteht die einzige Möglichkeit zur Energieeinsparung darin, die CPU-Taktfrequenz zu regulieren und/oder den RF-Modus entsprechend den Anforderungen der Anwendung und der folgenden Tabelle zu ändern.
| Stromverbrauch je nach RF-Modus | |
|---|---|
| Transmit 802.11b, DSSS 1 Mbps, POUT = +19.5 dBm | 240 mA |
| Transmit 802.11g, OFDM 54 Mbps, POUT = +16 dBm | 190 mA |
| Transmit 802.11n, OFDM MCS7, POUT = +14 dBm | 180 mA |
| Receive 802.11b/g/n | 95 ~ 100 mA |
| Transmit BT/BLE, POUT = 0 dBm | 130 mA |
| Receive BT/BLE | 95 ~ 100 mA |
Einstellung der Leistungsstufe des WLAN-Funkfrequenzbereichs:
#include "esp_wifi.h"
...
// esp_wifi_set_max_tx_power(int level);
esp_wifi_set_max_tx_power(14); // +14 dBm
Einstellung der Leistung des klassischen Bluetooth-Senders:
#include "esp_bt.h"
....
// esp_err_t esp_bredr_tx_power_set(esp_power_level_t min_power_level, esp_power_level_t max_power_level);
esp_bredr_tx_power_set(ESP_PWR_LVL_N6, ESP_PWR_LVL_N0);
Die standardmäßige Mindestleistung ist „ESP_PWR_LVL_N0“, die maximale Leistung ist „ESP_PWR_LVL_P3“.
Die folgende Tabelle enthält die möglichen Leistungsparameter:
| Bluetooth-Leistungsstufen: | |
|---|---|
| ESP_PWR_LVL_N12 | -12dbm |
| ESP_PWR_LVL_N9 | -9dbm |
| ESP_PWR_LVL_N6 | -6dbm |
| ESP_PWR_LVL_N3 | -3dbm |
| ESP_PWR_LVL_N0 | 0dbm |
| ESP_PWR_LVL_P3 | +3dbm |
| ESP_PWR_LVL_P6 | +6dbm |
| ESP_PWR_LVL_P9 | +9dbm |
| ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12 | Abwärtskompatibilität! Wenn wir -14 dBm einstellen, ergibt dies tatsächlich -12 dBm.. |
| ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9 | Abwärtskompatibilität! Wenn wir -11 dBm einstellen, ergibt dies tatsächlich -9 dBm. |
| ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6 | Abwärtskompatibilität! Wenn wir -8 dBm einstellen, ergibt dies tatsächlich -6 dBm. |
| ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3 | Abwärtskompatibilität! Wenn wir -5 dBm einstellen, ergibt dies tatsächlich -3 dBm. |
| ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0 | Abwärtskompatibilität! Wenn wir -2 dBm einstellen, ergibt dies tatsächlich 0 dBm. |
| ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3 | Abwärtskompatibilität! Wenn wir +1 dBm einstellen, ergibt dies tatsächlich +3 dBm. |
| ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6 | Abwärtskompatibilität! Wenn wir +4 dBm einstellen, ergibt dies tatsächlich +6 dBm. |
| ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9 | Abwärtskompatibilität! Wenn wir +7 dBm einstellen, ergibt dies tatsächlich +9 dBm. |
werbung
BLE-Sendeleistung einstellen:
#include "esp_bt.h"
....
// esp_err_t esp_bredr_tx_power_set(esp_power_level_t min_power_level, esp_power_level_t max_power_level);
esp_bredr_tx_power_set(ESP_PWR_LVL_N6, ESP_PWR_LVL_N0);
Die folgende Tabelle zeigt die Leistungsparameter des BLE-Typs:
| BLE-Leistungstypen | |
|---|---|
| ESP_BLE_PWR_TYPE_CONN_HDL0 | TX-Leistung für Operator 0. |
| ESP_BLE_PWR_TYPE_CONN_HDL1 | TX-Leistung für Operator 1. |
| ESP_BLE_PWR_TYPE_CONN_HDL2 | TX-Leistung für Operator 2. |
| ESP_BLE_PWR_TYPE_CONN_HDL3 | TX-Leistung für Operator 3. |
| ESP_BLE_PWR_TYPE_CONN_HDL4 | TX-Leistung für Operator 4. |
| ESP_BLE_PWR_TYPE_CONN_HDL5 | TX-Leistung für Operator 5. |
| ESP_BLE_PWR_TYPE_CONN_HDL6 | TX-Leistung für Operator 6. |
| ESP_BLE_PWR_TYPE_CONN_HDL7 | TX-Leistung für Operator 7. |
| ESP_BLE_PWR_TYPE_CONN_HDL8 | TX-Leistung für Operator 8. |
| ESP_BLE_PWR_TYPE_ADV | TX-Leistung für die Ankündigung. |
| ESP_BLE_PWR_TYPE_SCAN | TX-Leistung für das Scannen. |
| ESP_BLE_PWR_TYPE_DEFAULT | Standardmäßiger TX-Leistungstyp, mit dem die Leistung von zuvor nicht eingestellten Leistungstypen eingestellt werden kann. |
| ESP_BLE_PWR_TYPE_NUM | Anzahl der Typen. |
Zweifellos verbraucht dieser Modus am meisten Strom und ist am wenigsten energieeffizient. Um Energie zu sparen, sollten wir zu einem anderen energiesparenden Modus wechseln.
Werbung
Die auf dieser Website angezeigten Werbung hilft bei der Aufrechterhaltung der Website.
Modem-Schlafmodus
Im Modem- Schlafmodus arbeiten die ESP32-Prozessorkerne und alle anderen Peripheriegeräte, die Uhr ist konfigurierbar, Radio, WLAN und Bluetooth sind deaktiviert.
Blockdiagramm des ESP32 im Modem-Schlafmodus:

Mit dem ESP32 können wir mit einem Befehl den Leichtschlafmodus oder den Tiefschlafmodus aktivieren, aber die Aktivierung des Modem-Schlafmodus ist nicht unbedingt so einfach. Es kann sein, dass mehrere Schritte erforderlich sind, um dies zu erreichen.
Wenn der Schlafmodus des Modems aktiviert ist, wechselt das WLAN-Modul (nur im Station-Modus) nach erfolgreicher Verbindung mit dem Zugangspunkt regelmäßig zwischen dem aktiven und dem Schlafmodus. Auch Bluetooth wechselt zwischen dem aktiven und dem Schlafmodus.
Das ESP32-Modem kann im Schlafmodus die Verbindung zum Zugangspunkt aufrechterhalten, indem es DTIM (Delivery Traffic Indication Message) verwendet. Die Grundidee von DTIM basiert auf der Beacon-Technik. Es sendet regelmäßig Nachrichten über das Netzwerk und fordert damit alle Stationen auf, aus dem Schlafmodus aufzuwachen, sich mit dem Netzwerk zu synchronisieren und dann wieder in den Schlafmodus zu wechseln. Dadurch kann Energie gespart werden.
Das WLAN-Modul ist zwischen zwei DTIM-Beacons deaktiviert und wird automatisch aktiviert, sobald das nächste Beacon eintrifft. Die Zeit zwischen zwei DTIM-Beacons bestimmt also die Schlafzeit des ESP32-Modems.
Drei mögliche Einstellungen für den Modem- Schlafmodus.
Minimaler Modem-Schlaf.
Wenn der Schlafmodus (modem sleep) des Modems aktiviert ist, werden die empfangenen WLAN-Daten nach der DTIM-Periode übertragen, sodass die übertragenen Daten nicht verloren gehen. Das Problem ist, dass wir bei hohem Datenverkehr in unserem Netzwerk viele Beacon-Nachrichten erhalten können.
Für die Verwendung müssen wir nichts tun, da dies die Standardeinstellung des WLAN-Modems ist. Es ist erforderlich, wenn wir zuvor den Modus des Modems geändert haben. Zurücksetzen können wir mit der Funktion „setSleep()” im Verzeichnis „Wifi.h”.
#include <Wifi.h>
....
WiFi.setSleep(true);
Für die Energiespareinstellungen des WLAN-Modems können wir auch die Low-Level-Befehle des ESP-IDF-Frameworks in unserem Code verwenden. Dazu müssen wir die Bibliothek „esp_wifi.h” importieren, um die Funktion „esp_wifi_set_ps()” verwenden zu können. Diese verwenden wir wie folgt:
#include <esp_wifi.h>
....
esp_wifi_set_ps(WIFI_PS_MIN_MODEM);
Maximaler Modem-Schlaf.
Wenn der maximale Schlafmodus des Modems aktiviert ist, wird die Kommunikation in regelmäßigen Abständen überprüft und nicht nur bei Eingang von Beacon-Nachrichten. Bei hohem Netzwerkverkehr kann sich der Energieverbrauch etwas verbessern, jedoch können die übertragenen Daten verloren gehen, da sich das WLAN-Modul während DTIM möglicherweise im Schlafmodus befindet.
Da die Bibliothek „Wifi.h” keine entsprechende Anweisung enthält, müssen wir zur Aktivierung des maximalen Modem- Schlafmodus die Low-Level-Funktion des ESP-IDF-Frameworks verwenden. Dazu müssen wir die Bibliothek „esp_wifi.h” importieren, um die Funktion „esp_wifi_set_ps(WIFI_PS_MAX_MODEM)” nutzen zu können.
#include <esp_wifi.h>
....
esp_wifi_set_ps(WIFI_PS_MAX_MODEM);
Mini PC 16GB DDR4 512GB ROM, Intel Celeron N5105 bis zu 2,9 GHz
Windows 11 Pro Mini Computer mit 2xHDMI+VGA 4K Triple Display, WiFi 5, RJ45-LAN, BT 4.2
werbung
Modem-Schlafmodus deaktivieren.
Dieser Modus deaktiviert den Schlafmodus des Modems vollständig. Dies führt zu einem deutlich höheren Energieverbrauch, gewährleistet jedoch eine minimale Verzögerung beim Empfang von Daten in Echtzeit über das WLAN-Netzwerk.
Auch hier kann die Funktion „setSleep()” aus dem Verzeichnis „Wifi.h” verwendet werden.
#include <Wifi.h>
....
WiFi.setSleep(false);
Oder importieren wir die Bibliothek „esp_wifi.h”, um die Funktion „esp_wifi_set_ps(WIFI_PS_NONE )” zu verwenden.
#include <esp_wifi.h>
....
esp_wifi_set_ps(WIFI_PS_NONE);
Deaktivierung der Elemente der Radio-Gruppe.
Es ist ziemlich unklar, was zur Realisierung des Modem- Schlafmodus gehört. Einige sagen, dass die vollständige Deaktivierung der Funkgruppe erforderlich ist, andere sagen, dass der minimale Schlafmodus des WLAN-Modems (der übrigens der Standardmodus ist) ausreicht.
Auf jeden Fall können wir weitere Energieeinsparungen erzielen, indem wir das Bluetooth-Funkmodul ausschalten, wenn wir es nicht verwenden.
btStop();
Wenn wir das WLAN nicht benötigen, können wir es auch deaktivieren. Zuerst deaktivieren wir das WLAN mit der Funktion „WiFi.disconnect(true);”, dann deaktivieren wir mit der Funktion „WiFi.mode(WIFI_OFF);” den Betrieb des WLAN-Modems.
#include <Wifi.h>
...
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
Dadurch ändert sich der durchschnittliche Energieverbrauch nicht wesentlich, aber es reagiert nicht auf DTIM-Beacon-Nachrichten, sodass der Stromverbrauch beim Empfang von WLAN-Daten nicht mehr ansteigt. Dadurch können wir einige mA einsparen.
Um das WLAN wiederherzustellen, müssen die folgenden Funktionen ausgeführt werden:
#include <Wifi.h>
...
WiFi.disconnect(false);
WiFi.mode(WIFI_STA);
WiFi.begin(STA_SSID, STA_PASS);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
}
Touchscreen-Tastatur, Türriegelschlösser, Smartes Türschloss, Elektronisches Türschloss, Türöffner per App, Fingerprint, Code, Alexa, Google, unterstützt Matter
werbung
Reduzieren wir die CPU-Taktfrequenz.
Der Stromverbrauch hängt stark von der Taktfrequenz der CPU ab. Auch in diesem Modus lassen sich durch eine Verringerung der Taktfrequenz der CPU bessere Ergebnisse erzielen. Eine Verringerung der Taktfrequenz senkt den Stromverbrauch, eine Erhöhung der Taktfrequenz hingegen erhöht den Energieverbrauch.
Die folgende Tabelle zeigt den Energieverbrauch in Abhängigkeit von der Taktfrequenz der CPU.
| CPU-Frequenz | Energieverbrauch |
|---|---|
| 240 MHz | 30 mA ~ 68 mA |
| 160 MHz | 27 mA ~ 44 mA |
| 80 MHz | 20 mA ~ 31 mA |
Es gibt eine Funktion zum Einstellen der CPU-Frequenz, nämlich „setCpuFrequencyMhz(Frequenz)“.
setCpuFrequencyMhz(80);
Und es gibt eine Funktion zum Abrufen der CPU-Frequenz, „getCpuFrequencyMhz()“.
Serial.println(getCpuFrequencyMhz());
void setup()
{
Serial.begin(115200);
delay(2000);
Serial.print("basic frequency: ");
Serial.println(getCpuFrequencyMhz());
delay(1000);
setCpuFrequencyMhz(80);
delay(2000);
Serial.print("1. modified frequency: ");
Serial.println(getCpuFrequencyMhz());
setCpuFrequencyMhz(40);
delay(2000);
Serial.print("2. modified frequency: ");
Serial.println(getCpuFrequencyMhz());
}
void loop(){}
Werbung
Die auf dieser Website angezeigten Werbung hilft bei der Aufrechterhaltung der Website.
Leicht-Schlafmodus
Im Light-Sleep-Modus des ESP32 funktionieren WLAN und Bluetooth nicht, die CPU wird angehalten (sie arbeitet taktsignalgesteuert) und ein Großteil des RAM sowie die digitalen Peripheriegeräte werden abgeschaltet.
Das Blockdiagramm des ESP32 im Light-Sleep-Modus sieht wie folgt aus:

Der Wechsel in den Schlafmodus kann fehlschlagen, wenn aktiver WLAN- oder Bluetooth-Datenverkehr vorliegt. Es kann sinnvoll sein, die Verbindung vorher zu unterbrechen.
btStop();
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
Der Schlafmodus des ESP32 kann mit der folgenden Funktion aktiviert werden.
esp_light_sleep_start();
Bevor wir den Leichtschlafmodus aktivieren können, müssen wir den Weckmodus des Systems festlegen, dann können wir den Leichtschlafmodus starten.
Wenn wir ohne Konfiguration der Weckquellen in den Schlafmodus wechseln, bleibt der Chip auf unbestimmte Zeit im Schlafmodus, bis wir einen externen Reset durchführen.
Beim Verlassen des Leichtschlafmodus setzt die CPU den Betrieb dort fort, wo sie ihn unterbrochen hat, wobei der Zustand der Peripheriegeräte und die Werte der Variablen erhalten bleiben.
Das Aufwachen des ESP32-Chips aus dem Leichtschlafmodus ist wie im Kapitel Weckquellen beschrieben möglich.
Tief-Schlafmodus
Im Tiefschlafmodus (Deep Sleep) des ESP32 werden die CPU-Kerne, ein Großteil des RAM und alle vom Advanced Peripheral Bus (APB_CLK) gesteuerten digitalen Peripheriegeräte ausgeschaltet. Der Echtzeituhr-Controller (RTC), der Ultra Low Power (ULP)-Coprozessor, die RTC-Peripheriegeräte und die RTC-Speicher bleiben jedoch weiterhin verfügbar.
Blockdiagramm des ESP32 im Deep-Sleep-Modus:

Vor der Aktivierung des Tiefschlafmodus des ESP32 muss der Weckmodus des Systems festgelegt werden.
Wenn wir ohne Angabe von Weckquellen in den Schlafmodus wechseln, bleibt der esp32 so lange im Schlafmodus, bis wir einen externen Reset durchführen.
Der Tiefschlafmodus kann mit der folgenden Funktion aktiviert werden:
esp_deep_sleep_start();
Jedes Mal, wenn der ESP32 aus dem Tiefschlaf erwacht, führt er einen vollständigen Neustart durch, anstatt dort fortzufahren, wo er die Ausführung des Programms unterbrochen hat.
Wenn wir Daten speichern und nach dem Aufwachen aus dem Tiefschlaf abrufen müssen, müssen wir diese im RTC-Speicher speichern. Die hier gespeicherten Daten gehen im Tiefschlafmodus nicht verloren, werden aber gelöscht, wenn die Reset-Taste gedrückt wird.
RTC_DATA_ATTR int myData = 0;
Das Zurückkehren aus dem Tiefschlafmodus ist mit einer der im Kapitel Weckquellen beschriebenen Methoden möglich.
werbung
Hibernation-Modus
Der Hibernation-Modus des ESP32 ist eigentlich ein erweiterter Tiefschlafmodus, dessen Ziel es ist, den Energieverbrauch auf ein Minimum zu reduzieren. Dieser Zustand wird durch das Abschalten praktisch aller nicht lebenswichtigen Einheiten erreicht.
Im Hibernation-Modus des ESP32 werden alle Oszillatoren, der RTC-Peripheriebereich und die RTC-Speicher sowie der Ultra Low Power (ULP)-Coprozessor deaktiviert.

Im Hibernation-Modus ist nur ein RTC-Timer mit langsamer Taktfrequenz verfügbar, und nur bestimmte RTC-GPIO-Pins sind aktiv, die zum Aufwachen aus dem Hibernation-Modus erforderlich sind. Damit kann ein extrem niedriger Stromverbrauch von bis zu 5 µA erreicht werden.
Die Funktion „esp_sleep_pd_config()” hilft bei der Verwaltung der Energiebereiche des ESP32-Chips.
esp_sleep_pd_config(domain, option);
| Energiebereich Domain | |
|---|---|
| ESP_PD_DOMAIN_RTC_PERIPH | RTC Peripherien |
| ESP_PD_DOMAIN_RTC_FAST_MEM | RTC-Schnellspeicher (ULP-Programme). |
| ESP_PD_DOMAIN_RTC_SLOW_MEM | RTC- Langsamspeicher (ULP-Daten). |
| ESP_PD_DOMAIN_XTAL | Quarzoszillator |
| Optionen für Domains | |
|---|---|
| ESP_PD_OPTION_OFF | Ausschalten der angegebenen Domain |
| ESP_PD_OPTION_ON | Einschalten der angegebenen Domain |
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF);
Dann können wir den Hibernation-Modus aktivieren..
esp_deep_sleep_start();
Da auch der RTC-Speicher ausgeschaltet wird, können im Schlafmodus keine Daten gespeichert werden. In diesem Fall besteht die einzige Möglichkeit zur Datensicherung darin, die Daten in den EEPROM zu schreiben.
#include <EEPROM.h>
int myData = 1;
void setup()
{
EEPROM.begin(1);
}
void loop()
{
myData = 5;
EEPROM.write(0, myData);
EEPROM.commit();
}
Shelly Pro 4PM
Shelly Pro 4PM Professioneller Relaisschalter 4 Kontakte
Professionelles 4-Kanal-Relais mit Wi-Fi-, LAN- und Bluetooth-Anschluss, geeignet für die Haus- und Gebäudeautomation mit Fernsteuerung und präzisem Energiemanagement.
Montage auf DIN-Schiene in Schalterkasten. Erweiterte Sicherheitsfunktionen und kompatibel mit den meisten gängigen Plattformen.
werbung – amazon.de
Weckquellen, Beispiele
Timer-Wecker
Der RTC-Timer kann mit der Funktion esp_sleep_enable_timer_wakeup() so eingestellt werden, dass er den ESP32 in bestimmten Zeitabständen aus dem Leicht-/Tiefschlafmodus weckt. Das folgende Beispiel weckt den ESP32_t nach 5 Sekunden auf.
esp_sleep_enable_timer_wakeup(5 * 1000000); // 5 sec
esp_light_sleep_start();
Sehen wir uns ein Beispiel für die Rückkehr aus dem Leichtschlaf an..
byte ledPin = 4;
void setup()
{
Serial.begin(115200);
delay(50);
Serial.println("starting...");
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
delay(2000);
digitalWrite(ledPin, HIGH);
delay(2000);
Serial.println("go to light sleep...");
delay(50);
esp_sleep_enable_timer_wakeup(5 * 1000000); // 5 sec
esp_light_sleep_start();
Serial.println("hi again here!");
}
void loop(){}
Wie wir sehen können, setzt das esp32 nach dem Aufwachen aus dem Leichtschlafmodus die Ausführung des Programms dort fort, wo es aufgehört hat, also erscheint die Begrüßung „hi again here!” auf dem seriellen Monitor und die angeschlossene LED leuchtet kontinuierlich.
Schauen wir uns an, was mit unserem Programm passiert, wenn wir das esp32 in den Tiefschlaf versetzen.
byte ledPin = 4;
void setup()
{
Serial.begin(115200);
delay(50);
Serial.println("starting...");
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
delay(2000);
digitalWrite(ledPin, HIGH);
delay(2000);
Serial.println("go to deep sleep...");
delay(50);
esp_sleep_enable_timer_wakeup(5 * 1000000); // 5 sec
esp_deep_sleep_start();
Serial.println("you never see this: hi again here!");
}
void loop(){}
In diesem Fall startet der esp32 nach dem Aufwachen neu. Die Ein- und Ausgänge werden neu initialisiert und behalten ihren vorherigen Zustand nicht bei. Die Programmzeilen nach der Funktion „esp_deep_sleep_start()” werden nie ausgeführt.
Meross Smart Heizkörperthermostat
Meross smartes Heizkörperthermostat inklusive Hub, WLAN Heizungsthermostat Kompatibel mit HomeKit, Alexa und Google Assistant,Sprachsteuerung Zeitpläne Automation Fensteröffnungserkennung, M30*1,5mm
werbung – amazon.de
Das Aufwachen durch ein externes Ereignis (z. B. Tastendruck) ist eine weitere Möglichkeit, den ESP32 aufzuwecken. Es gibt zwei Optionen für das externe Aufwachen: ext0 und ext1.
Externe Weckfunktion (ext0)
Der ESP32 verfügt über 16 RTC-GPIOs, die Teil des RTC-Low-Power-Subsystems sind. Diese RTC-GPIOs können den ESP32 aus einer externen Quelle aufwecken, wenn der Ultra Low Power (ULP)-Coprozessor läuft.
Ext0-Wecken bedeutet, dass wir den ESP32 aus dem Schlafmodus wecken können, indem wir eine Taste drücken, die an einen RTC-GPIO angeschlossen ist.
Um die Weckquelle des ESP32 zu nutzen, können wir die folgende Funktion verwenden:
esp_sleep_enable_ext0_wakeup(GPIO_pin_num, level);
Das erste Argument der Funktion ist die GPIO-Nummer des zu verwendenden Fußes. Der zweite Parameter gibt den Zustand des GPIO an, der den Weckruf auslöst. Dieser kann 1 oder 0 sein.
Die dedizierten Pins des RTC GPIO sind in der folgenden Abbildung dargestellt:
| RTC_GPIO0 | GPIO36 |
| RTC_GPIO3 | GPIO39 |
| RTC_GPIO4 | GPIO34 |
| RTC_GPIO5 | GPIO35 |
| RTC_GPIO6 | GPIO25 |
| RTC_GPIO7 | GPIO26 |
| RTC_GPIO8 | GPIO33 |
| RTC_GPIO9 | GPIO32 |
| RTC_GPIO10 | GPIO4 |
| RTC_GPIO11 | GPIO0 |
| RTC_GPIO12 | GPIO2 |
| RTC_GPIO13 | GPIO15 |
| RTC_GPIO14 | GPIO13 |
| RTC_GPIO15 | GPIO12 |
| RTC_GPIO16 | GPIO14 |
| RTC_GPIO17 | GPIO27 |
Auf dem folgenden Bild sehen wir die RTC_GPIO-Pins auf der 38-poligen ESP32-Entwicklerkarte:

Ein Beispiel für das Aufwecken des esp32 aus dem Tiefschlaf durch Drücken einer Taste.
const gpio_num_t ledPin = GPIO_NUM_4;
const gpio_num_t wakePin = GPIO_NUM_0;
int wakeLevel = 0;
void setup()
{
Serial.begin(115200);
delay(50);
Serial.println("starting...");
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
delay(2000);
digitalWrite(ledPin, HIGH);
delay(2000);
Serial.println("go to deep sleep...");
delay(50);
esp_sleep_enable_ext0_wakeup(wakePin, wakeLevel);
esp_deep_sleep_start();
Serial.println("you never see this");
}
void loop(){}
Dieser Weckmodus funktioniert auch bei Leichtschlaf:
const gpio_num_t ledPin = GPIO_NUM_4;
const gpio_num_t wakePin = GPIO_NUM_0;
int wakeLevel = 0;
void setup()
{
Serial.begin(115200);
delay(50);
Serial.println("starting...");
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
delay(2000);
digitalWrite(ledPin, HIGH);
delay(2000);
Serial.println("go to light sleep...");
delay(50);
esp_sleep_enable_ext0_wakeup(wakePin, wakeLevel);
esp_light_sleep_start();
Serial.println("hi again here!");
}
void loop(){}
Externe Weckfunktion (ext1)
Die ext1-Weckquelle ermöglicht die gleichzeitige Verwendung mehrerer RTC-GPIOs. Um die ext1-Weckquelle zu verwenden, müssen wir die folgende Funktion verwenden:
esp_sleep_enable_ext1_wakeup_io(bitmask, mode);
Diese Funktion akzeptiert zwei Argumente:
Das erste Argument ist die Bitmaske der GPIO-Nummern, die am Wecken beteiligt sind.
Das zweite Argument, der Parameter „mode”, bestimmt die Logik, die das Wecken auslöst.
| Die den Weckruf auslösende Logik | |
|---|---|
| ESP_EXT1_WAKEUP_ALL_LOW | Wacht auf, wenn alle freigegebenen GPIOs auf Low-Pegel sinken. |
| ESP_EXT1_WAKEUP_ANY_HIGH | Wacht auf, wenn einer der freigegebenen GPIOs in den High-Zustand wechselt. |
Ein Beispiel für den Leichtschlafmodus mit ext1-Weckfunktion.
#include "driver/rtc_io.h"
const gpio_num_t ledPin = GPIO_NUM_4;
const gpio_num_t wakePin1 = GPIO_NUM_12;
const gpio_num_t wakePin2 = GPIO_NUM_14;
const gpio_num_t wakePin3 = GPIO_NUM_27;
// Macro for GPIO bitmask
#define WAKE_PIN_BITMASK(GPIO) (1ULL << GPIO)
// Creating a bitmask
uint64_t bitmask = WAKE_PIN_BITMASK(wakePin1) | WAKE_PIN_BITMASK(wakePin2) | WAKE_PIN_BITMASK(wakePin3);
// function to print the GPIO that triggered the wake-up
void print_GPIO_wake_up()
{
uint64_t GPIO_reason = esp_sleep_get_ext1_wakeup_status();
Serial.print("The pin that triggers the wake-up: ");
Serial.println((log(GPIO_reason))/log(2), 0);
}
void setup()
{
Serial.begin(115200);
delay(50);
Serial.println("starting...");
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
delay(2000);
digitalWrite(ledPin, HIGH);
delay(2000);
// activate pull-down resistor
pinMode(wakePin1, INPUT_PULLDOWN);
pinMode(wakePin2, INPUT_PULLDOWN);
pinMode(wakePin3, INPUT_PULLDOWN);
// Configuring the wakeup pin(s) as RTC IO for EXT1 wakeup
rtc_gpio_deinit(wakePin1);
rtc_gpio_deinit(wakePin2);
rtc_gpio_deinit(wakePin3);
// Enable EXT1 wake source
esp_sleep_enable_ext1_wakeup(bitmask, ESP_EXT1_WAKEUP_ANY_HIGH);
}
void loop()
{
Serial.println("Enter light sleep mode...");
delay(100);
// Enter light sleep mode
esp_light_sleep_start();
// After wake-up, disable the hold function on the RTC GPIOs.
rtc_gpio_hold_dis(wakePin1);
rtc_gpio_hold_dis(wakePin2);
rtc_gpio_hold_dis(wakePin3);
Serial.println("Entering light sleep mode...");
// We print the GPIO number that caused the wake-up
print_GPIO_wake_up();
delay(2000);
}
Und noch ein ext1-Weckruf aus dem Tiefschlaf.
#include "driver/rtc_io.h"
const gpio_num_t ledPin = GPIO_NUM_4;
const gpio_num_t wakePin1 = GPIO_NUM_12;
const gpio_num_t wakePin2 = GPIO_NUM_14;
const gpio_num_t wakePin3 = GPIO_NUM_27;
// Macro for GPIO bitmask
#define WAKE_PIN_BITMASK(GPIO) (1ULL << GPIO)
// Creating a bitmask
uint64_t bitmask = WAKE_PIN_BITMASK(wakePin1) | WAKE_PIN_BITMASK(wakePin2) | WAKE_PIN_BITMASK(wakePin3);
// function to print the GPIO that triggered the wake-up
void print_GPIO_wake_up()
{
uint64_t GPIO_reason = esp_sleep_get_ext1_wakeup_status();
if(GPIO_reason != 0)
{
Serial.print("The pin that triggers the wake-up: ");
Serial.println((log(GPIO_reason))/log(2), 0);
}
}
void setup()
{
Serial.begin(115200);
delay(50);
Serial.println("starting...");
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
delay(2000);
digitalWrite(ledPin, HIGH);
delay(2000);
// activate pull-down resistor
pinMode(wakePin1, INPUT_PULLDOWN);
pinMode(wakePin2, INPUT_PULLDOWN);
pinMode(wakePin3, INPUT_PULLDOWN);
// Configuring the wakeup pin(s) as RTC IO for EXT1 wakeup
rtc_gpio_deinit(wakePin1);
rtc_gpio_deinit(wakePin2);
rtc_gpio_deinit(wakePin3);
// Enable EXT1 wake source
esp_sleep_enable_ext1_wakeup(bitmask, ESP_EXT1_WAKEUP_ANY_HIGH);
}
void loop()
{
rtc_gpio_hold_dis(wakePin1);
rtc_gpio_hold_dis(wakePin2);
rtc_gpio_hold_dis(wakePin3);
print_GPIO_wake_up();
Serial.println("Entering deep sleep mode...");
delay(100);
esp_deep_sleep_start();
}
Touchpad-Wecker
Das ESP32-Panel verfügt über 10 kapazitive Touchscreen-GPIOs (die je nach ESP32-Chip variieren können). Diese GPIOs können Veränderungen an elektrisch geladenen Objekten, wie z. B. der menschlichen Haut, erkennen. So können sie Veränderungen erkennen, die beim Berühren der GPIOs mit dem Finger entstehen. Diese ESP32-Touchpads können verwendet werden, um den ESP32 aus dem Tiefschlaf zu wecken.
Das RTC-IO-Modul enthält die Logik zur Verarbeitung des durch den Berührungssensor ausgelösten Weckens. Um das Aufwachen durch den Berührungssensor zu ermöglichen, müssen wir die Unterbrechung des Touchpads konfigurieren, bevor der ESP32 in den Tief- oder Leichtschlafmodus wechselt.
Mit der Funktion „esp_sleep_enable_touchpad_wakeup()” kann die Weckquelle durch den Berührungssensor aktiviert werden.
touchSleepWakeUpEnable(TOUCH_PIN, THRESHOLD);
Die Funktion „esp_sleep_get_touchpad_wakeup_status()” gibt zurück, welcher Touchpad-Pin den Weckvorgang ausgelöst hat.
touch_pad_t touchPin = esp_sleep_get_touchpad_wakeup_status();
Die ESP32-Berührungssensoren werden an diese dedizierten GPIO-Pins angeschlossen.
| Touch0 | GPIO4 |
| Touch1 | GPIO0 |
| Touch2 | GPIO2 |
| Touch3 | GPIO15 |
| Touch4 | GPIO13 |
| Touch5 | GPIO12 |
| Touch6 | GPIO14 |
| Touch7 | GPIO27 |
| Touch8 | GPIO33 |
| Touch9 | GPIO32 |

Die Arduino IDE enthält hierfür einen leicht verständlichen Beispielcode unter dem Menüpunkt „Datei/Beispiele/ESP32 Deep Sleep/“ im Entwurf „TouchWakeUp“.
ULP-Coprozessor-Weckfunktion
Der ULP-Coprozessor kann auch im Schlafmodus des ESP32 laufen und das im RTC SLOW-Speicher gespeicherte Programm ausführen. Er kann zum Abfragen von Sensoren und ADC-Werten, zum Überwachen von Berührungssensoren, aber auch zum Aufwecken des Chips bei Erkennung eines Ereignisses verwendet werden.
Sowohl die CPU als auch der ULP-Coprozessor können auf den RTC SLOW-Speicher zugreifen, sodass wir ihn zum Austausch von Daten zwischen der CPU und dem ULP-Coprozessor verwenden können.
Weitere Informationen zur Programmierung des ULP-Coprozessors finden Sie unter folgendem Link:
https://docs.espressif.com/projects/esp-idf/en/v5.4.2/esp32/api-reference/system/ulp.html#
werbung – amazon.de
Gründe für das Wecken
Oft müssen wir wissen, warum das ESP32 aus dem Schlafmodus aufgewacht ist, um zu entscheiden, unter welchen Bedingungen unser Programm weiterlaufen soll. Die Funktion „esp_sleep_get_wakeup_cause()” gibt zurück, was den Weckvorgang ausgelöst hat.
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason)
{
case ESP_SLEEP_WAKEUP_EXT0 :
Serial.println("External source-triggered wake-up (ext0)");
break;
case ESP_SLEEP_WAKEUP_EXT1 :
Serial.println("External source-triggered wake-up (ext1)");
break;
case ESP_SLEEP_WAKEUP_TIMER :
Serial.println("Timer triggered wake-up");
break;
case ESP_SLEEP_WAKEUP_TOUCHPAD :
Serial.println("Touchpad-activated wake-up");
break;
case ESP_SLEEP_WAKEUP_ULP :
Serial.println("ULP program-triggered wake-up");
break;
default :
Serial.printf("Undefined source: %d\n", wakeup_reason);
break;
}
}
#include "driver/rtc_io.h"
const gpio_num_t ledPin = GPIO_NUM_4;
const gpio_num_t wakePin1 = GPIO_NUM_12;
const gpio_num_t wakePin2 = GPIO_NUM_14;
const gpio_num_t wakePin3 = GPIO_NUM_27;
const gpio_num_t wakePin = GPIO_NUM_0;
int wakeLevel = 0;
// Macro for GPIO bitmask
#define WAKE_PIN_BITMASK(GPIO) (1ULL << GPIO)
// Creating a bitmask
uint64_t bitmask = WAKE_PIN_BITMASK(wakePin1) | WAKE_PIN_BITMASK(wakePin2) | WAKE_PIN_BITMASK(wakePin3);
// function to print the GPIO that triggered the wake-up
void print_GPIO_wake_up()
{
uint64_t GPIO_reason = esp_sleep_get_ext1_wakeup_status();
if(GPIO_reason != 0)
{
Serial.print("The pin that triggers the wake-up: ");
Serial.println((log(GPIO_reason))/log(2), 0);
}
}
// function for printing the reason for waking up
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("External source-triggered wake-up (ext0)");
break;
case ESP_SLEEP_WAKEUP_EXT1 :
Serial.println("External source-triggered wake-up (ext1)");
break;
case ESP_SLEEP_WAKEUP_TIMER :
Serial.println("Timer triggered wake-up");
break;
case ESP_SLEEP_WAKEUP_TOUCHPAD :
Serial.println("Touchpad-activated wake-up");
break;
case ESP_SLEEP_WAKEUP_ULP :
Serial.println("ULP program-triggered wake-up");
break;
default :
Serial.printf("Undefined source: %d\n", wakeup_reason);
break;
}
}
void setup()
{
Serial.begin(115200);
delay(50);
Serial.println("starting...");
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
delay(2000);
digitalWrite(ledPin, HIGH);
delay(2000);
// activate pull-down resistor
pinMode(wakePin1, INPUT_PULLDOWN);
pinMode(wakePin2, INPUT_PULLDOWN);
pinMode(wakePin3, INPUT_PULLDOWN);
// Configuring the wakeup pin(s) as RTC IO for EXT1 wakeup
rtc_gpio_deinit(wakePin1);
rtc_gpio_deinit(wakePin2);
rtc_gpio_deinit(wakePin3);
// Enable EXT0 wake source
esp_sleep_enable_ext0_wakeup(wakePin, wakeLevel);
// Enable EXT1 wake source
esp_sleep_enable_ext1_wakeup(bitmask, ESP_EXT1_WAKEUP_ANY_HIGH);
// Enable RTC timer wake source
esp_sleep_enable_timer_wakeup(15 * 1000000);
}
void loop()
{
rtc_gpio_hold_dis(wakePin1);
rtc_gpio_hold_dis(wakePin2);
rtc_gpio_hold_dis(wakePin3);
print_wakeup_reason();
print_GPIO_wake_up();
Serial.println("Entering light sleep mode...");
delay(1000);
esp_light_sleep_start();
}







































