Deep Sleep su ESP32: progetti a batteria che durano mesi

Published on 02/05/2026 ESP32

Il problema del consumo

Un ESP32 in funzione assorbe 80-260 mA. Con una batteria 18650 da 3000 mAh dura meno di 24 ore. Il deep sleep abbassa il consumo a 10-150 µA: la stessa batteria può durare anche 5 anni se il dispositivo si sveglia ogni ora per qualche secondo.

Cosa è il deep sleep

In deep sleep ESP32 spegne CPU, WiFi, Bluetooth e RAM principale. Restano attivi solo:

  • RTC controller — l'orologio interno per i timer di wake-up
  • RTC memory — 8 KB di RAM persistente tra cicli sleep/wake
  • RTC GPIO — pin che possono svegliare il chip

Sleep con wake-up timer

#include "esp_sleep.h"

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("Faccio cose utili...");
  // lettura sensore, invio MQTT, ecc.

  Serial.println("Vado in sleep per 10 minuti");
  esp_sleep_enable_timer_wakeup(10ULL * 60 * 1000000);  // microsecondi
  esp_deep_sleep_start();
}

void loop() {} // mai chiamato

Dopo 10 minuti l'ESP32 si risveglia ed esegue di nuovo setup(). Non c'è "ripresa" del codice precedente: ogni risveglio è come un reset, ma più veloce (~250 ms).

RTC memory: ricordare tra un sleep e l'altro

RTC_DATA_ATTR int boot_count = 0;

void setup() {
  boot_count++;
  Serial.printf("Risveglio numero %d\n", boot_count);
  esp_sleep_enable_timer_wakeup(60 * 1000000);
  esp_deep_sleep_start();
}

Variabili marcate RTC_DATA_ATTR sopravvivono al deep sleep. Utile per contatori, ultimo valore letto, stato di calibrazione.

Wake-up da pulsante (RTC GPIO)

I pin GPIO 0, 2, 4, 12-15, 25-27, 32-39 sono RTC GPIO e possono svegliare ESP32:

#define BUTTON_PIN GPIO_NUM_33

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  esp_sleep_enable_ext0_wakeup(BUTTON_PIN, 0); // 0 = LOW
  esp_deep_sleep_start();
}

Quando l'utente preme il pulsante (lo collega a GND), ESP32 si sveglia.

Misurare il consumo reale

Con un multimetro in serie sull'alimentazione vedrai sì il deep sleep, ma l'avvio momentaneo (200-500 mA per 1-2 secondi durante il boot e l'invio WiFi) è quello che pesa di più sulla batteria.

Strategia: minimizzare il tempo "on". Esempio per un sensore temperatura ogni 10 min:

  • Boot: 0.5 s @ 200 mA
  • WiFi connect: 2 s @ 150 mA
  • MQTT publish: 0.2 s @ 80 mA
  • Sleep: 600 s @ 20 µA

Consumo medio: ~0.85 mAh / ora → 18650 da 3000 mAh dura ~150 giorni teorici, ~100 reali con margine.

Trucchi per ridurre il tempo "on"

  • Static IP invece di DHCP (risparmia 1-2 secondi)
  • Salva BSSID + canale WiFi in RTC memory: dopo il primo connect skippa la scansione (-3 s)
  • Usa MQTT QoS 0 invece di QoS 1 (niente ack, send-and-forget)
  • Abbassa CPU clock a 80 MHz quando non servono prestazioni: setCpuFrequencyMhz(80);

Hardware per consumi estremi

I moduli economici hanno regolatori AMS1117 che da soli consumano 10 mA in stand-by. Per progetti seri usa schede come LilyGO T-PicoC3 o moduli ESP32-S3 con regolatori switching: consumo in deep sleep sotto 10 µA.