ESP32-WROOM - Realisierung von LIGHT_SLEEP/DEEP_SLEEP

Hi zusammen,

ich möchte im Rahmen meines Projektes auch einen Energiesparmodus realisieren.

In diesem Zuge habe ich schon vom DEEP_SLEEP Modus gehört. Allerdings noch nie mit eingebunden. Hat jemand von euch damit Erfahrung? Insbesondere, wenn ich den ESP32 durch Touch-Kontakt wieder aufwecken möchte.

An welcher Stelle müsste ich was einbinden?
Was passiert unterdessen mit dem Loop-Teil, während der Sleep-Phase?
Welche Energiesparmodi gibt es noch?

Was passiert oder was wäre empfehlenswert für Sensoren, die dennoch aktiv sein sollen?

Vielen Dank zunächst.

Hier findest du eine Übersicht über Stromsparmaßnahmen auf dem ESP32.

Allgemeine Informationen über die verschiedenen Sleep Modes findest du hier:

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

Danke für den Link, allerdings beantwortet das noch nicht wirklich meine vorhandenen Fragen bezüglich des genauen einbindens in den Sketch.

In meinem Fall, realisiere ich eine elektrische Türöffnung. Die spezielle Herausforderung ist nun folgende: Via Rotary-Encoder wird die Stellung des Türschlüssels ermittelt. Angeschlossen an Pin18 und Pin26. Für die Auswertung nutze ich #include <NewEncoder.h>

Aus meiner recherche habe ich folgende Möglichkeit für das Wake-Up in Betracht gezogen: External Wake Up (ext1) eine entsprechende BUTTON_PIN_BITMASK habe ich für beide Pins bereits ermittelt. Jedoch funktioniert der Wake-Up bei Bewegung des Rotarys nicht. Auch ein Hallendstop der bei geschlossener Tür auf HIGH steht soll bei Veränderung ein Wake bewirken. Eignet sich PIN 23 nicht dafür?

Vielleicht möchten Sie Ihre Fragen noch etwas präzisieren? Die Fragen sind zu allgemein, also haben Sie eine allgemeine Antwort.

Wir müssen genau wissen, was Ihr ESP ist, und das Design Ihrer Schaltung würde helfen.

Ohne jetzt mein ganzes Projekt zu veröffentlichen geht es mir ledglich um die Fragestellung, wie ich meinen ESP32 Code-Technisch in den light-sleep versetzte und durch bestimmte Veränderungen wieder aufwachen lasse.

Wie bereits gesagt ist mein ESP32 ein elektonischer Türöffner mit Fingerprintsensor. Über das Modul selbst gibt es eine HIGH/LOW Funktion über einen PIN der zum Aufwachen genutzt werden kann. Das klappt soweit.

Jedoch reicht das alleine nicht. Denn es gibt noch einen
Hallendstop, der liefert im geschlossenen Zustand HIGH und bei geöffnerter Tür ein LOW

Des Weiteren gibt es noch die Möglichkeit das man von außen die Tür manuell mit dem Schlüssel aufschließt. Dabei wird auf der Gegenseite ein Rotary mitgewegt. Dieser ist aber im lightsleep nicht aktiv, weshalb der ESP beim Drehen des Rotarys nicht aufwacht. (ist wohl das größtes Problem)

Also was ich noch liefern kann wäre die aktuelle Pinbelegung.
Fingerprintsensor-Touchpin = 4 (HIGH/LOW) (LOW bei Berührung)
HallendstopSignal = 23 (HIGH/LOW (HIGH bei geschlossener Tür)
Rotary CLK (channelA) = 26
Rotary DT (channelB) = 18

Beim Rotary weiß ich nicht, wie sich der Stromfluss auswirkt, oder wie man dort eine Änderung sichtbar macht.

Es gibt also 3 Scenarien:

  1. Jemand öffnet von innen die Tür, Hallendstop geht auf low. (ESP 32 soll aufwachen)
  2. Jemand legt seinen Finger auf den Fingersensor von außen. Tür ist geschlossen. (ESP32 soll aufwachen.
  3. Es steckt jemand den Schlüssel ins Schloss und öffnet die Tür manuell. (ESP32 soll aufwachen)

Also Fragestellung, wie kann ich den Lightslepp Modus konfigurieren, das ich genau solche mehreren scenarien damit abdecken kann. Auf Youtube etc wird meist nur der deep-sleep beschrieben. Der wäre aber wohl für mein Projekt vermutlich nicht nutzbar.

funktioniert esp_sleep_enable_ext0_wakeup() nicht für Drehgeber?
Ich kann es im Moment nicht versuchen, aber die Pins werden HIGH / LOW-Übergänge durchlaufen

#include <ESP32Encoder.h> // https://github.com/madhephaestus/ESP32Encoder

ESP32Encoder encoder;

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 gotoLightSleep() {
  Serial.println("encoder is going to light sleep"); Serial.flush();
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_32, digitalRead(GPIO_NUM_32) == LOW ? HIGH : LOW);
  esp_light_sleep_start();
  print_wakeup_reason();
}

void testEncoder() {
  static int32_t oldEncoder = 0;
  int32_t newEncoder = encoder.getCount();
  if (newEncoder != oldEncoder) {
    Serial.println(newEncoder);
    oldEncoder = newEncoder;
    if (newEncoder == 10) {
      gotoLightSleep();
      encoder.clearCount(); // ensure we call pcnt_counter_clear
      encoder.setCount(newEncoder);
    }
  }
}


void setup() {
  Serial.begin(115200);
  ESP32Encoder::useInternalWeakPullResistors = UP;
  encoder.attachHalfQuad(32, 33);
  encoder.setFilter(1023);  // max debounce
  encoder.clearCount();
  Serial.print("Encoder Ready, wake up on pin #"); Serial.println(GPIO_NUM_32); Serial.flush();
  gotoLightSleep();
}

void loop() {
  testEncoder();
}

Dieser Code startet im light_sleep, eine Berührung des Encoders weckt das System auf. Wenn der Encoder auf 10 geht, beginnt der light_sleep erneut.

(nicht getestet, aber probieren Sie es aus)

encoder CLK --> ESP32 pin D33
encoder DT --> ESP32 pin D32

Vielen Dank für die Antwort.

Ich gucke mir deinen Code in Ruhe nochmal an. Ich nutze jedenfalls für den Rotary pin IO26 und IO18.

In meinem ESP32 Belegungs-Diagramm liegen IO32 und IO33 jetzt relativ weit voneinander weg. Das wäre jetzt zwar nicht dramatisch, aber was spricht gegen IO26 für CLK und IO18 und DT sind die Pin grade für die Funktionen CLK und DT nicht festgelegt? Im aktuellen Setup funktioniert dieser jedenfalls.

WENN es denn mit

 esp_sleep_enable_ext0_wakeup(GPIO_NUM_32, digitalRead(GPIO_NUM_32) == LOW ? HIGH : LOW);

funktionieren sollte, besteht immer noch das Problem, das ich mehrere Scenarien für das Aufwachen benötige. Ich bräuchte mindestens den Rotary und dan Touchpin vom Fingerprintsensor, sonst wäre eine Türschlossbewegung notwendig um das ganze System zu nutzen.

Ich habe RTC-GPIO-Pins ausgewählt. Diese RTC-GPIOs können verwendet werden, um den ESP32 aus dem deep-sleep zu wecken. Ich habe nicht versucht, ob Nicht-RTC-Pins für light-sleep funktionieren.

Sie können sich esp_sleep_enable_ext1_wakeup() ansehen

External wakeup (ext1)

RTC controller contains logic to trigger wakeup using multiple RTC GPIOs. One of the two logic functions can be used to trigger wakeup:

  • wake up if any of the selected pins is high (ESP_EXT1_WAKEUP_ANY_HIGH)
  • wake up if all the selected pins are low (ESP_EXT1_WAKEUP_ALL_LOW)

Ja, das habe ich bereits versucht. EXT1 Aber es könnte natürlich sein, das mein PIN 26 und 18 keine RTC Pins sind und daher vermutlich deswegen der Wakeup beim Rotary nicht funktioniert.

Hi zurück!

Ich kann dir auf jeden Fall positives Feedback geben. Offensichtlich lag es wirklich an den benutzten PINS. So funktionierts. Sehr gut!

Danke, weiter so.

Das sind gute Neuigkeiten!!!