Stazione meteo: primo firmware sulla XIAO ESP32-C6 (PlatformIO/Arduino)

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

  1. In VS Code, PlatformIO → New Project
  2. Nome: 02-firmware-base
  3. Board: cerca “Seeed XIAO ESP32C6”
  4. 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_ATTR mette 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 da setup() 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.

Riguardo

Imprenditore, maker, MBSE enthusiast e co-autore di Web App Portal. Collegati su LinkedIn.