Costruiamo una Mini Serra con un ESP32-C3 Super Mini, programmandola in ESPHome ed integrandola in Home Assistant.
In questo progetto realizzeremo una mini serra da interno che programmeremo in ESPHome in modo da integrarla in Home Assistant, per poi gestirla in completa autonomia. Per il progetto è stata scelta una ESP32-C3 Super Mini, estremamente compatta e potente, con un numero sufficiente di pin per gestire 4 sensori, un display e 3 relè a cui saranno collegate una ventola, una pompa ad immersione e una striscia led UV. L’obiettivo è poter gestire piccole piante all’interno del proprio appartamento, occupando meno spazio possibile e creare una mini serra adatta alle proprie esigenze.
Componenti
Il nucleo del progetto è la ESP32-C3 Super Mini [LINK], dev-board spesso apprezzata proprio per le ridotte dimensioni. La ESP32-C3 Super Mini è una dev-board di 18 mm x 22,52 mm, molto piccola e compatta. Possiamo trovarla in due versioni: una con SoC ESP32-C3FH4 ed una con SoC ESP32-C3FN4. Entrambi i modelli si basano comunque su un chip a 32bit da 160MHz, con 4MB di memoria flash e 400KB di RAM, mentre la ROM ha disponibili solo 384KB. Troviamo ben 16 pin, di cui ben 13 sono GPIO e di questi 3 sono analogici. La tensione di lavoro di questa dev-board è di 3,3V, tuttavia possiamo alimentare la scheda con i 5V direttamente dal connettore USB Type-C o da pin 5V presente sulla ESP32-C3 Super Mini.

Per monitorare la temperatura e l’umidità all’interno della mini serra. abbiamo scelto un sensore digitale con interfaccia I2C che abbiamo già conosciuto: il sensore SHT45 [LINK]. Esso offre un’accuratezza superiore grazie alla tecnologia CMOSens® proprietaria. Questo sensore è in grado di misurare la temperatura con una precisione tipica di ±0.1 °C e l’umidità relativa con una precisione tipica di ±1.0 % RH, in condizioni standard (25°C e 45% RH). Il range di misurazione della temperatura va da -40 °C a +125 °C, mentre quello dell’umidità relativa si estende dallo 0% al 100%.

Il BH1750 [LINK], sensore scelto per rilevare la luminosità, offre una precisione di circa ±20%, generando misurazioni sufficientemente precise. Possiamo, inoltre, alimentare il sensore con i 3,3V o i 5V, richiedendo corrente fino a circa 0.12 mA e questo lo rende perfetto per sensori IOT sempre accesi o per applicazioni su ESP32 alimentati a batteria o pannello solare. Questa combinazione di precisione, facilità d’uso e basso costo lo rende ideale per progetti DIY basati su microcontrollori e ambienti automatizzati.

Per monitorare il livello di umidità del suolo abbiamo scelto l’igrometro capacitivo [LINK], un sensore che misura il livello di umidità del terreno senza utilizzare contatti elettrici diretti con l’acqua. A differenza dei classici sensori resistivi, che tendono a ossidarsi rapidamente a causa della corrente che attraversa il terreno, il modello capacitivo è molto più resistente nel tempo.

Parlando di piante, oltre al livello di umidità del suolo, dobbiamo parlare anche di annaffiatura, quindi dobbiamo pensare ad un serbatoio che accumuli l’acqua e che deve essere sempre al giusto livello. Per fare ciò, abbiamo scelto il sensore ad ultrasuoni HC-SR04 [LINK]. Il sensore, posto in cima al serbatoio, misurerà il livello di acqua. Nel sensore HC-SR04 troviamo un oscillatore a cristallo, una parte trasmittente (TRIG) che invia un impulso (con una frequenza di circa 40KHz) ed un parte ricevente (ECHO) che capta quest’impulso quando esso viene rifletto da una superficie. Queste due parti sono riconoscibili dalla presenza di una lettera stampata al loro fianco.

I valori rilevati dai sensori (non tutti in realtà), appariranno su un display OLED da 0.96″ SSD1306 [LINK].Questo display ha una risoluzione di 128×64 pixel e rappresenta una scelta ideale per visualizzare testi, icone, piccoli grafici o indicatori di stato in progetti embedded. Il cuore del modulo è proprio il controller SSD1306, un circuito integrato progettato per pilotare direttamente i pixel OLED grazie alla presenza di una memoria interna chiamata GDDRAM, che memorizza lo stato di ciascun pixel. Come il sensore SHT45 e il BH1750, anche esso adopererà l’interfaccia I2C.

Ogni volta che i sensori rilevano un valore che rientra al di sopra o al di sotto di predeterminate soglie, settabili anche via Home Assistant, la ESP32-C3 Super Mini attiverà 3 relè. Si tratta di relè Songle con tensione di lavoro a 5V, controllati da 3 Transistor NPN 2n2222.

Il relè, come pure i transistor, saranno saldati, insieme ad altre componenti, come resistori, led, morsettiere e la ESP32 saranno saldate su un PCB, che abbiamo realizzato con KiCad e di cui potete scaricare il file Gerber [LINK].
Oltre a queste componenti, abbiamo acquistato una pompa a immersione da 5V, una striscia LED a UV sempre a 5V, una ventola da 80mm, una scatola di derivazione che ospiterò il PCB, una scatola porta oggetti trasparente come serra, ed una saliera che adatteremo a serbatoio dell’acqua. Per alimentare l’intero progetto abbiamo adoperato un alimentatore da 5V e 5A, dotato di connettore USB Type-C, che collegheremo ad una porta USB dello stesso tipo che poi va connessa ad una morsettiera sul PCB.
Lista Componenti Amazon:
- ESP32-C3 Super Mini: https://amzn.to/44cVjcZ
- SHT45: https://amzn.to/4o171P4
- BH1750: https://amzn.to/48fyZ50
- HC-SR04: https://amzn.to/4r1i3q9
- Igrometro: https://amzn.to/4nVAcDa
- Display OLED 0.96″ SSD1306: https://amzn.to/3WUEQGz
- Ventola 80mm 5V: https://amzn.to/49g7eKC
- Pompa immersione 5V: https://amzn.to/49g7glI
- Tubo irrigazione: https://amzn.to/3JBHAFS
- Striscia Led UV 5V: https://amzn.to/3K4pEnh
- Alimentatore 5V 5A: https://amzn.to/47WCj3B
- Connettore USB Type-C: https://amzn.to/49UtVnQ
- Relè Songle: https://amzn.to/4nXHUgc
- LED Rossi: https://amzn.to/4phSujb
- Resistori 220 Ohm: https://amzn.to/47Hps6z
- Resistori 470 Ohm: https://amzn.to/4hZlslg
- Diodi IN4007: https://amzn.to/48m2qRZ
- Transistor NPN 2n2222: https://amzn.to/3LKYMsY
- Morsettiere: https://amzn.to/3LL2GlC
- Scatola derivazione: https://amzn.to/47Ul6aX
- Scatola Porta Oggetti 25 litri: https://amzn.to/4oIOetd
Lista Componenti Aliexpress:
- ESP32-C3 Super Mini: https://s.click.aliexpress.com/e/_c3MuvkEp
- SHT45: https://s.click.aliexpress.com/e/_c3h10209
- BH1750: https://s.click.aliexpress.com/e/_c4UpL9YD
- HC-SR04: https://s.click.aliexpress.com/e/_c4EcNR6V
- Igrometro: https://s.click.aliexpress.com/e/_c3bKyFed
- Display OLED 0.96″ SSD1306: https://s.click.aliexpress.com/e/_c3kYO1rP
- Ventola 80mm 5V: https://s.click.aliexpress.com/e/_c4m3c0wZ
- Pompa immersione 5V: https://s.click.aliexpress.com/e/_c4Fk1WOh
- Tubo irrigazione: https://s.click.aliexpress.com/e/_c2xRZjWH
- Striscia Led UV 5V: https://s.click.aliexpress.com/e/_c34kWL69
- Alimentatore 5V 5A: https://s.click.aliexpress.com/e/_c3FZrXjr
- Connettore USB Type-C: https://s.click.aliexpress.com/e/_c4o9Ht1L
- Relè Songle: https://s.click.aliexpress.com/e/_c4SP2BBX
- LED Rossi: https://s.click.aliexpress.com/e/_c4BBTiSt
- Resistori 220 Ohm: https://s.click.aliexpress.com/e/_c4cxz0zX
- Resistori 470 Ohm: https://s.click.aliexpress.com/e/_c42OlPsp
- Diodi IN4007: https://s.click.aliexpress.com/e/_c4oGPOL7
- Transistor NPN 2n2222: https://s.click.aliexpress.com/e/_c3gb8VPf
- Morsettiere: https://s.click.aliexpress.com/e/_c3LKg0KD
- Scatola derivazione: https://s.click.aliexpress.com/e/_c3mIgNZ3
- Scatola Porta Oggetti 25 litri: https://s.click.aliexpress.com/e/_c3SP9B3r
Collegamenti
I collegamenti richiedono una spiegazione più semplice per i sensori e un po’ più complessa lato relè. Partendo dai sensori con interfaccia I2C, adoperiamo i GPIO6 e GPIO7 per SDA e SCL, alimentando il sensore BH1750 a 5V ed il sensore SHT45 a 3,3V. Anche il display OLED verrà connesso ai GPIO6 e GPIO7 e poi alimentato a 5V. Per quanto riguarda l’igrometro, permane l’alimentazione a 5V, ma il pin analogico verrà connesso al GPIO1.
Il sensore ad ultrasuoni richiederà che il pin ECHO venga connesso al GPIO3 e il TRIG al GPIO4.

Lato relè, il segnale digitale partirà dai GPIO10, GPIO20 e GPIO21, arrivando, tramite resistore da 470Ω, alla Base del transistor NPN 2n2222, aprendo il circuito lato GND (connesso all’Emettitore) e permettendo ai relè di chiudere il circuito.

I Relè, alimentati a 5V e posti a monte del Collettore del transistor, possiedono un diodo a protezione e un circuito con LED rosso e resistore da 220Ω che si accende quando il transistor chiude il circuito, fornendo un feedback visivo sullo stato del relè stesso. Poiché poi abbiamo alimentato tutto a 5V e scelto una pompa, una ventola e una striscia LED a 5V, la stessa alimentazione dei relè viene guidata ai COMUNI degli stessi, i quali la gireranno ai terminali del NO (normalmente aperto) quando viene chiuso il circuito, fornendo tensione ai tre dispositivi.

Per semplificare ancora più l’installazione, ogni dispositivo avrà un terminale a due viti, riportante il collegamento del positivo e del negativo.
Codice
Questo è il codice per configurare una ESP32-C3 Super Mini per leggere lo stato dei sensori e inviare tutto a Home Assistant tramite ESPHome. La mini serra sarà accessibile in rete tramite Wi-Fi e potrà essere aggiornata via OTA (Over-The-Air) senza bisogno di connessione fisica. Potete scaricarlo a questo LINK.
All’inizio, il codice definisce il nome del progetto, sia quello tecnico (“mini-serra”) che quello più leggibile per Home Assistant (“Mini Serra).
esphome:
name: mini-serra
friendly_name: Mini Serra
Poi si specifica che il microcontrollore utilizzato è un ESP32-C3 e che il firmware verrà compilato usando il framework Arduino, che è più semplice e supportato rispetto ad altre alternative come ESP-IDF.
esp32:
board: esp32-c3-devkitm-1
framework:
type: arduino
Il codice attiva il logger, che serve a registrare gli eventi e inviare messaggi di debug. Inoltre, viene attivata l’API di ESPHome, che permette a Home Assistant di comunicare con il dispositivo in modo sicuro grazie a una chiave di crittografia.
logger:
api:
encryption:
key: "UeDA3flqEJViavQ5EGwj6w2t+qmp2wT+zriDNaJsQ/c="
Per evitare di dover collegare il dispositivo fisicamente ogni volta che si vuole aggiornare il firmware, viene attivata la modalità OTA (Over-The-Air), con una password di sicurezza.
ota:
- platform: esphome
password: "730efdec906dbe8881be1c9f64c2ff66"
Per collegarsi alla rete, il codice usa le credenziali Wi-Fi salvate nei secrets di ESPHome (file separato non visibile nel codice). Se la connessione fallisce, il dispositivo crea un hotspot Wi-Fi di emergenza (“Super-Mini-C3 Fallback Hotspot”) con una password predefinita, in modo che sia possibile riconfigurarlo. Inoltre, è presente la funzione captive portal, che permette di riconfigurare il Wi-Fi direttamente da un browser in caso di problemi di connessione.
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Super-Mini-C3 Fallback Hotspot"
password: "8gXa1zDnxgVW"
captive_portal:
Alla ESP32 abbiamo connesso in parallelo 2 sensori e un display con interfaccia I2C (SHT45, BH17050 e Display OLED SSD1306), pertanto abbiamo bisogno di dichiarare i pin SDA e SCL.
i2c:
sda: 6
scl: 7
scan: true
Andiamo a dichiarare i nostri sensori con interfaccia I2C, settando per ognuno un nome, il corretto indirizzo e update (2 secondi). Non spediamo troppe parole su questi sensori, giacché li abbiamo visti singolarmente. Ricordiamo che ci serviranno per rilevare temperatura, umidità e luminosità.
sensor:
# SHT45 (Temperatura / Umidità aria)
- platform: sht4x
temperature:
name: "Temperatura"
id: temp_aria
humidity:
name: "Umidità"
id: umidita_aria
address: 0x44
update_interval: 2s
# BH1750 (Luminosità)
- platform: bh1750
name: "Luminosità Terrario"
id: luminosita
address: 0x23
Dichiariamo anche il sensore ad ultrasuoni HC-SR04 per misurare la distanza dal sensore al pelo dell’acqua nel serbatoio, per poi misurarne l’altezza. Il pin TRIG va connesso al GPIO4, mentre l’ECHO al GPIO3. Forniamo anche un id al sensore HC-SR04, utile per poi convertire i valori di distanza in numeri percentuali per calcolare il livello di acqua nel serbatoio. Difatti, dopo aver misurato i livelli minimi a massimi nel serbatoio, convertiamo questi valori in percentuale, considerando ogni valore uguale o superiore a 10cm come percentuale di acqua pari a 0%, mentre ogni valore uguale o inferiore a 5,5cm come livello al 100%.
- platform: ultrasonic
trigger_pin: 4
echo_pin: 3
name: "Livello Acqua Serbatoio"
id: livello_acqua_grezzo
update_interval: 2s
timeout: 4m
unit_of_measurement: "cm"
accuracy_decimals: 1
filters:
- lambda: return x * 100;
# Percentuale livello acqua
- platform: template
name: "Percentuale Livello Acqua"
id: livello_acqua_pct
unit_of_measurement: "%"
accuracy_decimals: 0
update_interval: 2s
lambda: |-
float lvl = id(livello_acqua_grezzo).state;
const float full_lvl = 5.5; // 100%
const float empty_lvl = 10.0; // 0%
if (lvl <= full_lvl) return 100; if (lvl >= empty_lvl) return 0;
float pct = (empty_lvl - lvl) * 100.0 / (empty_lvl - full_lvl);
return pct;
Nei sensori dichiariamo l’igrometro analogico connesso al GPIO1, creando anche il valore espresso in percentuale per una lettura più semplice.
- platform: adc
pin: 1
attenuation: 12db
id: adc_raw
name: "Igrometro - Tensione grezza"
update_interval: 2s
accuracy_decimals: 3
unit_of_measurement: "V"
- platform: template
name: "Umidità Suolo"
id: umidita_suolo
unit_of_measurement: "%"
accuracy_decimals: 1
update_interval: 2s
lambda: |-
float raw_v = id(adc_raw).state;
float wet_v = id(wet_value).state;
float dry_v = id(dry_value).state;
// fallback di sicurezza
if (isnan(wet_v)) wet_v = 0.45;
if (isnan(dry_v)) dry_v = 2.40;
if (fabs(dry_v - wet_v) < 0.0001) dry_v = wet_v + 0.0001;
float norm = (raw_v - wet_v) / (dry_v - wet_v);
if (norm < 0.0) norm = 0.0; if (norm > 1.0) norm = 1.0;
float humidity = (1.0 - norm) * 100.0;
return humidity;
Passiamo ai relè, connessi rispettivamente ai GPIO10, GPIO20 e GPIO21. Oltre ad assegnare un nome, impostiamo il restore_mode su RESTORE_DEFAULT_OFF, in modo tale che al riavvio della mini serra tornino sempre in OFF.
switch:
- platform: gpio
pin: 10
name: "Ventola Terrario"
id: ventola
icon: "mdi:fan"
restore_mode: RESTORE_DEFAULT_OFF
- platform: gpio
pin: 20
name: "Pompa Acqua"
id: pompa
icon: "mdi:water-pump"
restore_mode: RESTORE_DEFAULT_OFF
- platform: gpio
pin: 21
name: "Luce UV"
id: luce_uv
icon: "mdi:lightbulb"
restore_mode: RESTORE_DEFAULT_OFF
Il passaggio successivo è creare delle box per la calibrazione dell’igrometro e impostare anche delle soglie di tolleranza per le automazioni dei relè. Infatti, impostiamo come valori iniziale per l’igrometro allo stato bagnato 0.45, stato asciutto 2.40, per la ventola la soglia iniziale è 35, per la luminosità 20, per l’umidità del suolo 40.
number:
- platform: template
name: "Igrometro - Bagnato (V)"
id: wet_value
optimistic: true
min_value: 0.0
max_value: 3.3
step: 0.01
initial_value: 0.45
restore_value: true
mode: box
- platform: template
name: "Igrometro - Asciutto (V)"
id: dry_value
optimistic: true
min_value: 0.0
max_value: 3.3
step: 0.01
initial_value: 2.40
restore_value: true
mode: box
# --- Soglie di controllo ---
- platform: template
name: "Soglia Temperatura Ventola"
id: soglia_temp_ventola
optimistic: true
min_value: 20
max_value: 45
step: 0.5
unit_of_measurement: "°C"
initial_value: 35
- platform: template
name: "Soglia Luminosità UV"
id: soglia_lux_uv
optimistic: true
min_value: 0
max_value: 25000
step: 10
unit_of_measurement: "lx"
initial_value: 20
- platform: template
name: "Soglia Umidità Suolo"
id: soglia_umidita_suolo
optimistic: true
min_value: 0
max_value: 100
step: 1
unit_of_measurement: "%"
initial_value: 40
Impostate tali soglie iniziale, personalizzabili poi in Home Assistant, creiamo le automazioni. La prima automazioni gestisce l’irrigazione automatica, attivando la pompa posta nel serbatoio. Quando il valore rilevato dall’igrometro si trova al di sotto del 40%, viene attivato il relè controllato dal GPIO20 per attivare la pompa. La seconda serve ad attivare la ventola, quando la temperatura raggiunge o supera i 35°C, attivando il relè gestito dal GPIO10. L’ultima automazione attiverà l’ultimo relè gestito dal GPIO21, quando la luminosità si trova al di sotto dei 20lx, accendendo la striscia led UV.
interval:
- interval: 1s
then:
# --- Irrigazione automatica ---
- if:
condition:
lambda: 'return id(umidita_suolo).state < id(soglia_umidita_suolo).state;'
then:
- if: condition: lambda: 'return !id(pompa).state;' then: - logger.log: "Terreno secco - avvio irrigazione" - switch.turn_on: pompa else: - if: condition: lambda: 'return id(pompa).state;' then: - logger.log: "Terreno sufficientemente umido - spengo pompa" - switch.turn_off: pompa
# Ventola (temperatura)
- if: condition: lambda: 'return id(temp_aria).state > id(soglia_temp_ventola).state;'
then:
- logger.log: "Temperatura alta - accendo ventola"
- switch.turn_on: ventola
else:
- if:
condition:
lambda: 'return id(temp_aria).state < (id(soglia_temp_ventola).state - 2.0);'
then:
- logger.log: "Temperatura bassa - spengo ventola"
- switch.turn_off: ventola
# --- Luce UV (luminosità) ---
- if:
condition:
lambda: 'return id(luminosita).state < id(soglia_lux_uv).state - 5;' then: - logger.log: "Luminosità bassa - accendo luce UV" - switch.turn_on: luce_uv else: - if: condition: lambda: 'return id(luminosita).state > id(soglia_lux_uv).state + 5;'
then:
- logger.log: "Luminosità sufficiente - spengo luce UV"
- switch.turn_off: luce_uv
Occupiamoci ora del display, premettendo che abbiamo adoperato 3 font differenti: Arial per il testo, WeatherSymbols e Fans per le icone di ventola, pompa e UV.
font:
- file: "arial.ttf"
id: font1
size: 12
- file: "WeatherSymbols.ttf"
id: font_weather
size: 21
- file: "Fans.ttf"
id: font_fan
size: 19
Configuriamo ora il display, stampando nella parte superiore le icone, quando i relè sono attivi, mentre se tutti e tre saranno spenti, apparirà la scritta “Tutto OFF”. Nelle tre righe successive verranno mostrati i valori rilevati di temperatura, umidità e umidità del suolo.
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
address: 0x3C
rotation: 0
lambda: |-
int x = 0;
int y_icons = 0;
if (id(ventola).state) {
it.printf(x, y_icons, id(font_fan), "B");
x += 25;
}
if (id(pompa).state) {
it.printf(x, y_icons, id(font_weather), "B");
x += 25;
}
if (id(luce_uv).state) {
it.printf(x, y_icons, id(font_weather), "N");
x += 25;
}
if (!id(ventola).state && !id(pompa).state && !id(luce_uv).state) {
it.printf(0, y_icons, id(font1), "Tutto OFF");
}
int y_values = 20;
it.printf(0, y_values, id(font1), "T: %.1f°C", id(temp_aria).state);
it.printf(0, y_values + 15, id(font1), "U: %.1f%%", id(umidita_aria).state);
it.printf(0, y_values + 30, id(font1), "Suolo: %.1f%%", id(umidita_suolo).state);
Salvate e verificate con Validate se il codice è stato scritto correttamente.

Collegate la ESP32 al computer tramite cavo USB, e cliccate su Install.

Conclusa l’installazione, integriamo il device su Home Assistant. Dovrebbe essere arrivata una notifica sulla plancia. In ogni caso, per integrarlo andate su Impostazioni -> Dispositivi e servizi e apparirà il dispositivo Mini Serra da integrare.
Conclusa l’installazione, integriamo il device su Home Assistant. Possiamo così monitorare le rilevazioni della nostra mini serra, creando automazioni ad essa collegate, come ad esempio l’allerta tramite notifica del livello di acqua basso. Possiamo anche modificare le soglie di ventola, led UV e pompa, nonché intervenire manualmente su ogni singolo relè.




















