ESP32 Energieeinsparungen durch Verwendung bestimmter Schlafmodi

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.

ESP32 NodeMCU WLAN Module
ESP32 Dev Kit C V4 NodeMCU WLAN/WiFi Development Board

Werbung

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:

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 dBm190 mA
Transmit 802.11n, OFDM MCS7, POUT = +14 dBm180 mA
Receive 802.11b/g/n 95 ~ 100 mA
Transmit BT/BLE, POUT = 0 dBm130 mA
Receive BT/BLE95 ~ 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_N00dbm
ESP_PWR_LVL_P3+3dbm
ESP_PWR_LVL_P6+6dbm
ESP_PWR_LVL_P9+9dbm
ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12Abwärtskompatibilität!
Wenn wir -14 dBm einstellen, ergibt dies tatsächlich -12 dBm..
ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9Abwärtskompatibilität!
Wenn wir -11 dBm einstellen, ergibt dies tatsächlich -9 dBm.
ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6Abwärtskompatibilität!
Wenn wir -8 dBm einstellen, ergibt dies tatsächlich -6 dBm.
ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3Abwärtskompatibilität!
Wenn wir -5 dBm einstellen, ergibt dies tatsächlich -3 dBm.
ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0Abwärtskompatibilität!
Wenn wir -2 dBm einstellen, ergibt dies tatsächlich 0 dBm.
ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3Abwärtskompatibilität!
Wenn wir +1 dBm einstellen, ergibt dies tatsächlich +3 dBm.
ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6Abwärtskompatibilität!
Wenn wir +4 dBm einstellen, ergibt dies tatsächlich +6 dBm.
ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9Abwärtskompatibilität!
Wenn wir +7 dBm einstellen, ergibt dies tatsächlich +9 dBm.

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_HDL0TX-Leistung für Operator 0.
ESP_BLE_PWR_TYPE_CONN_HDL1TX-Leistung für Operator 1.
ESP_BLE_PWR_TYPE_CONN_HDL2TX-Leistung für Operator 2.
ESP_BLE_PWR_TYPE_CONN_HDL3TX-Leistung für Operator 3.
ESP_BLE_PWR_TYPE_CONN_HDL4TX-Leistung für Operator 4.
ESP_BLE_PWR_TYPE_CONN_HDL5TX-Leistung für Operator 5.
ESP_BLE_PWR_TYPE_CONN_HDL6TX-Leistung für Operator 6.
ESP_BLE_PWR_TYPE_CONN_HDL7TX-Leistung für Operator 7.
ESP_BLE_PWR_TYPE_CONN_HDL8TX-Leistung für Operator 8.
ESP_BLE_PWR_TYPE_ADVTX-Leistung für die Ankündigung.
ESP_BLE_PWR_TYPE_SCANTX-Leistung für das Scannen.
ESP_BLE_PWR_TYPE_DEFAULTStandardmäßiger TX-Leistungstyp, mit dem die Leistung von zuvor nicht eingestellten Leistungstypen eingestellt werden kann.
ESP_BLE_PWR_TYPE_NUMAnzahl 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.

Zurück zum Inhaltsverzeichnis

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:

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

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);
}
SwitchBot WLAN Smart Lock Pro mit Touchscreen-Tastatur, Türriegelschlösser, Smartes Türschloss, Elektronisches Türschloss, Türöffner per App, Fingerprint, Code, Alexa, Google, unterstützt Matter

SwitchBot WLAN Smart Lock Pro

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-FrequenzEnergieverbrauch
240 MHz 30 mA ~ 68 mA
160 MHz 27 mA ~ 44 mA
80 MHz20 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(){}

Zurück zum Inhaltsverzeichnis

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:

Das Blockdiagramm des ESP32 im Light-Sleep-Modus

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.

Zurück zum Inhaltsverzeichnis

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:

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.

Zurück zum Inhaltsverzeichnis

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.

esp32 Hibernation-Modus Blockdiagramm

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_PERIPHRTC Peripherien
ESP_PD_DOMAIN_RTC_FAST_MEMRTC-Schnellspeicher (ULP-Programme).
ESP_PD_DOMAIN_RTC_SLOW_MEMRTC- Langsamspeicher (ULP-Daten).
ESP_PD_DOMAIN_XTALQuarzoszillator
Optionen für Domains
ESP_PD_OPTION_OFFAusschalten der angegebenen Domain
ESP_PD_OPTION_ONEinschalten 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();
}

Zurück zum Inhaltsverzeichnis

Shelly Pro 4PM

Shelly Pro 4PM Professioneller Relaisschalter 4 Kontakte

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 smartes Heizkörperthermostat inklusive Hub, WLAN Heizungsthermostat Kompatibel mit HomeKit, Alexa und Google Assistant,Sprachsteuerung Zeitpläne Automation Fensteröffnungserkennung, M30*1,5mm

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_GPIO0GPIO36
RTC_GPIO3GPIO39
RTC_GPIO4GPIO34
RTC_GPIO5GPIO35
RTC_GPIO6GPIO25
RTC_GPIO7GPIO26
RTC_GPIO8GPIO33
RTC_GPIO9GPIO32
RTC_GPIO10GPIO4
RTC_GPIO11GPIO0
RTC_GPIO12GPIO2
RTC_GPIO13GPIO15
RTC_GPIO14GPIO13
RTC_GPIO15GPIO12
RTC_GPIO16GPIO14
RTC_GPIO17GPIO27

Auf dem folgenden Bild sehen wir die RTC_GPIO-Pins auf der 38-poligen ESP32-Entwicklerkarte:

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_LOWWacht auf, wenn alle freigegebenen GPIOs auf Low-Pegel sinken.
ESP_EXT1_WAKEUP_ANY_HIGHWacht 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.

Touch0GPIO4
Touch1GPIO0
Touch2GPIO2
Touch3GPIO15
Touch4GPIO13
Touch5GPIO12
Touch6GPIO14
Touch7GPIO27
Touch8GPIO33
Touch9GPIO32
Die ESP32-Berührungssensoren werden an diese dedizierten GPIO-Pins angeschlossen.

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();
}

Zurück zum Inhaltsverzeichnis