Perché la tua stazione meteo ESP32 si blocca dopo 24 ore (e come risolvere il problema)

I progetti IoT scolastici con ESP32 si bloccano raramente a causa del silicio difettoso. Vanno invece in tilt per la frammentazione dinamica della memoria heap, i cicli bloccanti di riconnessione Wi-Fi e la mancata gestione dei watchdog hardware.
Se la stazione meteo con ESP32 realizzata in classe funziona alla perfezione sul banco di laboratorio durante la quarta ora ma smette del tutto di rispondere la mattina seguente, il silicio non è difettoso. I microcontrollori non si degradano nell'arco di ventiquattr'ore. Al contrario, il software embedded a lunga esecuzione si arresta quasi sempre per due problemi silenziosi e cumulativi: la frammentazione della memoria heap dovuta a operazioni dinamiche sul testo e le cadute di rete non gestite che intrappolano il processore in un ciclo bloccante infinito.
Risolvere questi problemi richiede di abbandonare le scorciatoie della prototipazione rapida e adottare le prassi standard dell'ingegneria embedded: buffer di memoria a dimensione fissa, macchine a stati di rete non bloccanti e un timer watchdog hardware.
Primo colpevole: stringhe dinamiche e frammentazione dell'heap
L'ESP32 dispone all'incirca di 320 KB di SRAM interna utilizzabile. In una stazione meteo che interroga i sensori ogni dieci secondi, il codice scritto con la classe standard String di Arduino alloca, ridimensiona e libera piccoli blocchi di memoria migliaia di volte al giorno:
// Il pattern che compromette silenziosamente il progetto:
String payload = "{\"temp\": ";
payload += String(temperature);
payload += ", \"humidity\": ";
payload += String(humidity);
payload += "}";
http.POST(payload);Ogni volta che vengono create e concatenate stringhe dinamiche all'interno di loop(), il runtime C++ alloca spazio sull'heap. Poiché anche altri task di sistema in background (come gli stack Wi-Fi e Bluetooth) allocano memoria contemporaneamente, questa continua allocazione e deallocazione trasforma l'heap in un groviera. La memoria libera totale potrebbe ancora indicare 150 KB, ma il blocco contiguo libero più grande si riduce a poche centinaia di byte. Quando lo stack Wi-Fi o il serializzatore JSON richiede improvvisamente un blocco contiguo da 2 KB per un pacchetto TCP, l'allocazione fallisce, restituendo un puntatore nullo che scatena un kernel panic silenzioso o un blocco anomalo non gestito.
La soluzione: utilizzare buffer sullo stack a dimensione fissa e snprintf. Il firmware per microcontrollori dovrebbe allocare buffer statici o basati sullo stack la cui dimensione sia nota al momento della compilazione.
// Alternativa robusta senza allocazioni sull'heap:
char payload[128];
snprintf(payload, sizeof(payload),
"{\"temp\":%.2f,\"humidity\":%.2f}",
temperature, humidity);
http.POST((uint8_t*)payload, strlen(payload));Secondo colpevole: il ciclo di riconnessione al Wi-Fi della scuola
Negli ambienti scolastici, la rete Wi-Fi è raramente stabile. Gli access point rinnovano i token di sicurezza, i lease DHCP scadono e le interruzioni di corrente locali o le transizioni di distacco programmato del carico (load shedding) disconnettono brevemente i router a monte, anche se la stazione IoT funziona a batteria. Molti tutorial introduttivi suggeriscono di riconnettersi al Wi-Fi in questo modo:
if (WiFi.status() != WL_CONNECTED) {
WiFi.reconnect();
while (WiFi.status() != WL_CONNECTED) {
delay(500); // Fatale: blocca il processore a tempo indefinito
}
}Se il router si riavvia e impiega due minuti per attivare la sottorete locale, questo ciclo while blocca l'esecuzione. Poiché FreeRTOS esegue lo stack Wi-Fi e i task di gestione del sistema sui due core, bloccare il loop principale può privare di risorse i task di watchdog in background, causando un reset hardware immediato o un blocco permanente dei task.
La soluzione: gestire la connettività come una macchina a stati non bloccante. Non interrompere mai l'esecuzione in attesa di una connessione. Se il Wi-Fi non è disponibile, salva i dati localmente nella memoria flash o su una scheda SD e ritenta la connessione a intervalli programmati senza interrompere le letture dei sensori.
Terzo colpevole: l'assenza dei timer watchdog
Per quanto il codice sia pulito, i sensori esterni, i picchi elettrici generati da compressori vicini o le linee del bus I2C che non rispondono (soprattutto con i diffusissimi sensori BME280 o DHT22) possono trascinare l'ESP32 in un deadlock hardware. Se un sensore non rilascia la linea di clock dell'I2C, la libreria Wire standard può rimanere bloccata all'infinito.
Un Task Watchdog Timer (TWDT) monitora i cicli critici. Se il loop principale non riesce ad «alimentare» o reimpostare il watchdog entro un intervallo prestabilito (ad es. 8 secondi), l'ESP32 avvia automaticamente un riavvio forzato e ripristina il funzionamento senza necessità di intervento manuale.
#include <esp_task_wdt.h>
#define WDT_TIMEOUT_SECONDS 8
void setup() {
// Inizializza il watchdog per un timeout di 8 secondi
esp_task_wdt_init(WDT_TIMEOUT_SECONDS, true);
esp_task_wdt_add(NULL); // Registra il thread corrente
}
void loop() {
// Reimposta il timer watchdog a ogni ciclo
esp_task_wdt_reset();
readSensors();
sendTelemetry();
// Evita delay() lunghi; utilizza controlli non bloccanti con millis()
}Una nota sulla stabilità dell'alimentazione
Prima di presumere che un bug sia puramente software, è opportuno controllare la linea di alimentazione hardware. L'ESP32 assorbe brevi picchi di corrente fino a 350–500 mA durante le raffiche di trasmissione Wi-Fi (calibrazione RF e invio di pacchetti). Se la scheda è alimentata da un cavo USB sottile collegato a un computer portatile o da un alimentatore da parete economico a 5V, i cali di tensione al di sotto della soglia di brownout di 2,7V inducono il rilevatore interno di brownout a provocare un riavvio improvviso.
- Posiziona un condensatore elettrolitico da 100 µF a 470 µF tra i pin
VINeGNDper assorbire i picchi di corrente transitori. - Assicurati che il rilevatore di brownout sia abilitato nel tuo framework anziché disattivato, poiché i cali di tensione possono danneggiare la memoria flash interna.
Se stai realizzando stazioni di monitoraggio da campo per le scienze ambientali o per il perimetro scolastico, la progettazione didattica di Sheen IoT offre framework hardware modulari e pattern firmware pronti per la produzione che evitano queste classiche criticità delle aule scolastiche.



