ESP32 risparmio energetico pratico: gestire WiFi e CPU – 1
L’ESP32 è in grado di attivare le modalità di risparmio energetico del sonno leggero (light sleep) e del sonno profondo (deep sleep), in molti casi non possiamo utilizzare una tale soluzione, ma è comunque possibile applicare alcune opzioni alle unità funzionali alla riduzione dei consumi energetici.
You can find various type of ESP32 to ESP32 Dev Kit v1 - TTGO T-Display 1.14 ESP32 - NodeMCU V3 V2 ESP8266 Lolin32 - NodeMCU ESP-32S - WeMos Lolin32 - WeMos Lolin32 mini - ESP32-CAM programmer - ESP32-CAM bundle - ESP32-WROOM-32 - ESP32-S
In modalità di sospensione leggera, le periferiche digitali, la maggior parte della RAM e le CPU sono regolate dal clock e la tensione di alimentazione è ridotta. All’uscita dalla modalità di sospensione leggera, le periferiche e le CPU riprendono a funzionare, ed il loro stato interno è preservato.
In modalità deep sleep, le CPU, la maggior parte della RAM e tutte le periferiche digitali gestite dal clock dell’Advanced Peripheral Bus (APB_CLK) sono spente. Le uniche parti del chip che rimangono ancora essere accese sono: controller dell’orologio in tempo reale (RTC), le periferiche RTC, incluso il coprocessore Ultra Low Power (ULP) e memorie RTC (lente e veloci).
In questa tabella puoi vedere la tabella dal datasheet dell’esp32 con le informazioni su come sono raggruppate la modalità di sleep.
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.
Per la lettura seriale puoi fare riferimento all’articolo “ESP32: gestire più seriali e logging per il debug“.
Gestione WiFi
Un sistema per gestire la durata della batteria consiste nel lavorare su delle unità singole del microcontrollore, come vedi nello schema in alto ci sono molte unità funzionali che non usi, o che puoi gestire.
Riduci la comunicazione con il WiFi
L’attivazione del WiFi o del Bluetooth consuma ampere, ma è quando comunicano che consumano molta potenza come puoi vedere in questa tabella:
Mode | Min | Typ | Max | Unit |
Trasmissione 802.11b, DSSS 1 Mbps, POUT = +19.5 dBm | – | 240 | – | mA |
Trasmissione 802.11g, OFDM 54 Mbps, POUT = +16 dBm | – | 190 | – | mA |
Trasmissione 802.11n, OFDM MCS7, POUT = +14 dBm | – | 180 | – | mA |
Ricezione 802.11b/g/n | – | 95 ~ 100 | – | mA |
Trasmissione BT/BLE, POUT = 0 dBm | – | 130 | – | mA |
Ricezione BT/BLE | – | 95 ~ 100 | – | mA |
Quindi la prima cosa che puoi fare è ridurre il tempo di comunicazione al minimo possibile.
WiFi: attiva le modalità di risparmio energetico o ottieni le migliori prestazioni
Se è necessario mantenere la connessione WiFi, abilitare la sospensione del modem (modem-sleep) WiFi e/o abilitare la funzione di sospensione leggera (light-sleep) automatica. Ciò consentirà al sistema di riattivarsi dalla sospensione automaticamente quando richiesto dal driver WiFi, mantenendo così la connessione all’AP.
Puoi gestire la gestione del risparmio energetico WiFi, ci sono 3 possibilità che puoi impostare
WIFI_PS_NONE
: disabilita completamente la sospensione del modem;WIFI_PS_MIN_MODEM
: attiva la modalità di risparmio energetico minimo Modem-sleep;WIFI_PS_MAX_MODEM
: per abilitare la modalità di risparmio energetico massimo di sospensione del modem.
WIFI_PS_MIN_MODEM è il parametro predefinito, quando la sospensione del modem è abilitata, i dati Wi-Fi ricevuti possono essere ritardati per tutto il periodo DTIM.
DTIM è l’acronimo di Delivery Traffic Indication Message.
Un delivery traffic indication map (DTIM) è un tipo di messaggio di indicazione del traffico atto ad informare i client della presenza di dati multicast/broadcast e/o memorizzati nel buffer dell’Access Point. Tale messaggio viene generato dopo ogni periodo DTIM specificato nel beacon, cioè nei pacchetti inviati dall’Access Point per la sincronizzazione della rete wireless. I normali messaggi di indicazione del traffico (Traffic Indication Message, (TIM)) che sono presenti in ogni beacon servono a segnalare la presenza di dati unicast bufferizzati. Successivamente ad un DTIM, l’Access Point invierà i dati multicast/broadcast sul canale in accordo alle normali regole di accesso al mezzo (CSMA/CA).
Il problema del periodo DTIM è che se hai molto traffico nella tua rete è possibile che tu riceva molti messaggi beacon.
WIFI_PS_MAX_MODEM quando la sospensione del modem è abilitata, i dati Wi-Fi ricevuti possono essere ritardati per tutto l’intervallo di ascolto, questa funzionalità è nascosta dal core E32 predefinito, perché non c’è un grande guadagno con questa tecnica.
WIFI_PS_NONE disabilita completamente la sospensione del modem. Questo ha un consumo energetico molto più elevato, ma fornisce una latenza minima per la ricezione dei dati Wi-Fi in tempo reale.
Con il mio esp32 DEV KIT v1 ottengo questa differenza di consumo energetico.
Modalità sleep WiFi | Consumo energetico (nessun invio) |
---|---|
WIFI_PS_NONE | 145mA |
WIFI_PS_MIN_MODEM (default) | 80mA ~ 108mA |
WIFI_PS_MAX_MODEM | 80mA ~ 108mA |
Ma ora passiamo alla parte più interessante, come gestire questo tipo di risparmio energetico.
Prendi questo codice come esempio
/*
* ESP32
* Manage WiFi sleep mode
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org
*
* You may copy, alter and reuse this code in any way you like, but please leave
* reference to www.mischianti.org in your comments if you redistribute this code.
*/
#include <WiFi.h>
#include <BluetoothSerial.h>
#define STA_SSID "<YOUR-SSID>"
#define STA_PASS "<YOUR-PASSWD>"
BluetoothSerial SerialBT;
void setWiFiPowerSavingMode();
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(".");
}
setWiFiPowerSavingMode();
Serial2.println("");
Serial2.println("WiFi connected");
Serial2.println("IP address: ");
Serial2.println(WiFi.localIP());
}
void loop() {
}
void setWiFiPowerSavingMode(){
WiFi.setSleep(true);
}
Con questo codice si imposta il parametro di default, quindi si imposta WIFI_PS_MIN_MODEM
, se si rimuove la linea setWiFiPowerSavingMode();
il consumo energetico rimane lo stesso, circa 80mA ~ 108mA , il consumo minimo è quando non sono presenti messaggi beacon (quindi sleep) , il massimo è quando messaggi beacon arrivo.
Se cambi la funzione in questo modo
void setWiFiPowerSavingMode(){
WiFi.setSleep(false);
}
ll consumo di energia cambia drasticamente e aumenta a 145mA , con l’istruzioni che hai impostato, WIFI_PS_NONE
, ora non ci sono latenze nel tuo WiFi e aumenta la velocità di trasferimento dei pacchetti .
Come ho già scritto, la terza modalità WIFI_PS_MAX_MODEM
è “nascosta”, per abilitarla è necessario importare un nuovo pacchetto e utilizzare istruzioni primitive.
#include <esp_wifi.h>
[...]
void setWiFiPowerSavingMode(){
esp_wifi_set_ps(WIFI_PS_MAX_MODEM);
// esp_wifi_set_ps(WIFI_PS_NONE);
// esp_wifi_set_ps(WIFI_PS_MIN_MODEM);
}
Sembra che non ci sia differenza, ma l’intervallo del messaggio di controllo diventa meno frequente perché controlla le comunicazioni a intervalli regolari (non quando arriva il messaggio beacon) e il consumo energetico rimane simile a 80mA ~ 108mA e non cambia i problemi della batteria, ma in una rete trafficata potrebbe fare la differenza.
Disattiva WiFi
Se non hai bisogno del WiFi, ogni volta che puoi fermalo con il comando specificato,
È anche utile disabilitare l’ADC, altrimenti potresti avere problemi. L’ESP32 integra due ADC SAR (Successive Approximation Register) a 12 bit che supportano un totale di 18 canali di misurazione (pin analogici abilitati).
ADC2 è utilizzato dal driver Wi-Fi . Pertanto l’applicazione può utilizzare l’ADC2 solo quando il driver Wi-Fi non è stato avviato.
ecco un semplice esempio.
/*
* ESP32
* Disable WiFi
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org
*
* You may copy, alter and reuse this code in any way you like, but please leave
* reference to www.mischianti.org in your comments if you redistribute this code.
*/
#include <WiFi.h>
#include <BluetoothSerial.h>
#include <esp_wifi.h>
#include "driver/adc.h"
#define STA_SSID "<YOUR-SSID>"
#define STA_PASS "<YOUR-PASSWD>"
BluetoothSerial SerialBT;
void disableWiFi();
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());
disableWiFi();
Serial2.println("WiFi disconnected");
}
void loop() {
}
void disableWiFi(){
adc_power_off();
WiFi.disconnect(true); // Disconnect from the network
WiFi.mode(WIFI_OFF); // Switch WiFi off
}
Come puoi vedere il consumo di energia rimane simile, circa 72 mA (solo 8 ~ 12 mA) ma il vero vantaggio è quando arriva un messaggio beacon, non più fluttuazioni nel consumo energetico, quindi quando il messaggio beacon viaggia sulla rete il vantaggio diventa 18 ~ 46 mA.
Per ripristinare il WiFi la funzione è:
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());
}
Gestione della CPU
Un’altra caratteristica importante da utilizzare per ridurre il consumo di energia è tagliare le frequenze della CPU.
CPU freq. | N° Core | Power Consumption |
---|---|---|
240 MHz | Dual-core | 30 mA ~ 68 mA |
Single-core | N/A | |
160 MHz | Dual-core | 27 mA ~ 44 mA |
Single-core | 27 mA ~ 34 mA | |
Normal speed: 80 MHz | Dual-core | 20 mA ~ 31 mA |
Single-core | 20 mA ~ 25 mA |
Esiste un metodo semplice per ottenere e impostare le frequenze della CPU getCpuFrequencyMhz()
e setCpuFrequencyMhz(80)
.
L’unico valore ammesso (controlla la tabella) è 240, 160 e 80, ma ho provato con un valore inferiore e sembra che funzioni correttamente (controlla il video con 40Mhz, 20Mhz e 10MHz).
Ecco un semplice esempio su come impostare 80Mhz come frequenza.
/*
* ESP32
* Manage CPU Frequences
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org
*
* You may copy, alter and reuse this code in any way you like, but please leave
* reference to www.mischianti.org in your comments if you redistribute this code.
*/
#include "Arduino.h"
void setup()
{
Serial2.begin(115200);
while (!Serial2){
delay(500);
}
Serial2.print("CPU Freq: ");
Serial2.println(getCpuFrequencyMhz());
setCpuFrequencyMhz(80);
Serial2.print("CPU Freq: ");
Serial2.println(getCpuFrequencyMhz());
}
void loop()
{
}
Faccio qualche prova, come potete vedere nel video, e verifico che senza alcuna gestione il consumo è di circa 66,8mA .
Impostando
setCpuFrequencyMhz(160);
è 45.9mA, con
setCpuFrequencyMhz(80);
La potenza diventa 33.2mA, e con
setCpuFrequencyMhz(40);
è 19.88mA, poi provo
setCpuFrequencyMhz(20);
e la potenza diventa 15.43mA, e con
setCpuFrequencyMhz(10);
la potenza diventa 13.19mA.
Frequenza | Consumo |
---|---|
240Mhz | 66.8mA |
160Mhz | 45.9mA |
80Mhz | 33.2mA |
40Mhz | 19.88mA |
20Mhz | 15.43mA |
10Mhz | 13.19mA |
Grazie
- 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à.
Grazie, i tuoi tutorial sono fatti benissimo. Ora ho potuto impostare WiFi.setSleep(false); sul mio esp perché non volevo che andasse mai in sleep mode.
Hehehe.. grazie Pietro, ci provo, li scrivo di notte e alle volte quando li rileggo mi accorgo che sono pure sgrammaticati.
Ciao Renzo
Ciao,
una cosa non mi è chiara. Ci si può risvegliare da modem sleep anche con BLE o è qualcosa solo per WiFi? grazie
Ciao Emme,
si vale anche per BLE, come chiarisce la documentazione ufficiale Espressif
Ciao RM
Grazie Renzo. Dovrò masticare un po’ la cosa e fare esperimenti ….. sto cercando di allungare al massimo la durata della batteria di un dispositivo senza perdere reattività nel rispondere a sporadici comandi BLE da app di cellulare senza bruciarmi tutta la batteria in meno di dieci ore. quindi svegliarsi a intervalli regolari e pollare non si può fare, devo essere il più possibile vicino al real time (un secondo di ritardo si può accettare).Non c’è moltissimo in merito in giro!
Nel senso – il dispositivo di solito è spento, ma quando lo accendo, pilota via gpio altre periferiche collegate (un exciter audio, per fare suoni e forme d’onda…), e una volta che riceve il comando di “partire” in realtà non c’ comunicazione finchè non gli dico “basta”, solo che tenere acceso anche BLE sempre porta via 40mA di suo …. questa è la croce della questione
Se devi ridurre così tanto i consumi l’unica via è usare l’UPL per fare un qualche genere di polling, di sicuro tra i vari comandi troverai qualche cosa che fa al caso tuo, ma non è mai una gioia avere a che fare con l’UPL.
Ciao RM
UPL? O intendi lo ultra low power processor?
Hehehe.. si si, ULP.