Una stazione meteo domestica con dati in tempo reale in Home Assistant è uno dei progetti IoT più soddisfacenti da costruire: componenti economici, poche righe di firmware, e un risultato che usi davvero ogni giorno per decidere se prendere l'ombrello. Il cuore del progetto è il sensore BME280 (Bosch), che in un solo package misura temperatura, umidità relativa e pressione atmosferica via I2C.
Collegamento hardware
Il BME280 comunica via I2C, quindi bastano quattro fili verso l'ESP32:
VCC→ 3.3V (attenzione: molti moduli BME280 economici NON sono 5V-tolerant)GND→ GNDSCL→ GPIO 22 (default I2C su molte board ESP32 DevKit)SDA→ GPIO 21
Per un'installazione esterna, il sensore va protetto dalla pioggia diretta ma non sigillato ermeticamente: serve comunque un minimo di ricircolo d'aria per una lettura di umidità/pressione realistica — uno schermo tipo Stevenson-screen in miniatura, anche stampato in 3D, risolve il problema.
Firmware: lettura del sensore
#include <Wire.h>
#include <Adafruit_BME280.h>
Adafruit_BME280 bme;
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
if (!bme.begin(0x76)) { // alcuni moduli usano 0x77: prova entrambi
Serial.println("BME280 non trovato");
while (1) delay(1000);
}
}
void loop() {
float temp = bme.readTemperature(); // °C
float hum = bme.readHumidity(); // %
float pres = bme.readPressure() / 100.0F; // hPa
Serial.printf("T=%.1f°C U=%.1f%% P=%.1f hPa\\n", temp, hum, pres);
delay(30000);
}
Pubblicazione via MQTT
Home Assistant "auto-scopre" i sensori se pubblichi anche un messaggio di discovery MQTT una tantum, oltre ai dati periodici:
#include <PubSubClient.h>
WiFiClient espClient;
PubSubClient mqtt(espClient);
void pubblicaDiscovery() {
mqtt.publish("homeassistant/sensor/meteo_giardino_temp/config",
"{\\"name\\":\\"Temperatura giardino\\",\\"state_topic\\":\\"meteo/giardino/temperatura\\","
"\\"unit_of_measurement\\":\\"°C\\",\\"device_class\\":\\"temperature\\"}", true);
// ripeti per umidita' e pressione con i rispettivi topic/device_class
}
void loop() {
mqtt.loop();
mqtt.publish("meteo/giardino/temperatura", String(bme.readTemperature(),1).c_str());
mqtt.publish("meteo/giardino/umidita", String(bme.readHumidity(),1).c_str());
mqtt.publish("meteo/giardino/pressione", String(bme.readPressure()/100.0F,1).c_str());
delay(30000);
}
Il flag true nel publish del discovery imposta il messaggio come retained: resta memorizzato sul broker, così Home Assistant lo riceve anche se si riavvia dopo che l'ESP32 lo ha già pubblicato.
Calibrazione: il dettaglio che tutti saltano
Il BME280 misura la temperatura vicino ai propri componenti elettronici, che scaldano leggermente: in un case chiuso o vicino a un ESP32 attivo, la lettura può risultare 1-3°C sopra il reale. Confrontala con un termometro di riferimento e applica un offset software fisso in firmware, invece di fidarti ciecamente del valore grezzo — lo stesso principio vale per qualunque sensore di temperatura installato vicino a componenti che dissipano calore.
Alimentazione per installazione permanente
Per una stazione esterna alimentata a batteria, alterna letture ogni 30-60 secondi con un deep sleep tra un ciclo e l'altro: un ESP32 in deep sleep consuma pochi microampere contro le decine di milliampere della modalità attiva, trasformando una batteria che dura ore in una che dura mesi.