ESP32 risparmio energetico pratico: modem e light sleep – 2
ESP32 è in grado di attivare le modalità di sospensione leggera (light sleep) e di sospensione profonda (deep sleep) con un comando specifico, ma esiste un’altra modalità di sospensione modem (modem sleep), questo non è una sospensione ben definita come le altre, e per implementarla può essere necessario eseguire più di un’operazione.
Quindi ricorda che la modalità modem sleep è una modalità meno definita non eseguita con un comando specifico e per comprendere meglio è utile leggere il capitolo precedente.
La modalità di sospensione leggera è, invece, ben definita ed esiste un comando specifico per attivarla, con questa modalità le periferiche digitali, la maggior parte della RAM e le CPU hanno una frequenza di clock ridotta ed anche la tensione di viene ridotta. All’uscita dalla modalità di sospensione leggera, le periferiche e le CPU riprendono a funzionare, ed il loro stato interno viene preservato.
In questa tabella, presa dal datasheet dell’esp32, vi sono informazioni su come raggruppare le modalità di sospensione.
Modalità di alimentazione | Descrizione | Consumo di energia | ||
Attivo (RF funzionante) |
Pacchetto Tx Wi-Fi |
78 mA ~ 90 mA senza comunicazione Per TX RX maggiori informazioni nella tabella successiva |
||
Pacchetto Wi-Fi / BT Tx | ||||
Wi-Fi / BT Rx e ascolto | ||||
Modem-sleep |
La CPU è accesa. |
240 MHz * | Dual-core chip(s) | 30 mA ~ 68 mA |
Single-core chip(s) | N/A | |||
160 MHz * | Dual-core chip(s) | 27 mA ~ 44 mA | ||
Single-core chip(s) | 27 mA ~ 34 mA | |||
Velocità normale: 80 MHz | Dual-core chip(s) | 20 mA ~ 31 mA | ||
Single-core chip(s) | 20 mA ~ 25 mA | |||
Light-sleep | – | 0.8 mA | ||
Deep-sleep |
Il coprocessore ULP è acceso. | 150 µA 100 µA @1% duty 10 µA | ||
Pattern monitorato dal sensore ULP | ||||
Timer RTC + memoria RTC | ||||
Hibernation | Solo timer RTC | 5 µA | ||
Power off | CHIP_PU è impostato su un livello basso, il chip è spento. | 1 µA |
Come misurare gli ampere
Ora controlleremo quanta energia consuma l’ESP32 in molte situazioni e configurazioni, qui lo schema di connessione che abbiamo usato.
Usando l’alimentatore esterno, alimentare l’esp32 con il pin 5v e il pin GND e scollegare l’USB. Per accedere usiamo la porta Serial2, ma se vuoi usare la porta Serial devi solo spostare il convertitore FTDI sul pin TX invece che sul pin TX2, non puoi usare l’USB perché alimenta il dispositivo e il multimetro ottiene un amperaggio errato.
Modem sleep (sospensione modem)
Se è necessario mantenere la connessione WiFi, abilitare la sospensione del modem WiFi e abilitare la funzione di sospensione leggera automatica. Ciò consentirà al sistema di riattivarsi dalla sospensione automaticamente quando richiesto dal driver WiFi, mantenendo così la connessione all’AP.
Dalla documentazione di Espressif
Il la modalità di sospensione del modem è abbastanza ambigua, alcune persone/blog sostengono che è la modalità di sospensione WiFi (ed Espressif lo conferma), altri che è quando tutte le radio (WiFi e Bluetooth) sono disabilitate.
Vero
Quindi se leggiamo la documentazione di Espressif il vero modem sleep è il normale funzionamento del WiFi (controlla il capitolo precedente), ecco un esempio di codice:
/*
* ESP32
* REAL Modem Sleep and wake up
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org/it/category/guide/guida-allesp32/esp32-risparmio-energetico-pratico/
*
*/
#include <WiFi.h>
#include <BluetoothSerial.h>
#include "driver/adc.h"
#include <esp_bt.h>
#define STA_SSID "<YOUR-SSID>"
#define STA_PASS "<YOUR-PASSWD>"
BluetoothSerial SerialBT;
void setModemSleep();
void wakeModemSleep();
void setup() {
Serial2.begin(115200);
while(!Serial2){delay(500);}
SerialBT.begin("ESP32test"); //Bluetooth device name
SerialBT.println("START BT");
Serial2.println("START WIFI");
WiFi.begin(STA_SSID, STA_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial2.print(".");
}
Serial2.println("");
Serial2.println("WiFi connected");
Serial2.println("IP address: ");
Serial2.println(WiFi.localIP());
setModemSleep();
Serial2.println("MODEM SLEEP ENABLED FOR 5secs");
}
//void loop() {}
unsigned long startLoop = millis();
bool started = false;
void loop() {
if (!started && startLoop+5000<millis()){
// Not use delay It has the own policy
wakeModemSleep();
Serial2.println("MODEM SLEEP DISABLED");
started = true;
}
}
void setModemSleep() {
WiFi.setSleep(true);
if (!setCpuFrequencyMhz(40)){
Serial2.println("Not valid frequency!");
}
// Use this if 40Mhz is not supported
// setCpuFrequencyMhz(80);
}
void wakeModemSleep() {
setCpuFrequencyMhz(240);
}
E si traduce in un consumo di energia di 40mA ~ 68mA , il minimo sulla sospensione automatica si attiva il massimo quando si riceve il messaggio beacon.
Falso
Ecco l’interpretazione più comune (falsa) del significato del termine modem sleep
Se hai già letto il primo capitolo sai che puoi disabilitare il WiFi con questi comandi
void disableWiFi(){
adc_power_off();
WiFi.disconnect(true); // Disconnect from the network
WiFi.mode(WIFI_OFF); // Switch WiFi off
}
Per ridurre i consumi è possibile disabilitare anche altre unità del gruppo Radio come il bluetooth con questo comando
void disableBluetooth(){
btStop();
}
Ma come abbiamo visto l’unico vantaggio di spegnere il WiFi è che è suscettibile ai messaggi beacon dalla rete, perché le impostazioni predefinite forniscono una modalità di sospensione WiFi che mette il WiFi in modalità di sospensione automaticamente per inattività ed è equivalente alla disattivazione del modem.
Poi bisogna prestare attenzione alla tabella del datasheet che si può ottenere un migliore modem sleep modificando le frequenze della CPU (vedi capitolo precedente), riducendo i MHz della CPU
setCpuFrequencyMhz(40);
Quindi ora sappiamo cosa dobbiamo fare per andare su Modem Sleep:
- Disabilita WiFi;
- Disabilita Bluetooth;
- Riduci la frequenza della CPU.
Il risultato sarà:
/*
* ESP32
* Modem Sleep and wake up
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org/it/category/guide/guida-allesp32/esp32-risparmio-energetico-pratico/
*
*/
#include <WiFi.h>
#include <BluetoothSerial.h>
#include "driver/adc.h"
#include <esp_bt.h>
#define STA_SSID "<YOUR-SSID>"
#define STA_PASS "<YOUR-PASSWD>"
BluetoothSerial SerialBT;
void setModemSleep();
void wakeModemSleep();
void setup() {
Serial2.begin(115200);
while(!Serial2){delay(500);}
SerialBT.begin("ESP32test"); //Bluetooth device name
SerialBT.println("START BT");
Serial2.println("START WIFI");
WiFi.begin(STA_SSID, STA_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial2.print(".");
}
Serial2.println("");
Serial2.println("WiFi connected");
Serial2.println("IP address: ");
Serial2.println(WiFi.localIP());
setModemSleep();
Serial2.println("MODEM SLEEP ENABLED FOR 5secs");
}
//void loop() {}
unsigned long startLoop = millis();
bool started = false;
void loop() {
if (!started && startLoop+5000<millis()){
// Not use delay It has the own policy
wakeModemSleep();
Serial2.println("MODEM SLEEP DISABLED");
started = true;
}
}
void disableWiFi(){
adc_power_off();
WiFi.disconnect(true); // Disconnect from the network
WiFi.mode(WIFI_OFF); // Switch WiFi off
Serial2.println("");
Serial2.println("WiFi disconnected!");
}
void disableBluetooth(){
// Quite unusefully, no relevable power consumption
btStop();
Serial2.println("");
Serial2.println("Bluetooth stop!");
}
void setModemSleep() {
disableWiFi();
disableBluetooth();
setCpuFrequencyMhz(40);
// Use this if 40Mhz is not supported
// setCpuFrequencyMhz(80);
}
void enableWiFi(){
adc_power_on();
delay(200);
WiFi.disconnect(false); // Reconnect the network
WiFi.mode(WIFI_STA); // Switch WiFi off
delay(200);
Serial2.println("START WIFI");
WiFi.begin(STA_SSID, STA_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial2.print(".");
}
Serial2.println("");
Serial2.println("WiFi connected");
Serial2.println("IP address: ");
Serial2.println(WiFi.localIP());
}
void wakeModemSleep() {
setCpuFrequencyMhz(240);
enableWiFi();
}
Con il Modem Sleep si può ottenere una notevole riduzione di potenza, si possono raggiungere 20mA e meno con 40Mhz (vedi capitolo precedente).
WeMos LOLIN32 and TTGO testing
Per il prossimo test voglio utilizzare altri microcontrollori, perché i produttori, spesso, creano queste schede senza pensare al risparmio energetico, e perciò dobbiamo sempre verificare se questi dispositivi sono adatto alla produzione o sono solo di test.
E dobbiamo prestare attenzione ai micro controller con gestione della batteria integrata perché possono dare soddisfazioni quando alimentati a batteria. I produttori gestiscono le unità funzionali per ottenere migliori prestazioni della batteria, ma andiamo a verificare la differenza con il multimetro.
Light sleep (Sonno leggero)
Il sonno leggero (light sleep) è diverso dal modem sleep, perché stai per mettere in pausa la CPU , quindi devi gestire quello stato con un comando speciale, e devi prima fornire al sistema la modalità di riattivazione.
Il sonno leggero può fallire se ci sono alcune connessioni attive (WiFi o Bluetooth), quindi per essere sicuro che non fallisca probabilmente devi disabilitare WiFi e Bluetooth.
In dettaglio in light sleep mode le periferiche digitali, la maggior parte della RAM e le CPU hanno una frequenza di clock ridotta ed anche la tensione di viene ridotta. All’uscita dalla modalità di sospensione leggera, le periferiche e le CPU riprendono a funzionare, ed il loro stato interno viene preservato.
Se non si seleziona una periferica come modalità risveglio
Presta attenzione a questi 2 sketchs, il primo sembra simile al secondo ma c’è una grande differenza nel consumo di energia, e ora spiegheremo meglio.
DOIT esp32 DEV KIT v1
Ora metteremo in sonno leggero un esp32 DOIT DEV KIT v1 con questo sketch:
/*
* ESP32
* Light Sleep and wake up
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org/it/category/guide/guida-allesp32/esp32-risparmio-energetico-pratico/
*
*/
#include <WiFi.h>
#include <BluetoothSerial.h>
#include "driver/adc.h"
#include <esp_bt.h>
#include <esp_wifi.h>
#include <esp_sleep.h>
#define STA_SSID "<YOUR-SSID>"
#define STA_PASS "<YOUR-PASSWD>"
BluetoothSerial SerialBT;
int variable = 0;
void setup() {
Serial2.begin(115200);
while(!Serial2){delay(500);}
SerialBT.begin("ESP32test"); //Bluetooth device name
SerialBT.println("START BT");
Serial2.println("START WIFI");
WiFi.begin(STA_SSID, STA_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial2.print(".");
}
Serial2.println("");
Serial2.println("WiFi connected");
Serial2.println("IP address: ");
Serial2.println(WiFi.localIP());
delay(1000);
variable += 10;
Serial2.println();
Serial2.println("LIGHT SLEEP ENABLED FOR 5secs");
delay(100);
esp_sleep_enable_timer_wakeup(5 * 1000 * 1000);
esp_light_sleep_start();
Serial2.println();
Serial2.println("LIGHT SLEEP WAKE UP");
Serial2.print("Variable = ");
Serial2.println(variable);
}
void loop() {
}
void disableWiFi(){
adc_power_off();
WiFi.disconnect(true); // Disconnect from the network
WiFi.mode(WIFI_OFF); // Switch WiFi off
Serial2.println("");
Serial2.println("WiFi disconnected!");
}
void enableWiFi(){
adc_power_on();
WiFi.disconnect(false); // Reconnect the network
WiFi.mode(WIFI_STA); // Switch WiFi off
Serial2.println("START WIFI");
WiFi.begin(STA_SSID, STA_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial2.print(".");
}
Serial2.println("");
Serial2.println("WiFi connected");
Serial2.println("IP address: ");
Serial2.println(WiFi.localIP());
}
void disableBluetooth(){
btStop();
esp_bt_controller_disable();
delay(1000);
Serial2.println("BT STOP");
}
DOIT DEV KIT v1
Ma il risultato non è così buono, questo dispositivo in modalità di sonno leggero consuma 4.89mA, molto lontano dagli 0.8mA dichiarati da Espressif.
Come puoi vedere il valore della variabile è 10 il quale è stato impostato prima di entrare in light sleep, questa è la caratteristica più importante del light sleep, il programma viene sospeso e lo stato viene ripristinato.
All’inizio ero depresso , ma poi ho riflettuto sul fatto che quella cifra era correlata al chip esp32 e basta.
Ma in una scheda di sviluppo ci sono molti altri componenti che possono cambiare il risultato , pensa a LED, regolatori di tensione, ecc.
Quindi provo a fare lo stesso test con due famosi produttori di schede, che hanno dispositivi con gestione della batteria e altre funzionalità, non solo per sviluppatori.
TTGO T8
Per prima cosa voglio provare un TTGO, che è uno dei più famosi produttori di questo tipo di dispositivo, con molte varianti, utilizzo uno dei suoi migliori prodotti il TTGO T8.
Il risultato con alimentazione a 5v dal pin specifico dà un cattivo risultato 8.24mA, ma la scheda quando alimentata solo con batteria esclude alcune unità funzionali come il regolatore di tensione led ecc., Quindi lo stesso test con alimentazione a batteria arriva a 3,73mA, molto meglio del primo risultato e molto meglio del DOIT DEV KIT v1.
WeMos LOLIN32
Quindi il WeMos LOLIN32, adoro WeMos come produttore, penso che abbia un buon set di dispositivi e molto versatili con dimensioni diverse.
Il risultato con alimentazione a 5V dal pin specifico dà un risultato decisamente migliore di 2.60mA, ma la scheda quando alimentata solo con la batteria raggiunge 1.52mA , e questo è un risultato soddisfacente.
Risultato
I dati sono molto chiari, il DOIT DEV KIT v1 è il perdente e il LOLIN32 è il vincitore, TTGO ha il prezzo più alto, non lo ritengo soddisfacente.
Device | Mode | Power |
---|---|---|
DOIT DEV KIT v1 | Power to VIN pin | 4.98mA |
TTGO T8 | Power to 5V pin | 8.24mA |
Power via Battery | 3.73mA | |
WeMos LOLIN32 | Power via 5V pin | 2.60mA |
Power via Battery | 1.52mA |
RTC altre sorgenti wake up
Ma non abbiamo usato RTC come sorgente di risveglio, e se presti attenzione allo schema, RTC ha una posizione a parte nei moduli funzionali.
Ma altre sorgenti di risveglio (come quella esterna) sono posizionata in altri blocchi funzionale. Quindi cosa succede se usiamo una sorgente di risveglio esterna come l’RTC?
Useremo lo schizzo precedente ma aggiungeremo una wake-up source esterna.
esp_sleep_enable_timer_wakeup(5 * 1000 * 1000);
esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,1);
esp_light_sleep_start();
e qui il risultato
Device | Mode | Power |
---|---|---|
DOIT DEV KIT v1 | Power to VIN pin | 6.85mA (+1,87mA) |
TTGO T8 | Power to 5V pin | 10.05mA (+1,81mA) |
Power via Battery | 5.04mA (+1,31mA) | |
WeMos LOLIN32 | Power via 5V pin | 4.35mA (+1,75mA) |
Power via Battery | 3.54mA (+2,02mA) |
Il modulo RTC IO contiene la logica per la riattivazione quando uno dei GPIO RTC è impostato su un livello logico predefinito. RTC IO fa parte del dominio di alimentazione delle periferiche RTC, quindi le periferiche RTC verranno mantenute accese durante la sospensione profonda se viene richiesta questa sorgente di attivazione.
Dalla documentazione di Espressif
Presta attenzione a queste parole perché saranno importanti per spiegare la differenza tra ibernazione e sonno profondo.
Grazie
In questo articolo apprendiamo che dispositivi diversi hanno risultati diversi, quindi quando stai per acquistare un dispositivo ricordati di controllare la qualità.
- ESP32: piedinatura, specifiche e configurazione dell’Arduino IDE
- ESP32: fileSystem integrato SPIFFS
- ESP32: gestire più seriali e logging per il debug
- ESP32 risparmio energetico pratico
- ESP32 risparmio energetico pratico: gestire WiFi e CPU
- ESP32 risparmio energetico pratico: modem e light sleep
- ESP32 risparmio energetico pratico: deep sleep e ibernazione
- ESP32 risparmio energetico pratico: preservare dati al riavvio, sveglia a tempo e tramite tocco
- ESP32 risparmio energetico pratico: sveglia esterna e da ULP
- ESP32 risparmio energetico pratico: sveglia da UART e GPIO
- ESP32: filesystem integrato LittleFS
- ESP32: filesystem integrato FFat (Fat/exFAT)
- ESP32-wroom-32
- ESP32-CAM
- ESP32: ethernet w5500 con chiamate standard (HTTP) e SSL (HTTPS)
- ESP32: ethernet enc28j60 con chiamate standard (HTTP) e SSL (HTTPS)
- Come usare la scheda SD con l’esp32
- esp32 e esp8266: file system FAT su memoria SPI flash esterna
- Gestione aggiornamenti firmware e OTA
- Gestione del firmware
- Aggiornamento OTA con Arduino IDE
- Aggiornamento OTA con browser web
- Aggiornamenti automatici OTA da un server HTTP
- Aggiornamento del firmware non standard
- Integrare LAN8720 con ESP32 per la connettività Ethernet con plain (HTTP) e SSL (HTTPS)
- Collegare l’EByte E70 (CC1310) ai dispositivi ESP32 c3/s3 ed un semplice sketch di esempio
- ESP32-C3: piedinatura, specifiche e configurazione dell’IDE Arduino
- Integrazione del modulo W5500 su ESP32 con Core 3: supporto nativo ai protocolli Ethernet con SSL e altre funzionalità
- Integrazione del modulo LAN8720 su ESP32 con Core 3: supporto nativo del protocollo Ethernet con SSL e altre funzionalità.