Quantcast
Channel: Tutorials – lucadentella.it
Viewing all articles
Browse latest Browse all 84

ESP32 (29) – Deep sleep

$
0
0

Una delle tematiche principali per dispositivi embedded è il consumo energetico. Se infatti il dispositivo che si sta realizzando dovrà essere alimentato a batteria, è necessario ridurre al minimo il consumo di corrente in modo da massimizzare l’autonomia (= il tempo di funzionamento prima che sia necessario sostituire o ricaricare la batteria).

Il chip esp32 offre 5 diverse modalità di consumo energetico (power modes). La modalità di funzionamento “nomale” prende il nome di active mode; in tale modalità tutte le funzionalità del chip sono disponibili. Iniziando a ridurre la velocità di funzionamento e disattivando periferiche e cores, si passa a diverse modalità di risparmio energetico, riassunte nel seguente schema:

sleep-001

In questo primo articolo relativo al risparmio energetico del chip esp32, vi parlerò della modalità deep sleep.

Deep sleep

Il framework esp-idf supporta attualmente due modalità di risparmio ergetico: light sleepdeep sleep. Tra le due, la modalità deep sleep è quella che offre un risparmio maggiore di energia. In tale modalità vengono spente:

  • entrambe le CPU
  • la maggior parte della memoria RAM
  • tutte le periferiche

sono invece di default mantenute in esecuzione:

  • il controller RTC
  • le periferiche RTC, incluso il coprocessore ULP
  • Le memorie RTC lenta e veloce (slowfast)

L’attivazione della modalità deep sleep avviene con il comando esp_deep_sleep_start(), mentre è possibile “risvegliarsi” (wakeup) da tale modalità in base a diversi eventi:

sleep-002

Al risveglio dalla modalità deep sleep, avviene un nuovo boot. E’ molto importante comprendere quindi che il programma non riprende dal punto in cui è stato chiamato il metodo esp_deep_sleep_start().

Vediamo nel dettaglio la configurazione e l’utilizzo di due eventi: di touch pad e ULP vi parlerò in un prossimo articolo.

Timer

L’evento di wakeup più semplice è quello che utilizza un timer del controller RTC. Utilizzando il metodo:

esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)

è possibile risvegliare il chip esp32 dopo il numero di microsecondi specificati come parametro. Il metodo deve essere chiamato prima di attivare la modalità deep sleep:

// wakeup after 10 seconds
esp_sleep_enable_timer_wakeup(10000000);
esp_deep_sleep_start();

I/O triggers

In un precedente articolo vi ho parlato della possibilità di avere interrupts al cambio di stato di uno dei pin digitali del chip esp32. Possiamo sfruttare una funzionalità simile per risvegliare il chip esp32 dallo sleep.

Con il metodo

esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)

è possibile attivare il wakeup se avviene un cambio di stato (level) del pin specificato (gpio_num).

I pin utilizzabili sono soltanto quelli con funzionalità RTC (0, 2, 4, 12-15, 25-27, 32-39) e i livelli sono 0 (= basso) o 1 (alto). Se ad esempio vogliamo configurare il risveglio da deep sleep quando il pin 4 ha uno stato logico basso, scriveremo:

esp_sleep_enable_ext0_wakeup(4, 0);

E’ disponibile anche un metodo per monitorare diversi pins:

esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode)

i pin (anche per tale metodo è possibile specificare solo quelli sopra elencati) vanno indicati come bitmask, mentre le modalità possibili sono:

  • ESP_EXT1_WAKEUP_ALL_LOW = wakeup quanto tutti i pins sono a livello logico basso
  • ESP_EXT1_WAKEUP_ANY_HIGH = wakeup quando almeno un pin è a livello logico alto
Al ritorno dallo sleep, i pin specificati saranno configurati come RTC IO. Per poterli utilizzare come pin digitali, è necessario chiamare il metodo rtc_gpio_deinit(gpio_num). Il metodo ext0_wakeup non è attualmente compatibile con wakeup basati su touch pad o ULP.

Dopo il risveglio…

Se sono stati attivati più eventi di wakeup, è possibile conoscere quale evento ha causato il risveglio con:

esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause()

Le costanti possibili sono:

sleep-003

Per l’evento ext1_wakeup, è possibile conoscere la bitmask dei pin che hanno causato il risveglio con:

uint64_t esp_sleep_get_ext1_wakeup_status()

Memoria

Come spiegato sopra, in deep sleep viene preservato il contenuto delle memorie RTC fastRTC slow. E’ quindi possibile utilizzare tali aree di memoria per memorizzare dati da conservare durante lo sleep.

Per indicare al compilatore che una variabile deve essere memorizzata nella RTC slow memory è sufficiente usare l’attributo RTC_DATA_ATTR, oppure RTC_RODATA_ATTR se tale variabile è in sola lettura (read only):

RTC_DATA_ATTR static time_t last;

Demo

Ho preparato un programma (il codice sorgente è disponibile nel mio repository Github) che mostra il funzionamento della modalità deep sleep e due diversi eventi di wake up (sottitoli in italiano disponibili):


Viewing all articles
Browse latest Browse all 84

Trending Articles