Forum: Mikrocontroller und Digitale Elektronik ESP32-H2 will nicht schlafen


von Olli Z. (z80freak)


Angehängte Dateien:

Lesenswert?

Ich habe ein kleines Projekt erstellt in dem ich mit einem ESP32-H2 eine 
Art Zeitschaltuhr gebaut habe. Das ganze ist Batteriebetrieben und soll 
möglichst wenig Strom verbrauchen. Dazu schalte ich mittels
1
esp_light_sleep_start();
den ESP nach kurze Inaktivität bei der Bedienung in den Schlafmodus. 
Hier hätte ich erwartet das die Stromaufnahme deutlich sinkt, tut sie 
aber nicht, im Gegenteil, es entstehen "Bursts", so als wolle er nicht 
wirklich ruhen. Irgendwas reißt ihn mit 200 HZ aus dem Schlaf.

Mein Sleep-Code schaut aktuell so aus:
1
void go_to_sleep() {
2
    ESP_LOGI(TAG, "Time to sleep! zzzzZZZ...\n");
3
    vTaskDelay(pdMS_TO_TICKS(100));
4
5
    iot_button_stop();
6
    xTimerStop(inactivity_timer, 0);
7
8
    esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); // disable ALL wakeup sources (just for safety)
9
10
    gpio_wakeup_enable(BUTTON_GPIO, GPIO_INTR_HIGH_LEVEL); // LOW -> HIGH wakeup
11
    esp_sleep_enable_gpio_wakeup();
12
13
    // USB-CDC vor Sleep deaktivieren
14
    usb_serial_jtag_driver_uninstall();
15
16
    sleep_indicator_sleeping(); // set GPIO4 to HIGH
17
18
    // SLEEP
19
    esp_light_sleep_start();
20
21
    sleep_indicator_awake(); // set GPIO4 to LOW
22
23
    // USB-CDC nach Sleep neu starten
24
    reinit_usb_cdc();
25
26
    ESP_LOGI(TAG, "Uuaaa, i woke up!\n");
27
    esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
28
    ESP_LOGI(TAG, "Wakeup reason: %d", wakeup_reason);
29
30
    iot_button_resume();
31
    vTaskDelay(pdMS_TO_TICKS(500));
32
    
33
    xTimerReset(inactivity_timer, 0);
34
}

Problem bei der Sache ist auch das Debugging. Wenn ich das Super-Mini 
Board am USB lasse für Logmeldungen, kann ich keine Strommessung 
durchführen weil es ja direkt vom USB versorgt wird und im anderen Fall 
habe ich kein USB und somit kein Log :-/ Und im reinen USB-Modus sehe 
ich nach dem Sleep nichts mehr weil sich die Console abkoppelt und nicht 
automatisch wieder aufnimmt.

von Nemopuk (nemopuk)


Lesenswert?

Unterscheide zwischen Light- und Deep- Sleep, dann verstehst du das 
beobachtete Verhalten. Works as designed.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Olli Z. schrieb:
> Irgendwas reißt ihn mit 200 HZ aus dem Schlaf.

Das ist doch der Tick vom RTOS. Der Light-Sleep ist sowieso nicht 
besonders effektiv, ist eher so wie der "Idle" Mode beim Cortex-M  (also 
nur WFI) - praktisch die Alternative zu Busy-Wait, aber ohne dass die 
Peripherie (und damit auch der Tick Timer) davon beeinflusst würden.

Daher brauchst du den Deep-Sleep.

von Olli Z. (z80freak)


Lesenswert?

Deep-Sleep kann (will) ich nicht nehmen, da während dem Sleep das PWM 
weiter erzeugt werden soll der meine externe LED auch während dem Sleep 
weiter auf Helligkeit hält.

Also ihr seid der Meinung das das OK so ist? Wenn ich ein Mittel nehme, 
dann ist es vor dem Sleep 16,5 mA und während dem Sleep 5,5 mA. Immerhin 
ein Drittel weniger.

Im Sleep kann doch von RTOS nichts mehr ausgeführt werden, wie soll das 
denn bitteschön gehen? Die CPU ist angehalten. Davon ab ist die RTOS 
Tick Frequenz bei mir auf Default 100 Hz.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Olli Z. schrieb:
> Das finde ich seltsam, warum sollte der Hersteller das so designen?

Weil's billiger ist. Low-Power Halbleiter Herstellung kostet halt, und 
das Hauptargument für die ESP32 ist der Preis.

Olli Z. schrieb:
> Und im Sleep kann doch von RTOS nichts mehr ausgeführt werden, wie soll
> das denn bitteschön gehen?

Der Sinn ist doch, dass nichts mehr ausgeführt wird, um Energie zu 
sparen...

Olli Z. schrieb:
> Die CPU ist angehalten.

Wenn die CPU an ist, verbraucht sie Strom - im Falle der ESP32 halt 
viel Strom.

Olli Z. schrieb:
> da während dem Sleep das PWM weiter erzeugt werden soll.

PWM und Stromsparend geht nicht bei ESP32.

Andere Controller wie z.B. die STM32Uxx haben spezielle Low-Power Timer 
die auch im "Stop" Mode eine PWM ausgeben können. Dafür ist natürlich 
trotzdem eine Taktquelle nötig, z.B. der 32 kHz Uhrenquartz - das grenzt 
die PWM-Frequenz und -Auflösung ein. Das verbraucht dann Größenordnung 
10-30 μA.

von Olli Z. (z80freak)


Lesenswert?

Hm, wenn ich in meinem Code "esp_light_sleep_start();" durch 
"esp_deep_sleep_start();" ersetze ändert das nichts an der Stromaufnahme 
und Charakteristik. Ist das auch "by Design"?

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

Niklas G. schrieb:

> Andere Controller wie z.B. die STM32Uxx haben spezielle Low-Power Timer
> die auch im "Stop" Mode eine PWM ausgeben können. Dafür ist natürlich
> trotzdem eine Taktquelle nötig, z.B. der 32 kHz Uhrenquartz - das grenzt
> die PWM-Frequenz und -Auflösung ein. Das verbraucht dann Größenordnung
> 10-30 μA.

Genau das kann der ESP32 auch und so habe ich es auch konfiguriert. Das 
klappt aber nur im Light-Sleep.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Leg doch mal ein Minimal-Programm an das nur esp_deep_sleep_start() 
aufruft und sonst nichts. Vielleicht muss man da auch was im menuconfig 
aktivieren

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Olli Z. schrieb:
> Genau das kann der ESP32 auch und so habe ich es auch konfiguriert. Das
> klappt aber nur im Light-Sleep.

Kann er nicht, weil er dafür den aktiven Haupttakt benötigt. Was nur im 
Light-Sleep der Fall ist, weil da das ganze System "an" ist, nur die CPU 
selbst nicht. Spezifische Low-Power-Controller wie u.a. die STM32Uxx 
können es auch ohne Haupttakt.

: Bearbeitet durch User
von Olli Z. (z80freak)



Lesenswert?

Niklas G. schrieb:
> Leg doch mal ein Minimal-Programm an das nur esp_deep_sleep_start()
> aufruft und sonst nichts. Vielleicht muss man da auch was im menuconfig
> aktivieren

Genau das hatte ich jetzt auch gemacht um mal alle anderen Fehlerquellen 
auszuschließen. Dazu verwende ich nur die Power-Meter Funktion vom PPK2 
und übergehe sogar den Spannungsregler auf dem EPS32-H2 Super-Mini Board 
indem ich direkt 3,3V auf dem ausgeführten Pin erzeuge. Das Board habe 
ich komplett unbeschaltet mit folgendem Code
1
#include <stdio.h>
2
#include "freertos/FreeRTOS.h" // FreeRTOS
3
#include "freertos/task.h" // Tasks
4
#include "esp_log.h"    // Logging
5
#include "esp_sleep.h" // Sleep
6
7
static const char *TAG = "sleep-test";
8
void app_main(void)
9
{
10
    while (1)
11
    {
12
        vTaskDelay(pdMS_TO_TICKS(10000));
13
        //esp_light_sleep_start();
14
        esp_deep_sleep_start();
15
    }
16
}

Im Deep-Sleep verbraucht er dann 345 µA (viel zu hoch) und im 
Light-Sleep 480 µA (auch zu hoch, aber wäre ok).

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Grundsätzlich gibt es eine Menge möglicher Ursachen für zu hohen 
Stromverbrauch im Standby.

Floatende Pins sind der Klassiker, weil dann der Input-Schmitt-Trigger 
oszilliert. Typischerweise sollte man alle unbeschalteten Pins und alle 
Input-Pins auf Pull-Up/Down setzen, bei den STM32 hingegen auf "Analog".

Eventuell sind noch irgendwelche Peripherie-Einheiten aktiv, Flash nicht 
abgeschaltet, zusätzliche ICs auf dem ESP32-Modul nicht 
abgeschaltet/abschaltbar, irgendwelche Interrupts sind "Pending" beim 
Sleep-Eintritt...

von Rolf (rolf22)


Lesenswert?

Olli Z. schrieb:
> Im Sleep kann doch von RTOS nichts mehr ausgeführt werden, wie soll das
> denn bitteschön gehen? Die CPU ist angehalten.

Die CPU könnte durch vorprogrammierte Interrupts zwischendurch kurz 
aufgeweckt werden und dann eine Interruptbehandlungs-Routine oder mehr 
durchlaufen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.