Stazione meteo: primo firmware sulla XIAO ESP32-C6 (PlatformIO/Arduino)
Da questo articolo iniziamo a scrivere codice per la stazione meteo. Prima tappa: prendere confidenza con la Seeed XIAO ESP32-C6, la scheda scelta per tutta la serie, con un primo firmware che fa lampeggiare il LED integrato e va in deep sleep — il comportamento che userà l’intero progetto finale per durare mesi con una batteria.
Cosa ti serve
- Una Seeed XIAO ESP32-C6
- Un cavo USB-C dati (non solo ricarica)
- Facoltativo: un misuratore USB-C con display (pochi euro online) per vedere il consumo in tempo reale, ad esempio FNIRSI® FNAC-28 Tester USB Tipo-C 2-IN-1 Voltmetro Digitale Amperometro

Rispetto alle dev board classiche (tipo ESP32-DevKitC) la XIAO è pensata per il basso consumo e l’ingombro minimo: pochi pin esposti, ma include già il circuito di carica per una batteria LiPo collegata al connettore JST a due poli sul retro. Il LED utente integrato è pilotabile via il pin LED_BUILTIN, definito automaticamente da PlatformIO per questa board — non serve conoscere il numero di GPIO esatto.
Creazione del progetto PlatformIO
- In VS Code, PlatformIO → New Project
- Nome:
02-firmware-base - Board: cerca “Seeed XIAO ESP32C6”
- Framework: Arduino
Il codice
#include <Arduino.h>
// Contatore persistente tra i risvegli: la RAM normale viene azzerata
// al risveglio da deep sleep, la RTC memory no.
RTC_DATA_ATTR int bootCount = 0;
#define SLEEP_SECONDS 10
void setup() {
Serial.begin(115200);
delay(200);
bootCount++;
Serial.printf("Risveglio numero: %d\n", bootCount);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW); // su molte board il LED e' attivo basso
delay(300);
digitalWrite(LED_BUILTIN, HIGH);
Serial.printf("Vado in deep sleep per %d secondi...\n", SLEEP_SECONDS);
Serial.flush();
esp_sleep_enable_timer_wakeup((uint64_t)SLEEP_SECONDS * 1000000ULL);
esp_deep_sleep_start();
}
void loop() {
// non viene mai eseguito: dopo il setup si va subito in deep sleep
}
Come funziona
-
RTC_DATA_ATTRmette la variabile nella RTC memory, l’unica area che sopravvive al deep sleep: è così che il firmware “ricorda” quanti risvegli sono avvenuti -
esp_sleep_enable_timer_wakeup()programma un timer hardware che risveglierà il chip dopo il tempo indicato, in microsecondi -
esp_deep_sleep_start()spegne quasi tutto il chip: al risveglio non riprende da dove aveva lasciato, riparte dasetup()come se fosse un reset — è per questo che serve la RTC memory per mantenere lo stato -
Serial.flush()è importante che venga fatto prima di entrare in sleep: garantisce che i messaggi di log vengano inviati, in sleep la seriale è spenta
Caricamento e verifica
Carica il firmware mediante porta USB: viene virtualizzata una porta seriale (115200 baud) e osserva: il LED lampeggia brevemente, poi ogni 10 secondi vedrai un nuovo “Risveglio numero” incrementarsi. Se scolleghi e ricolleghi l’alimentazione, il contatore riparte da 1 (la RTC memory si azzera solo con un power-cycle completo, non con il deep sleep).
Misurare il consumo (facoltativo ma istruttivo)
Se hai un misuratore USB-C, collega la XIAO attraverso di esso: vedrai il consumo salire per una frazione di secondo all’avvio (decine di mA), poi scendere quasi a zero durante il deep sleep. Questa differenza è il motivo per cui una stazione meteo a batteria può durare mesi: passa la quasi totalità del tempo in questo stato a bassissimo consumo, svegliandosi solo per il tempo strettamente necessario.
Va oltre
Nel prossimo tutorial rifacciamo esattamente questo stesso esempio — blink e deep sleep — ma in ESP-IDF nativo, senza framework Arduino: vedremo come lo stesso comportamento si ottiene con le API dirette di Espressif, e confronteremo i due approcci.

