ESP32 Deep Sleep Tutorial

ESP32 Deep Sleep Tutorial


02.10.2020  |  Tutorial, ESP32 Projekte

In diesem Tutorial möchte ich dir an mehreren Beispielen erklären, wie du den ESP32 Deep Sleep ganz einfach umsetzen kannst. Dann kannst du den ESP32 beispielsweise über längere Zeit mit einer Batterie, einem Akku oder einer PowerBank versorgen.

Was ist der ESP32 Deep Sleep?

Mit dem Deep Sleep kann der ESP32 in einen Energiesparmodus versetzt werden. Damit ist es möglich, den ESP32 mit einer Batterie oder einer Power Bank zu betreiben und die Akkulaufzeit zu erhöhen. Das ist sinnvoll bei Sensoren, die beispielsweise nur einmal in der Stunde einen Wert an einen Server senden. Die restliche Zeit kann der ESP32 im Deep Sleep verweilen um den Akku zu schonen.

NodeMCU ESP32

Der Deep Sleep des ESP32 wird einmal per Timer umgesetzt. Damit lässt sich beispielsweise ein Sensor mit Batterie oder Akku umsetzen, der einmal pro Stunde einen Wert an einen Server sendet und die restliche Zeit im Energiesparmodus verbringt. Neben dem Deep Sleep mit einem Timer lässt sich auch ein Deep Sleep per Interrupt umsetzen. Dabei kann der ESP32 zum Beispiel aufgeweckt werden, wenn ein Bewegungsmelder ausgelöst oder eine Tür geöffnet wird. Dann lassen sich beispielsweise die Ereignisse "Bewegung erkannt" bzw. "Tür geöffnet" an einen Server senden. Um den ESP32 Deep Sleep mit einem Interrupt umzusetzen, verwende ich einen Reedkontakt und einen Bewegungsmelder.

Reedkontakt

-11%

Bewegungsmelder

ESP32 Deep Sleep mit Timer

Die einfachste Form des Deep Sleeps auf dem ESP32 ist die Variante, bei der der Energiesparmodus nach einer vorgegeben Zeit automatisch beendet wird. Damit lassen sich beispielsweise Sensoren realisieren, die nur einmal pro Stunde einen Wert an einen Server übermitteln sollen. In meinem Beispiel gibt der ESP32 auf dem seriellen Monitor eine Meldung aus, wenn er gestartet ist. Anschließend wird jedes mal, wenn die Loop-Funktion aufgerufen wird eine Meldung ausgegeben und vor dem Start des Deep Sleeps wird ebenfalls eine Meldung ausgegeben. Die Methode zum Start des Energiesparmodus wird in der Loop-Funktion aufgerufen. Der Deep Sleep soll dann nach 5 Sekunden automatisch wieder beendet werden.
int TIME_TO_SLEEP = 5;

void setup() {
  Serial.begin(9600);
  Serial.println("Waking up...");
}

void loop() {
  doAction();
  startDeepSleep();
}

void doAction(){
  Serial.println("Doing action...");
}

void startDeepSleep(){
  Serial.println("Going to sleep...");
  Serial.flush();
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * 1000000); 
  esp_deep_sleep_start();
}
Die Ausgabe auf dem seriellen Monitor sollte nun in etwa so aussehen: "Waking up... Looping... Going to sleep..." Diese Ausgabe sollte sich ungefähr alle 5 Sekunden wiederholen.
 

ESP32 Deep Sleep mit Interrupt

Neben der Nutzung eines Timers, um den ESP32 wieder aus dem Energiesparmodus aufzuwecken, gibt es auch die Möglichkeit, einen Interrupt zum Aufwecken zu verwenden. Dazu zählen beispielsweise Taster, Bewegungsmelder, Reedkontakte und viele mehr. In diesem Tutorial zeige ich dir die Nutzung eines Interrupts an zwei Beispielen. Dabei verwende ich einmal einen Reedkontakt, der den ESP32 aufwecken soll, wenn er geschlosen wird und einmal einen Bewegungsmelder, der den ESP32 aufwekcen soll, wenn eine Bewegung erkannt wird.  

ESP32 Deep Sleep mit Reedschalter als Interrupt

Mit einem Reedschalter kannst du beispielsweise messen, ob eine Tür oder ein Fenster geöffnet oder geschlossen ist. Der Reedschalter verwendet dazu einen Magneten. Wird ein Magnet an den Reedschalter gehalten, so werden zwei Kontakte verbunden und der Schalter ist geschlossen. Ist kein Magnet in der Nähe, so ist der Kontakt geöffnet. Wird der Magnet nun an einer Tür befestigt, so lässt sich der Kontakt schließen, sobald die Tür geschlossen wird. Mit diesem Skript könntest du den ESP32 zum Beispiel immer aufwecken, wenn die Tür geöffnet oder geschlossen wird und dann den Status aktualisieren. Dazu müsstest du nur die Methode "doAction()" anpassen und den Code einfügen, der ausgeführt werden soll, wenn sich der Zustand der Türkontakts ändert.[/vc_column_text]Um den Deep Sleep mit dem Reedkontakt beenden zu können, musst du den Reedkontakt mit einem 1kOhm-Widerstand so verbinden, wie auf der Abbildung zu sehen.
Der Deep Sleep kann durch einen Reedkontakt beendet werden.
Der Code für den Deep Sleep mit dem Reedkontakt sieht folgendermaßen aus:
const int REED_SENSOR_PIN = 34;

void setup() {
  Serial.begin(9600);
  Serial.println("Waking up...");

  pinMode(REED_SENSOR_PIN, INPUT);
}

void loop() {
  doAction();
  waitForChange();
}

void doAction(){
  Serial.print("Door has been ");
  Serial.print(doorClosed() ? "closed" : "opened");
  Serial.println("...");
}

void waitForChange(){
  Serial.print("Going to sleep until door is ");
  Serial.println(doorClosed() ? "opened" : "closed");
  Serial.flush();
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_34, doorClosed() ? LOW : HIGH);
  esp_deep_sleep_start();
}

bool doorClosed(){
  return digitalRead(REED_SENSOR_PIN) == 1;
}
Auf der seriellen Ausgabe werden die Schließ- und Öffnungsvorgänge des Türkontakts immer ausgegeben.
 

Deep Sleep des ESP32 mit Bewegungsmelder als Interrupt

Der Bewegungsmelder wird wie auf der Abbildung zu sehen mit dem ESP32 verbunden. Dann kann der Deep Sleep beendet werden, sobald eine Bewegung wahrgenommen wird. Der Code führt dann einmalig eine Aktion aus (In diesem Fall nur die Textausgabe, dass eine Bewegung erkannt wurde) und geht wieder in den Deep Sleep, sobald der Bewegungsmelder keine Bewegung mehr erkennt. Mit diesem Programm könnte man zum Beispiel per MQTT eine Meldung an den Broker senden, sobald eine Bewegung erkannt wurde. Dazu muss nur die Methode "doAction()" angepasst werden.
Der Code für das Aufwecken mit dem Bewegungsmelder sieht folgendermaßen aus:
const int MOTION_SENSOR_PIN = 34;

bool didAction = false;

void setup() {
  Serial.begin(9600);
  Serial.println("Waking up...");

  pinMode(MOTION_SENSOR_PIN, INPUT);
}

void loop() {
  doAction();
  if(!motionDetected()){
    startDeepSleep();
  }
}

void doAction(){
  if(didAction){
    return;
  }
  Serial.println("Motion detected...");
  didAction = true;
}

void startDeepSleep(){
  Serial.println("Going to sleep...");
  Serial.flush();
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_34, HIGH);
  esp_deep_sleep_start();
}

bool motionDetected(){
  return digitalRead(MOTION_SENSOR_PIN) == 1;
}
Auf der seriellen Ausgabe solltest du dann folgende Texte sehen:
Dank dem Deep Sleep kannst du deinen ESP32 also ganz einfach mit einem Akku auch über einen längeren Zeitraum mit Strom versorgen und ihn trotzdem alle wichtigen Statusmeldungen senden lassen.

Über den Autor


Sascha

Hallo, ich bin Sascha, der Gründer von Smarthome Blogger.

Mit einer Leidenschaft für Technologie und einem Hintergrund als Software Engineer habe ich 2016 Smarthome Blogger gegründet. Mein Ziel war es schon immer, innovative Lösungen zu entdecken, die unser Leben einfacher und intelligenter gestalten können. In meinem beruflichen Leben arbeite ich täglich mit Software und Technik, aber auch in meiner Freizeit bin ich stets auf der Suche nach neuen technischen Spielereien und Möglichkeiten, mein Zuhause zu automatisieren und zu verbessern.

Auf Smarthome Blogger teile ich mein Wissen, meine Erfahrungen und meine Begeisterung für alles rund um das Thema Smarthome.



Dieser Beitrag hat dir gefallen?

Dann abonniere doch unseren Newsletter!