In questo articolo vediamo in dettaglio come realizzare una serra automatizzata con Arduino (la famosa scheda elettronica con microcontrollore ideata da Massimo Banzi) in grado di compiere le principali azioni che dovrebbe svolgere l’uomo per far crescere e sviluppare una pianta.
Ovviamente, il progetto (di cui puoi trovare l’implementazione del codice nella mia repository GitHub) è stato realizzato solo a scopo didattico. Il focus del progetto è solo sulla parte informatica (quindi l’implementazione del software che gestisce il tutto), piuttosto che sulla parte elettronica.
A cosa serve una serra automatizzata con Arduino?
Negli ultimi anni, infatti, la coltivazione indoor tramite serre smart si è diffusa rapidamente grazie ai numerosi vantaggi apportati:
- possibilità di coltivare qualsiasi pianta in qualsiasi periodo dell’anno;
- massimo controllo sulla crescita e sullo sviluppo delle piante;
- riduzione dei problemi legati alle malattie delle piante come muffe e parassiti;
- possibilità di coltivare cibi biologici in casa.
Il vantaggio principale di tutto ciò è quello di delegare alla tecnologia delle azioni quotidiane e ripetute che altrimenti dovrebbero essere svolte dall’uomo e che richiederebbero, quindi, la presenza costante di esso.
A partire dalla semina fino al raccolto (a seconda della tipologia di pianta scelta), in una serra automatizzata le piante possono crescere e fruttare anche in casa senza l’aiuto dell’uomo.
A livello commerciale esistono già soluzioni avanzate, come LG Column Garden, MioBiO, Infarm. Ma ci sono anche diverse serre automatizzate low cost disponibili all’acquisto su Amazon.
Componenti per realizzare una serra automatizzata
Realizzare una serra automatizzata con Arduino non richiede delle abilità super complesse. Tuttavia, è meglio avere una certa manualità ad utilizzare attrezzi e strumenti frequenti nei lavori manuali, almeno per quanto riguarda la parte dell’assemblaggio fisico. Dovrai utilizzare pinze, cacciaviti, taglierino, pistola a caldo, forbici, spelacavi, ecc…
Per quanto riguarda la struttura della serra, io ho scelto:
- Un box in plexiglass da 100x60x40 cm come struttura globale;
- Un pannello di compensato scuro installato nella parte inferiore per emulare i colori della terra;
- Una cassetta di derivazione fissato nella parete esterna per organizzare al meglio tutti i componenti;
- Un contenitore (da serbatoio) per l’acqua utile per l’irrigazione delle piante;
- Un vaso in cui metterci una pianta di test a propria scelta.
Mentre, questo mostrato di seguito è l’elenco dei componenti elettronici utilizzati:
Arduino Uno
Ovvero il componente principale con microcontrollore ATmega328p della famiglia AVR, abbastanza basilare ma con un numero di pin analogici e digitali (perchè i vari sensori possono inviare segnali digitali oppure analogici) sufficienti per controllare tutti i sensori necessari a gestire tutte le funzionalità della serra. Sarà Arduino ad occuparsi dell’elaborazione dei dati ricevuti dai sensori e al tempo stesso di metterli a disposizione per un’eventuale consultazione dell’uomo.
Per quanto riguarda i collegamenti tra Arduino e le varie componentistiche è stata utilizzata una breadboard corredata di jumper.
Sensore di profondità
Il sensore di profondità viene utilizzato per rilevare il livello dell’acqua nel serbatoio;
Igrometro
Per gestire il processo di irrigazione è stato inserito un igrometro nel vaso, cioè un sensore analogico capace di rilevare l’umidità del terreno e di conseguenza capire se è necessario annaffiare la pianta.
Pompa ad immersione
Per l’irrigazione è stata disposta una pompa ad immersione nel serbatoio, la quale su comando di Arduino si avvia per un periodo di 2 secondi, il tempo necessario per inumidire il terreno e far penetrare l’acqua fino al contatto con il sensore.
Potrebbe succedere che questo processo si ripeta più volte, ma evita il problema di fornire troppa acqua in un solo colpo con l’impossibilità di tornare indietro.
Buzzer e Led
Questi componenti servono per la realizzazione di un allarme visivo e sonoro nel caso in cui si verificassero delle situazioni critiche, come la mancanza di acqua nel serbatoio.
Lampada a led
Una lampada a led da 6W a luce rosso e blu (perchè questo colore? lo scoprirai presto) che, oltre ad essere economica, non emette calore e mercurio (presenti, invece, nelle lampadine ad alta pressione di sodio e ioduri metallici).
Le piante sfruttano la luce del sole e la clorofilla (una sostanza che si trova all’interno delle cellule delle foglie) per avviare il cosiddetto processo di fotosintesi clorofilliana. Sostanzialmente nel corso del processo assorbono anidride carbonica e la trasformano in ossigeno.
Da studi effettuati in diverse occasioni è risultato che le piante utilizzano lunghezze d’onda comprese tra i 400 e 700 nm come fonte di energia per la fotosintesi clorofilliana. Qui un approfondimento sulle varie lunghezze d’onda.
A partire da tutto ciò sono stati effettuati diversi esperimenti utilizzando la tecnologia LED per testare quali colorazioni di luce sono più vantaggiosi per la crescita delle piante. I test eseguiti hanno evidenziato che luci gialle e verdi sono meno importanti per le foglie poiché i colori sono simili e a causa dei riflessi non ricavano 55
energia, mentre sono le lampade a luce rossa e blu quelle che hanno la migliore lunghezza d’onda per il processo di fotosintesi e favoriscono l’accrescimento delle piante sia nella parte vegetativa che nella parte di fioritura.
Oltre ad una crescita più efficace, dall’utilizzo di lampade LED nella coltivazione, sono emersi altri risultati utili riportati di seguito:
- Stelo più robusto;
- Colore più accentuato;
- Riduzione del rischio di filatura;
- Aumento dei cicli di produzione (dovuto alla possibilità di emulare la luce di ogni stagione con giornate nuvolose o solari).
Fotoresistore
Nella progettazione della serra con Arduino è stata considerata l’idea di agevolare lo spostamento della stessa anche in luoghi dove la luminosità esterna varia in continuazione.
Pertanto, è stato predisposto un fotoresistore in una posizione strategica che rileva il livello di luce. Si tratta di un componente simile ad un normale resistore ma il suo valore in ohm varia al variare dell’intensità luminosa che lo colpisce.
Ventola
Si tratta di una ventola alimentata con tensione 220v installata su una delle pareti della serra. La circolazione dell’aria non avviene di continuo, ma solo quando l’umidità interna è eccessiva per la corretta crescita delle piante coltivate. Quindi la scelta di attivare o meno la ventola viene gestita da Arduino in base al valore di umidità che riceve dall’apposito.
Sensore DHT11
Il DHT11 è un sensore digitale composto da una parte resistiva che si occupa di rilevare l’umidità e da un termoresistore che misura la temperatura dell’aria. Questi due componenti sono gestiti da un microcontrollore che è parte integrante del sensore.
Esso ha le seguenti caratteristiche:
- Range umidità 20-90%;
- Accuratezza umidità ±5%;
- Range temperatura 0-50%;
- Accuratezza temperatura ±2%;
- Tensione di alimentazione 3-5.5V;
Non è necessario calibrare il sensore, in quanto è un processo che viene previsto in fase di fabbricazione e i dati di calibrazione vengono memorizzati all’interno di una memoria di sola lettura.
Display
Il display, per far visualizzare all’utente le rilevazioni delle varie metriche. In particolare si tratta di un modulo display da 2 righe per 16 caratteri, quindi con la possibilità di visualizzare 32 caratteri per istante. Questo display sfrutta le caratteristiche del cristallo liquido per controllare l’area di visualizzazione in base alla tensione.
Modulo Relè
È un componente complementare, utile per il corretto funzionamento di altri componenti (lampada a Led, ventola e pompa ad immersione perchè hanno bisogno di un’alimentazione a 220v).Si tratta di un tipo particolare di interruttore che si apre e si chiude tramite un meccanismo magnetico azionato da un impulso elettrico. Infatti, è Arduino a stabilire durante i vari processi, in base all’elaborazione dei dati, quale interruttore attivare tramite un impulso elettrico.
Passi per realizzare una serra automatizzata con Arduino
Dopo aver visto tutte le componentistiche necessarie per realizzare la serra smart, come premesso non vedremo come effettuare tutti i collegamenti fisici tra i componenti, procediamo con tutti i passi che portano alla messa in opera di tutto il progetto.
Per programmare un Arduino occorre utilizzare un semplice linguaggio di programmazione derivato da Wiring e basato su C/C++. In particolare, un programma eseguibile da Arduino (chiamato sketch) deve contenere al suo interno due funzioni principali:
- setup, che viene eseguita una sola volta all’avvio;
- loop, che viene eseguita in modo ciclico dopo il setup.
Inoltre, se vuoi imparare a lavorare con Arduino, questi sono i migliori manuali disponibili in commercio: https://www.espertotech.it/migliori-libri-arduino/.
Visualizzazione dei dati rilevati
Arduino Uno ciclicamente si occuperà di elaborare i dati ricevuti dai sensori e al tempo stesso di metterli a disposizione per un’eventuale consultazione dell’uomo.
Per tale motivo, è stato installato il display LCD. Solitamente display simili hanno bisogno di 16 pin per il collegamento, oltre a quelli destinati all’alimentazione. Ma in questo caso avendone pochi a disposizione su Arduino Uno, peraltro da distribuire anche al resto dei dispositivi, è stata integrata un’interfaccia I2C. Di conseguenza il collegamento fisico è avvenuto tramite le sole linee bidirezionali SDA e SCL, rispettivamente sui pin analogici A4 e A5.
Per la parte software è stata utilizzata la libreria LiquidCrystal_I2C.h, la quale permette un’efficace comunicazione con il modulo display tramite la creazione di un oggetto LiquidCrystal_I2C a partire dall’indirizzo esadecimale (in questo caso 0x27) e dalle dimensioni del display.
Le principali funzionalità messe a disposizione dalla libreria sono:
- begin(uint8_t cols, uint8_t lines, uint8_t dotsize): inizializza l’istanza creata prendendo come parametri colonne e righe della matrice LCD, ovvero la grandezza del punto;
- clear(): rimuove eventuale testo dell’LCD;
- setCursor(uint8_t col, uint8_t row): posiziona il cursore nella colonna e nella riga specificate dai parametri;
- backLight(): abilita la retroilluminazione dello schermo.
- print(String s): stampa sull’LCD la stringa ricevuta come parametro a partire dall’attuale posizione del cursore.
Ecco il codice di implementazione:
#include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2);
Nella funzione setup viene inizializzata la comunicazione tramite l’oggetto creato in precedenza e viene attivata la retroilluminazione.
void setup() { lcd.init(); lcd.backlight(); }
All’interno della funzione loop, invece, vengono effettuate diverse chiamate alla funzione visualizzaDati passando come parametri i risultati ottenuti dai sensori.
void loop() { int ris[] = {0, 0}; gestioneDHT11(ris); //visualizza dati sul display visualizzaDati("Temperatura Aria", ris[0]); visualizzaDati("Umidita' Aria", ris[1]); visualizzaDati("Livello Luce", gestioneLuce()); visualizzaDati("Livello Acqua", gestioneLivelloAcqua()); visualizzaDati("Umidita' Terreno", gestioneIrrigazione()); }
Sul display è possibile visualizzare le seguenti misure:
- Temperatura dell’aria;
- Umidità dell’aria;
- Umidità della terra;
- Livello della luce;
- Livello dell’acqua nel serbatoio.
A questo punto, la funzione visualizzaDati ha il compito di cancellare tutti gli eventuali caratteri presenti sul display, stampare i nuovi valori associati alla relativa grandezza e infine fermarsi per tre secondi in attesa della lettura da parte dell’uomo.
void visualizzaDati(String grandezza, int valore) { lcd.clear(); lcd.setCursor(0, 0); lcd.print(grandezza); lcd.setCursor(0, 1); lcd.print(valore); delay(3000); }
Gestione interruttori
Considerata la presenza di componenti che hanno bisogno di alimentazione a 12v come la lampada Led, la ventola e la pompa ad immersione per l’irrigazione sono stati predisposti più di un modulo relè.
Arduino in base all’elaborazione dei dati, capirà quale interruttore attivare tramite la funzione digitalWrite inviando un segnale alto o basso, che viene tradotto in impulso elettrico.
Nel codice sono state definite tre costanti per associare i pin digitali ad ogni relè. Di conseguenza all’interno della funzione setup i sopracitati pin vengono impostati in modalità output tramite la funzione pinMode, con lo scopo di inviare il segnale verso l’esterno.
Ecco il codice di implementazione:
#define PIN_VENTOLA 8 #define PIN_POMPA 12 #define PIN_LAMPADA 13 void setup(){ pinMode(PIN_VENTOLA, OUTPUT); pinMode(PIN_POMPA, OUTPUT); pinMode(PIN_LAMPADA, OUTPUT); digitalWrite(PIN_VENTOLA, HIGH); digitalWrite(PIN_POMPA, HIGH); digitalWrite(PIN_LAMPADA, HIGH); }
Gestione illuminazione
Per quanto riguarda la gestione dell’illuminazione, la lampadina all’interno della serra si accende solo nel momento in cui esternamente è l’ambiente è buio. Questo processo viene gestito autonomamente da Arduino tramite l’ausilio di un fotoresistore.
Arduino con l’aiuto del fotoresistore recupera i dati relativi al livello luminoso tramite il pin analogico A0. Tra le costanti viene definito anche un valore di soglia utile per le scelte successive.
#define PIN_FOTORESISTORE A0 #define SOGLIA_LUCE 550</div>
int gestioneLuce() { int luce = analogRead(PIN_FOTORESISTORE); if (luce > SOGLIA_LUCE) digitalWrite(PIN_LAMPADA, LOW); else digitalWrite(PIN_LAMPADA, HIGH); return luce; }
Indipendentemente dalle decisioni prese all’interno di gestioneLuce, essa restituisce il valore relativo al livello luminoso che verrà trasferito alla funzione visualizzaDati, la quale come già anticipato si occuperà di farlo visualizzare su display.
Gestione ventilazione
Un altro fattore indispensabile da tenere in considerazione nella realizzazione di una serra è l’umidità. Essa indica la quantità di vapore acqueo che si accumula nell’aria per effetto dell’evaporazione e della traspirazione delle piante.
Solitamente la si misura in percentuale e prende il nome di umidità relativa (RH). È possibile calcolarla con la seguente equazione: RH = (Pv / Ps) * 100
Dove Pv è la densità del vapore acqueo e Ps è la densità del vapore acqueo a saturazione. Il 100% di RH indica che il vapore acqueo si è trasformato in gocce tramite condensa.
Quindi, un eccessivo livello di umidità è la probabile causa della presenza di grosse gocce di acqua depositate sulle foglie delle piante, e ciò crea problemi anche al processo di fotosintesi. Inoltre, come ben risaputo, l’umidità favorisce la diffusione di funghi e muffe.
Tuttavia, è possibile gestire il livello di umidità tramite un’adeguata circolazione dell’aria.
A livello software è stata utilizzata la libreria SimpleDHT.h che permette di lavorare con oggetti di tipo SimpleDHT11. Inoltre, tra le costanti viene definito anche un valore di soglia utile in seguito e da settare con lo specifico valore di umidità adatto al tipo di pianta che si intende coltivare.
#include SimpleDHT11 dht11; #define PIN_DHT11 2 #define SOGLIA_UM_ARIA 50
La funzione gestioneVentilazione ha il compito di estrarre tramite DHT11 i valori di temperatura e umidità. L’umidità rilevata viene confrontata con il valore di soglia e nel caso sia maggiore deve essere azionata la ventola.
void gestioneVentilazione(int val[]){ byte temp = val[0]; byte umid = val[0]; int err = 0; if ((err = dht11.read(PIN_DHT11, &temp, &umid, NULL)) != SimpleDHTErrSuccess) { Serial.print("Read DHT11 failed, err="); Serial.println(err); return; } val[0] = (byte)temp; val[1] = (byte)umid; if(umid > SOGLIA_UM_ARIA) digitalWrite(PIN_VENTOLA, LOW); else digitalWrite(PIN_VENTOLA, HIGH); }
Invece, per quanto riguarda la temperatura non viene effettuato alcun controllo. In ogni caso al di la dei valori rilevati, temperatura e umidità verranno passati alla funzione visualizzaDati che si occuperà di stamparli sul display.
Gestione serbatoio
Per consentire il processo di irrigazione della serra è stato predisposto un piccolo serbatoio dal quale verrà prelevata l’acqua.
Questa è l’unica fase in cui l’uomo deve intervenire per riempire il serbatoio nel caso in cui esso si svuoti, la frequenza di riempimento ovviamente dipende esclusivamente dalle dimensioni del serbatoio adottato.
Nel serbatoio è stato inserito un sensore analogico in grado di rilevare il livello di acqua presente, mentre per segnalare un livello inferiore al valore di soglia è stato realizzato un allarme sonoro e visivo (buzzer e led rosso).
Per quanto riguarda la configurazione, il sensore è collegato ad Arduino tramite il pin A2, mentre i pin 4 e 7 sono associati rispettivamente al buzzer e al led.
Invece, il monitoraggio è gestito dalle funzioni: gestioneSerbatoio e allarme.
#define PIN_SENS_ACQUA A2 #define PIN_LED 7 #define PIN_BUZZER 4 #define SOGLIA_LIV_ACQUA 1000int gestioneSerbatoio(){ int liv_acqua = analogRead(PIN_SENS_ACQUA); if(liv_acqua < SOGLIA_LIV_ACQUA){ allarme(); } return liv_acqua; } void allarme(){ digitalWrite(PIN_LED, HIGH); tone(4,2000,200); delay(300); digitalWrite(PIN_LED, LOW); delay(300); digitalWrite(PIN_LED, HIGH); tone(4,2000,200); delay(300); digitalWrite(PIN_LED, LOW); delay(300); digitalWrite(PIN_LED, HIGH); tone(4,2000,200); delay(300); digitalWrite(PIN_LED, LOW); }
Anche la quantità di acqua è un valore visualizzabile sul display.
Gestione irrigazione
Per gestire il processo di irrigazione è stato inserito l’igrometro nel vaso capace di rilevare l’umidità del terreno e di conseguenza capire se è necessario annaffiare la pianta.
In base al risultato della rilevazione, i valori possono dividersi in tre range:
- Terreno asciutto 0-300
- Terreno umido 300-700
- In acqua 700-950
L’igrometro è stato collegato sul pin A1, inoltre è stata definita una costante per indicare il valore di soglia che potrebbe variare a seconda del serbatoio utilizzato.
#define PIN_IGROMETRO A1 #define SOGLIA_UM_TERRA 400
La funzione gestioneIrrigazione prima si assicura la presenza di acqua nel serbatoio e poi da un confronto con l’umidità del terreno rilevata e il valore di soglia stabilisce se far partire o meno l’irrigazione. Inoltre, la funzione restituisce l’umidità rilevata che viene stampata sul display dall’apposita funzione.
int gestioneIrrigazione(){ int val_igrometro = analogRead(PIN_IGROMETRO); int liv_acqua = analogRead(PIN_SENS_ACQUA); if(liv_acqua >= SOGLIA_LIV_ACQUA){ if(val_igrometro < SOGLIA_UM_TERRA){ digitalWrite(PIN_POMPA, LOW); delay(2000); digitalWrite(PIN_POMPA, HIGH); } } return val_igrometro; }