Come creare un sistema di irrigazione automatica con ESP8266 controllato da Arduino Cloud

Introduzione

In questo articolo presenteremo un sistema di irrigazione automatica con ESP8266 controllato tramite Arduino Cloud.

Nell’era dell’Internet of Things (IoT), la possibilità di raccogliere, monitorare e controllare dati ambientali in tempo reale ha aperto nuove porte verso l’ottimizzazione delle risorse e la creazione di soluzioni innovative. In questo contesto, l’utilizzo del modulo ESP8266 come cuore di un sistema di irrigazione automatica controllato con Arduino Cloud, associato a vari sensori, ci permette di realizzare un circuito intelligente capace di misurare, raccogliere e reagire alle variazioni di temperatura, umidità, luminosità, pressione atmosferica e umidità del suolo. Inoltre, la possibilità di connessione al cloud tramite Arduino Cloud apre le porte alla gestione remota e all’automazione di tali parametri, rappresentando un passo avanti nell’efficienza e nella comodità.

Il cuore di questo sistema è l’ESP8266, una piattaforma IoT versatile e potente che agisce da intermediario tra il mondo fisico e il cloud. Questo dispositivo è connesso a un insieme di sensori altamente sensibili che catturano informazioni cruciali sull’ambiente circostante. Il sensore DHT22 registra la temperatura e l’umidità dell’aria, fornendo dati essenziali per il monitoraggio delle condizioni climatiche. Il BH1750, un sensore di luminosità avanzato, misura l’intensità della luce ambientale, mentre il BMP180 offre informazioni precise sulla pressione atmosferica.

Uno degli aspetti più interessanti di questo sistema è la sua capacità di controllare l’ambiente in maniera attiva. Con l’aggiunta di un sensore di umidità del suolo, il sistema è in grado di monitorare il livello di umidità nel terreno, fornendo un’indicazione cruciale per l’irrigazione delle piante. La vera innovazione arriva con l’uso di una elettrovalvola bistabile, controllata da una coppia di relè, che può aprire o chiudere il flusso d’acqua. Questo elemento è un passo avanti nell’ottimizzazione delle risorse idriche, consentendo un’irrigazione precisa e mirata.

Arduino Cloud: un passo avanti nell’automazione e nel monitoraggio remoto

Il collegamento di questo sistema al cloud tramite Arduino Cloud rappresenta un punto di svolta nella gestione dei dati e del controllo. Grazie a questa connessione, è possibile monitorare in tempo reale i dati raccolti dai sensori da qualsiasi parte del mondo. Inoltre, il sistema offre un’interfaccia utente intuitiva sotto forma di una Dashboard, in cui vengono visualizzati i dati ambientali e lo stato dell’irrigazione. Ma l’innovazione non si ferma qui: l’utente può commutare tra modalità manuale e automatica. Nella modalità manuale, l’utente ha il controllo completo sull’apertura e la chiusura dell’elettrovalvola attraverso l’interfaccia. In modalità automatica, il sistema risponde agli schemi di irrigazione definiti dall’utente tramite lo scheduler della Dashboard di Arduino Cloud, ottimizzando l’uso dell’acqua in base alle esigenze delle piante e alle condizioni ambientali.

In questo articolo, esploreremo nel dettaglio la progettazione, l’assemblaggio e la configurazione di questo sistema di monitoraggio e controllo ambientale. Dalla selezione dei componenti al codice di programmazione, passando per l’integrazione con Arduino Cloud, offriremo una guida completa per creare un sistema intelligente che unisce tecnologia e sostenibilità, aprendo nuove prospettive nell’ottimizzazione dell’ambiente circostante.

Se ti interessa vedere come funziona lo scheduler di Arduino Cloud puoi andare a dare un’occhiata all’articolo Come usare lo scheduler di Arduino Cloud con una ESP8266 su PlatformIO.

Ma cos’è Arduino Cloud?

Arduino Cloud è un servizio online sviluppato da Arduino, l’azienda nota per la sua piattaforma di prototipazione open-source. Lo scopo principale di Arduino Cloud è quello di fornire un modo semplice ed efficace per connettere e controllare dispositivi basati su Arduino da remoto attraverso Internet. È parte dell’ecosistema Arduino IoT (Internet of Things) che mira a consentire agli sviluppatori di creare progetti IoT in maniera facile ed estremamente intuitiva utilizzando le risorse di Arduino. Inoltre è possibile utilizzare anche altri tipi di dispositivi (non strettamente Arduino) come, per esempio, le board ESP8266 e ESP32.

Ecco alcune sue caratteristiche:

  • Connessione Remota: Arduino Cloud offre un modo per connettere vari dispositivi a Internet in modo che possano essere monitorati e controllati da qualsiasi luogo tramite una Dashboard online o un’applicazione mobile;
  • Controllo e Monitoraggio: una volta che i dispositivi sono connessi, puoi utilizzare l’interfaccia online per monitorare vari sensori e variabili sul tuo dispositivo e controllare i suoi attuatori. Ad esempio, potresti leggere i dati da un sensore di temperatura e umidità e attivare un motore o un relè collegato al tuo dispositivo;
  • Automazione: Arduino Cloud ti consente di creare regole e scenari di automazione in modo che il tuo dispositivo possa rispondere a determinate condizioni o attivare azioni specifiche. Questo è utile per creare sistemi di automazione domestica o progetti IoT avanzati;
  • Sicurezza: Arduino Cloud generalmente adotta misure di sicurezza per garantire che le connessioni tra i dispositivi e il servizio siano protette. Ciò può includere crittografia dei dati e autenticazione sicura;
  • Supporto per diversi dispositivi: Arduino Cloud è compatibile con una varietà di dispositivi e schede.

Breve descrizione delle funzionalità implementate dal sistema di irrigazione automatica con ESP8266

Iniziamo a descrivere le varie funzionalità che verranno implementate in questo progetto.
Il dispositivo è in grado di comandare un’elettrovalvola in modo da chiuderla o aprirla per interrompere o meno il flusso d’acqua di un tubo da giardino. È in grado di rilevare la temperatura e l’umidità dell’aria attraverso un apposito sensore (DHT22), la pressione atmosferica e l’intensità di luce tramite i sensori BMP180 e BH1750. Può inoltre misurare la quantità di umidità nel terreno in cui si trova la pianta. È anche in grado di connettersi a Internet tramite una connessione WiFi sul nostro modem di casa. La connessione Internet viene utilizzata per monitorare e controllare il dispositivo tramite una Dashboard di Arduino Cloud appositamente creata. Attraverso questa interfaccia possiamo visualizzare in maniera grafica da remoto la temperatura e l’umidità dell’aria, la pressione atmosferica, l’intensità di illuminazione, l’umidità del suolo, lo stato dell’elettrovalvola (se è aperta o chiusa). Possiamo anche inviare dei comandi: possiamo farlo funzionare manualmente (accendendo o spegnendo l’elettrovalvola dando un comando su uno switch della Dashboard) o automaticamente (impostando, sempre da Dashboard, gli orari di accensione e spegnimento dell’elettrovalvola).

Ovviamente, ci sono molte possibilità. L’utente può sviluppare nuove funzionalità o modificare quelle esistenti. Ad esempio, potrebbe decidere di attivare l’irrigazione in automatico se l’umidità del terreno è inferiore ad un certo valore e così via.

NOTA BENE: nonostante qusto progetto sia abbastanza semplice, richiede un numero di variabili che eccede il massimo numero di variabili gestibili con un piano gratuito di Arduino Cloud. Quindi, a meno di ridurre il numero di variabili (e quindi di sensori), è necessario sottoscrivere un piano a pagamento (che, peraltro, è abbastanza economico e vale la spesa sostenuta).

Abbiamo già descritto su questo stesso blog un progetto riguardante un irrigatore automatico controllato tramite Telegram. Se sei interessato dai un’occhiata all’articolo Come realizzare un irrigatore automatico comandato da Telegram con il NodeMCU ESP8266.

Come negli articoli già pubblicati su questo blog, useremo come IDE l’ottimo PlatformIO.

Di che componenti abbiamo bisogno?

La lista dei componenti non è particolarmente lunga:

Un esempio di modulo con doppio relè optoisolato usato in questo progetto
Un esempio di modulo con doppio relè optoisolato usato in questo progetto

Un esempio di elettrovalvola bistabile a 9V usata in questo progetto
Un esempio di elettrovalvola bistabile a 9V usata in questo progetto

Un connettore per batteria da 9V
Un connettore per batteria da 9V

La batteria da 9V ci serve per alimentare l’elettrovalvola.

Vediamo brevemente come funziona un’elettrovalvola

Principalmente esistono due tipi di elettrovalvole, una monostabile e una bistabile.
L’elettrovalvola monostabile è alimentata con tensione alternata mentre la bistabile con tensione continua.
In questo progetto utilizzeremo un’elettrovalvola bistabile. L’elettrovalvola bistabile ha due stati stabili, uno per la valvola chiusa e uno per la valvola aperta. Alimentando il solenoide, la valvola si apre e rimane aperta anche togliendo l’alimentazione.
Per chiuderla dobbiamo alimentare il solenoide invertendo la polarità, anche in questo caso togliendo alimentazione la valvola rimane chiusa. Il vantaggio principale è un consumo elettrico minimo, dato che per aprire e chiudere la valvola è necessario alimentarla solo per pochi millisecondi, questo permette di alimentarla utilizzando una batteria.
L’elettrovalvola necessita di un doppio modulo relè optoisolato. I due relè sono opportunamente pilotati da due uscite digitali del NodeMCU ESP8266 per applicare una tensione diretta o inversa all’elettrovalvola, a seconda che si voglia aprirla o chiuderla.

Realizzazione del progetto

Lo schema elettrico

Prima di realizzare il circuito vero e proprio diamo un’occhiata ai pinout della board e dei sensori:

Il pinout del NodeMCU ESP8266
Il pinout del NodeMCU ESP8266

In questo progetto sono utilizzati vari GPIO, alcuni per leggere i sensori altri per comandare i relè.

Useremo il GPIO 14 per leggere il sensore DHT22 (temperatura e umidità ambientali), i GPIO 4 e 5 per leggere i sensori BH1750 e BMP180 (luminosità ambientale e pressione atmosferica), l’ADC0 per leggere il valore di umidità del suolo e i GPIO 12 e 13 per comandare i relè.

Vediamo quindi i pinout dei sensori DHT22, BH1750 e BMP180:

Pinout del DHT22
Pinout del DHT22

Pinout del BH1750
Pinout del BH1750

Pinout del BMP180
Pinout del BMP180

Mentre il DHT22 ha un GPIO dedicato per la sua lettura (non utilizzato da altri sensori), i sensori BMP180 e BH1750 sono collegati entrambi ai GPIO 4 (SDA) e 5 (SCL) della ESP8266. Questi pin fanno parte di un bus di comunicazione a due fili che si chiama I2C. Questo bus prevede la presenza di un dispositivo master (nel nostro caso la ESP8266) che gestisce la comunicazione e uno o più dispositivi slave (che da noi sono i due sensori). I dispositivi slave hanno tutti un proprio indirizzo esadecimale in modo da far capire al master da quale dispositivo proviene un determinato messaggio o per fare in modo che il master mandi un messaggio allo slave giusto. In questo modo si evitano conflitti fra i messaggi, dato che viaggiano sullo stesso bus.

Il sensore BMP180 ha indirizzo 0xEF in lettura e 0xEE in scrittura mentre l’indirizzo del sensore BH1750 può essere settato tramite il pin ADDR. In particolare, avremo che:

  • l’indirizzo è 0x23 se la tensione al pin ADDR è inferiore a 0.7 Vcc
  • l’indirizzo è 0x5C se la tensione al pin ADDR è maggiore di 0.7V

Fortunatamente gli indirizzi dei due dispositivi non coincidono quindi non avremo collisioni dei messaggi.

In generale, nel caso due o più dispositivi abbiano lo stesso indirizzo (non modificabile) non sarà possibile collegarli allo stesso bus I2C.

A questo punto vediamo lo schema elettrico completo realizzato, come al solito, con Fritzing:

Schema elettrico completo del sistema di irrigazione automatica con ESP8266
Schema elettrico completo del sistema di irrigazione automatica con ESP8266

Come puoi vedere lo schema non è particolarmente complesso. Piuttosto devi fare attenzione alle alimentazioni dato che sono separate tra sezione di alimentazione dei sensori e sezione di alimentazione del modulo relè. Come puoi vedere, l’alimentazione per i tre sensori è presa dall’uscita 3.3V del NodeMCU (pin 3V3). E’ necessario alimentare i sensori con 3.3V in modo che anche la loro uscita sia 3.3V in quanto i pin digitali del NodeMCU non accettano tensioni superiori a 3.3V.

Invece l’alimentazione del modulo relè è presa dal pin Vin del NodeMCU che eroga i 5V necessari a pilotare le bobine dei relè.

ATTENZIONE: nel NodeMCU ESP8266 la tensione massima tollerata dagli ingressi digitali è pari a 3.3V. Qualsiasi tensione superiore lo danneggerebbe irreparabilmente!!

Attualmente il modulo doppio relè non è presente in Fritzing ma, se vuoi usarlo nei tuoi progetti, puoi scaricarlo da qui.

Analizziamo più in dettaglio il collegamento del modulo relè.

I due pin Vin e GND del NodeMCU ESP8266 vengono utilizzati per alimentare il modulo a doppio relè, collegando il pin Vin (lato NodeMCU) al pin VCC (lato modulo a doppio relè) e i due pin GND (massa).

Altre due connessioni sono utilizzate per controllare il modulo relè e sono il filo arancione e il filo marrone che collegano le due uscite digitali GPIO 12 e GPIO 13 del NodeMCU agli ingressi IN1 e IN2 del modulo relè.

Noterai che sul modulo relè è presente un ponticello (disegnato in azzurro sul connettore sinistro) che collega i morsetti JD-VCC e VCC. Questo ponticello viene utilizzato per alimentare il modulo relè attraverso i terminali VCC e GND sul connettore destro. Senza questo ponticello, siamo costretti ad alimentare il modulo con un alimentatore esterno.

Infine, collegate ai contatti del relè, abbiamo la batteria da 9V e l’elettrovalvola in modo da poterla alimentare con polarità opposta a seconda che la vogliamo aprire o chiudere.

Analizziamo ora il misuratore di umidità del terreno

Abbiamo già accennato alla presenza di una funzionalità che ci permette di verificare se il terreno in cui si trova la nostra pianta è abbastanza umido o secco e necessita di essere annaffiato.

Ma come si misura il valore di questa umidità? Quale parametro fisico possiamo usare? Il parametro che utilizziamo è la conducibilità elettrica del terreno. In realtà ciò che realmente misuriamo è la sua resistività elettrica, che è l’inverso della conduttività.

Il suolo, quando è bagnato, è un buon conduttore di elettricità. Ciò significa che la sua resistenza elettrica è bassa. Quando si asciuga, però, diventa un cattivo conduttore di elettricità, quindi la sua resistenza elettrica aumenta.

Per misurarne la resistenza, lo inseriamo in un circuito molto semplice chiamato partitore di tensione.

Schema del partitore di tensione
Schema del partitore di tensione

Come puoi vedere, il partitore di tensione è costituito da due resistori: R1 e R2. Nel nostro caso, R1 rappresenta la resistenza elettrica del terreno, R2 è una normale resistenza da 10kΩ. Una tensione, che chiamiamo Vin, viene applicata al partitore. All’uscita del partitore abbiamo una tensione che chiamiamo Vout. La tensione Vout sarà una frazione della Vin (da cui il nome partitore di tensione) data dalla formula:

Formula del partitore di tensione
Formula del partitore di tensione

La tensione Vin è la nostra tensione di riferimento e deve essere costante. La prendiamo dal pin 3V3 del NodeMCU che fornisce una tensione costante a 3.3V e che abbiamo già utilizzato per alimentare gli altri sensori.

ATTENZIONE: nel NodeMCU ESP8266 la tensione massima tollerata dall’ingresso analogico è pari a 3.3V. Qualsiasi tensione superiore lo danneggerebbe irreparabilmente!!

La resistenza R2 è fissa (la impostiamo a 10kΩ) mentre la resistenza R1 (quella del terreno) varia in base all’umidità. Pertanto la tensione Vout varierà in funzione della resistenza R1 (e quindi dell’umidità del terreno).

Non ci resta che misurare questa tensione Vout con l’ingresso analogico del NodeMCU.

I due fili rosso e blu vanno collegati a due bastoncini metallici che vanno poi conficcati nel terreno vicino alla pianta, distanziandoli di qualche centimetro l’uno dall’altro.

Come puoi vedere, la tensione Vout viene misurata collegando il filo blu tra il punto centrale del partitore di tensione e il pin A0 del NodeMCU.

Creiamo gli oggetti e la dashboard sul cloud

Per prima cosa, se non lo hai già fatto, devi crearti un account su Arduino Cloud.

NOTA BENE: nonostante qusto progetto sia abbastanza semplice, richiede un numero di variabili che eccede il massimo numero di variabili gestibili con un piano gratuito di Arduino Cloud. Quindi, a meno di ridurre il numero di variabili (e quindi di sensori), è necessario sottoscrivere un piano a pagamento (che, peraltro, è abbastanza economico e vale la spesa sostenuta).

Una volta che hai fatto il login ti troverai di fronte a questa pagina:

Pagina iniziale di Arduino Cloud
Pagina iniziale di Arduino Cloud

Clicca sul pulsante GET STARTED e verrai mandato alla pagina:

Seconda pagina di Arduino Cloud
Seconda pagina di Arduino Cloud

Clicca sul pulsante IoT Cloud. Si aprirà la pagina Things.

A questo punto procederai a:

  • creare il device che mapperà la board
  • creare l’oggetto (thing) con le variabili associate al device creato al passo precedente
  • creare la dashboard da associare alle variabili

Vedremo la procedura appena elencata con questo video:

NOTA BENE: è importante notare che nel video, al minuto 4:20, ho scaricato un pdf che contiene i parametri di collegamento al device. Essi sono chiamati Device ID e Secret Key e ci serviranno in seguito. Quindi scarica anche tu questo pdf e conservalo da qualche parte.

Ovviamente i parametri Device ID e Secret Key sono propri di ciascun device, quindi cambiano al variare del device.

Una volta completata la procedura, vai sull’ oggetto test_thing e clicca sul tab Sketch:

Schermata delle proprietà dell'oggetto
Schermata delle proprietà dell’oggetto

Premi poi il bottone Open full editor:

Schermata dello sketch
Schermata dello sketch

Si aprirà una finestra come questa:

Schermata del codice completo
Schermata del codice completo

Ciò che ci interessa (e che useremo successivamente) sono il file principale .ino (quello che in foto si chiama test_thing_aug15b.ino e che da te avrà un nome diverso) e il file thingProperties.h. Questi due file li useremo in seguito nel nostro progetto PlatformIO.

Lo sketch

Creiamo il progetto PlatformIO

Abbiamo già visto la procedura di creazione di un progetto PlatformIO nell’articolo Come creare un progetto per NodeMCU ESP8266 con PlatformIO.

Delle librerie indicate installa, seguendo la procedura, la libreria DHT sensor library for ESPx by Bernd Giesecke (che viene usata per leggere i dati trasmessi dal sensore di temperatura e umidità DHT22) e lascia perdere le altre due (WiFiManager e UniversalTelegramBot).

Installa ora la libreria Adafruit BMP085 Library by Adafruit:

Installa la libreria BMP085 sul progetto PlatformIO
Installa la libreria BMP085 sul progetto PlatformIO

Installa la libreria BH1750 by claws:

Installa la libreria BH1750 sul progetto PlatformIO
Installa la libreria BH1750 sul progetto PlatformIO

Installa poi, sempre seguendo la solita procedura, la libreria Arduino_ConnectionHandler:

Installazione della libreria Arduino_ConnectionHandler
Installazione della libreria Arduino_ConnectionHandler

e la libreria ArduinoIoTCloud:

Installazione della libreria ArduinoIoTCloud
Installazione della libreria ArduinoIoTCloud

Ora modifica il file platformio.ini per aggiungere queste due righe:

monitor_speed = 115200
upload_speed = 921600

in modo che abbia un aspetto del genere:

[env:nodemcuv2]
platform = espressif8266
board = nodemcuv2
framework = arduino
monitor_speed = 115200
upload_speed = 921600
lib_deps = 
	arduino-libraries/Arduino_ConnectionHandler@^0.7.6
	arduino-libraries/ArduinoIoTCloud@^1.12.0
	beegee-tokyo/DHT sensor library for ESPx@^1.19
	adafruit/Adafruit BMP085 Library@^1.2.2
	claws/BH1750@^1.3.0

A questo punto torna alla piattaforma cloud, copia il contenuto del file .ino:

Il file .ino del progetto
Il file .ino del progetto

e incollalo nel file main.cpp del progetto PlatformIO, in modo da sostituirne completamente il contenuto.

Ora crea nella cartella include un file che chiamerai thingProperties.h, vai nella piattaforma cloud, copia il contenuto del tab thingProperties.h:

Il file thingProperties.h
Il file thingProperties.h

e incollalo nel file thingProperties.h appena creato dentro il progetto Platformio.

A questo punto dovrai editare questo file in modo da collegarlo al cloud:

const char DEVICE_LOGIN_NAME[]  = "XXXXXXXXXXXXXXXXXXXXXXXXXX";

const char SSID[]               = SECRET_SSID;    // Network SSID (name)
const char PASS[]               = SECRET_OPTIONAL_PASS;    // Network password (use for WPA, or use as key for WEP)
const char DEVICE_KEY[]  = SECRET_DEVICE_KEY;    // Secret device password

Come vedi, in questa sezione ci sono alcuni parametri da impostare.

Il primo parametro (DEVICE_LOGIN_NAME) è stato aggiunto automaticamente e lo trovi nel pdf che hai scaricato quando hai creato l’oggetto (trovi il riferimento nel video precedente). Nel pdf il parametro è chiamato Device ID.

I parametri SECRET_SSID e SECRET_OPTIONAL_PASS sono, rispettivamente, il nome e la password della tua rete WiFi. Quindi, al posto di SECRET_SSID metterai il nome della tua rete tra doppi apici (“) e al posto di SECRET_OPTIONAL_PASS metterai la password della tua rete (sempre fra doppi apici).

L’ultimo parametro, SECRET_DEVICE_KEY, lo trovi sempre nel pdf che hai scaricato dalla piattaforma col nome Secret Key.

Quindi la sezione in oggetto dovrebbe avere un aspetto del genere:

const char DEVICE_LOGIN_NAME[]  = "5b20cc94-d4fe-4d09-a4fa-7bb75e353aa7";
const char SSID[]               = "my_wifi_network_ssid";    // Network SSID (name)
const char PASS[]               = "my_wifi_network_password";    // Network password (use for WPA, or use as key for WEP)
const char DEVICE_KEY[]  = "P7WPMDDR2G9SZW2LKBAY";    // Secret device password

Come puoi vedere, ho messo nel campo DEVICE_LOGIN_NAME il valore preso dal pdf alla voce Device ID (in questo caso 5b20cc94-d4fe-4d09-a4fa-7bb75e353aa7), nel campo SSID l’SSID della mia rete WiFi (in questo caso my_wifi_network_ssid), nel campo PASS la password della mia rete WiFi (in questo caso my_wifi_network_password) e nel campo DEVICE_KEY il valore preso dal pdf alla voce Secret Key (in questo caso P7WPMDDR2G9SZW2LKBAY).

È arrivato il momento di modificare il file main.cpp.

Inizialmente includerai la libreria Arduino e il file thingProperties.h in questo modo :

#include <Arduino.h>
#include <thingProperties.h>

Poi dovrai includere le librerie necessarie:

#include <Wire.h>
#include "DHTesp.h"
#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <BH1750.h>

Definisci le variabili necessarie per l’acquisizione del valore dell’umidità del suolo:

#define ANALOGPIN0 A0  // ESP8266 Analog Pin ADC0 = A0
#define MAXADCRESOLUTION 1024
int soilMoistureAcquired = 0;  // value read 
float soilMoistureVoltage = 0.0;
float soilMoistureThreshold = 1.0;
float powerSupply = 3.3;

Definisci gli oggetti che si interfacceranno agli altri sensori:

Adafruit_BMP085 bmp;  
BH1750 brightnessMeasure;
DHTesp dht;

Definisci poi i GPIO dedicati al DHT22 e al pilotaggio del modulo relè:

#define  DHT22_PIN 14   
#define  RELAY_1  13
#define  RELAY_2  12

Infine definisci le variabili che stabiliscono la temporizzazione delle misure (in questo caso le grandezze saranno misurate ogni 10 minuti):

unsigned long measureDelay = 600000;                //    NOT LESS THAN 2000!!!!!    BETTER 600000  (10 MINUTES)
unsigned long lastTimeRan;

Prosegui con l’implementazione delle funzioni che aprono/chiudono l’elettrovalvola (open_valve e close_valve) e quelle che le tolgono l’alimentazione (reset_valve_high e reset_valve_low) mettendo i due pin allo stesso potenziale:

void reset_valve_high() {
  // Sends 0V to the valve setting HIGH both control pins.
  digitalWrite(RELAY_1, HIGH);
  digitalWrite(RELAY_2, HIGH);  
  Serial.println("Reset HIGH\n");
}

void reset_valve_low() {
  // Sends 0V to the valve setting LOW both control pins.
  digitalWrite(RELAY_1, LOW);
  digitalWrite(RELAY_2, LOW);  
  Serial.println("Reset LOW\n");
}


void open_valve() {
  // Sends a 10ms impulse to open the valve.
  digitalWrite(RELAY_1, LOW);
  digitalWrite(RELAY_2, HIGH);
  delay(200); 
  Serial.println("\nValve opened. Water Flowing\n");
}


void close_valve() {
  // Sends a 10ms impulse to open the valve.
  digitalWrite(RELAY_1, HIGH);
  digitalWrite(RELAY_2, LOW);
  delay(200);
  Serial.println("\nValve closed. Water not Flowing\n");
}

L’elettrovalvola si apre ponendo il pin RELAY_2 su HIGH (cioè 1) e il pin RELAY_1 su LOW (cioè 0) per 200 ms (riga delay(200); ) e si chiude invertendo lo stato dei due pin.

A seconda del modello di elettrovalvola, potrebbe essere necessario modificare per tentativi questo intervallo di tempo.

Vediamo ora cosa succede nella funzione setup.

Inizialmente devi modificare la velocità della porta seriale da 9600 a 115200:

Serial.begin(115200);

invece di:

Serial.begin(9600);

e, se non è già presente, imponi un ritardo in modo da dare il tempo alla porta di inizializzarsi, così:

delay(1500); 

Procedi poi all’inizializzazione del bus I2C, dei sensori di luminosità e di pressione, del sensore di temperatura ed umidità, delle variabili mode e lastStatus e delle funzioni initProperties(), ArduinoCloud.begin(ArduinoIoTPreferredConnection), setDebugMessageLevel(2) e ArduinoCloud.printDebugInfo() che inizializzano la parte gestita da Arduino Cloud:

  Wire.begin();           

  brightnessMeasure.begin();

  if (!bmp.begin()) {
    Serial.println("Could not find a valid BMP085/BMP180 sensor, check wiring!");      
    while (1) {}
  }

  dht.setup(DHT22_PIN, DHTesp::DHT22); // Connect DHT sensor to GPIO 14 

  mode = true;
  lastStatus = false;  

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

Alla fine della funzione setup procederai a definire come OUTPUT i due pin che gestiscono il modulo relè:

  pinMode(RELAY_1, OUTPUT);
  pinMode(RELAY_2, OUTPUT);

e a dare il comando di chiusura dell’elettrovalvola (per evitare accidentali allagamenti):

close_valve();
reset_valve_high();

Vediamo ora come è fatta la funzione loop:

Inizialmente c’è la funzione ArduinoCloud.update() che si occupa di aggiornare lo stato del Cloud seguita da un blocco che si occupa della acquisizione delle misure delle grandezze fisiche ogni measureDelay millisecondi (nel nostro caso sono 600000 corrispondenti a 10 minuti):

ArduinoCloud.update();
// Your code here 

if (millis() > lastTimeRan + measureDelay)  {
atmosphericHumidity = dht.getHumidity();
atmosphericTemperature = dht.getTemperature();
ambientLight = brightnessMeasure.readLightLevel();
atmosphericPressure = bmp.readPressure() / 100.0;   
soilMoistureAcquired = analogRead(ANALOGPIN0); 
soilMoisture = (powerSupply / MAXADCRESOLUTION) * soilMoistureAcquired / 0.033;  

Serial.println("Sending data...");      

lastTimeRan = millis();
}

Queste variabili sono definite all’interno della test_thing che abbiamo realizzato all’interno di Arduino Cloud quindi vengono aggiornate in tempo reale sul Cloud.

Segue un blocco if che stabilisce se l’irrigatore è impostato sulla modalità automatica (quando la variabile mode è true) oppure sulla modalità manuale (quando la variabile mode è false). Nel primo caso viene eseguito il blocco principale, nel secondo caso viene eseguito il codice all’interno dell’else:

if(mode) {                    // if mode == true   automatic mode

switch(schedule.isActive())
{
    case 0:             // if valve state is CLOSED, closes the valve
    if(lastStatus != schedule.isActive()) {
        close_valve();
        reset_valve_high();
    }      
    lastStatus = false;
    break;

    case 1:             // if valve state is OPEN, opens the valve
    if(lastStatus != schedule.isActive()) {
        open_valve();
        reset_valve_low();
    }
    lastStatus = true;
    break;
}

} else {                    // if mode == false    manual mode

    switch(activate)
    {
    case 0:             // if valve state is CLOSED, closes the valve
        if(lastStatus != activate) {
        close_valve();
        reset_valve_high();
        }      
        lastStatus = false;
        break;
    
    case 1:             // if valve state is OPEN, opens the valve
        if(lastStatus != activate) {
        open_valve();
        reset_valve_low();
        }
        lastStatus = true;
        break;
    }

}

Vediamolo ora più nel dettaglio.

Nella modalità automatica (blocco principale) l’apertura o chiusura dell’elettrovalvola è decisa dallo scheduler della Dashboard. Al suo interno abbiamo una struttura switch…case così fatta:

switch(schedule.isActive())
{
    case 0:             // if valve state is CLOSED, closes the valve
    if(lastStatus != schedule.isActive()) {
        close_valve();
        reset_valve_high();
    }      
    lastStatus = false;
    break;

    case 1:             // if valve state is OPEN, opens the valve
    if(lastStatus != schedule.isActive()) {
        open_valve();
        reset_valve_low();
    }
    lastStatus = true;
    break;
}

Tale struttura controlla lo stato della variabile schedule (in particolare se schedule.isActive() è vero o falso). Nel caso sia falso (case 0) significa che dalla Dashboard lo scheduler ha dato il comando di chiusura dell’elettrovalvola. Nel caso sia vero (case 1) significa che dalla Dashboard lo scheduler ha dato il comando di apertura dell’elettrovalvola.

Nella modalità manuale (blocco else) l’apertura o chiusura dell’elettrovalvola è decisa dall’utente agendo sull’apposito switch presente sulla Dashboard. Al suo interno abbiamo una struttura switch…case così fatta:

switch(activate)
{
case 0:             // if valve state is CLOSED, closes the valve
    if(lastStatus != activate) {
    close_valve();
    reset_valve_high();
    }      
    lastStatus = false;
    break;

case 1:             // if valve state is OPEN, opens the valve
    if(lastStatus != activate) {
    open_valve();
    reset_valve_low();
    }
    lastStatus = true;
    break;
}

La variabile activate è quella associata al suddetto switch. Quindi, se l’utente decide di chiudere l’elettrovalvola agendo sullo switch sulla Dashboard, la variabile activate assumerà il valore 0 (false) attivando nello switch…case la prima sezione che chiama le funzioni:

close_valve();
reset_valve_high();

Se, invece, l’utente decide di aprire l’elettrovalvola agendo sullo switch, la variabile activate assumerà il valore 1 (true) attivando nello switch…case la seconda sezione che chiama le funzioni:

open_valve();
reset_valve_low();

Ovviamente puoi scaricare il progetto completo dal link seguente:

Video del funzionamento del nostro irrigatore

Una volta realizzato il circuito, compilato il progetto e caricato sulla ESP8266 dovremmo essere già in grado di agire sull’irrigatore. Dovresti poter vedere i primi dati acquisiti sulla Dashboard dopo circa 10 minuti (se hai lasciato l’impostazione che ho dato io). Ad ogni modo eccoti un video che mostra il funzionamento del progetto:

Alimentiamo il nostro impianto tramite l’energia solare

Un problema che si nota subito è che tale impianto non è indipendente da una fonte di energia derivata da un alimentatore. Si potrebbe anche usare un power bank ma questo necessita di essere periodicamente staccato per ricaricarlo. Una soluzione più efficiente è quella di alimentare l’irrigatore con un sistema dotato di pannello fotovoltaico e batteria. Se sei interessato a questo miglioramento ti rimando alla lettura dell’articolo Alimentazione solare per Arduino, ESP8266 e IoT: guida completa all’indipendenza energetica.

Il sistema alimentato con l'energia solare (in questa foto sta lavorando solo la parte datalogger mentre l'elettrovalvola è disabilitata)
Il sistema alimentato con l’energia solare (in questa foto sta lavorando solo la parte datalogger mentre l’elettrovalvola è disabilitata)

La dashboard mostra i valori rilevati in tempo reale dal dispositivo alimentato col sistema fotovoltaico
La dashboard mostra i valori rilevati in tempo reale dal dispositivo alimentato col sistema fotovoltaico

Realizziamo il PCB per il nostro irrigatore automatico

Uno degli aspetti più interessanti e utili del nostro progetto di irrigatore automatico e datalogger è la realizzazione di un PCB (Printed Circuit Board) personalizzato. Questo PCB svolge un ruolo fondamentale nell’ottimizzazione del nostro sistema, offrendo numerosi vantaggi. Prima di tutto, consente una maggiore affidabilità, poiché sostituisce i cablaggi complessi su breadboard (ed elimina tanti fili aggrovigliati) e riduce al minimo i rischi di errori di collegamento. Inoltre, il PCB rende il nostro sistema più compatto e ben organizzato, risparmiando spazio prezioso. Ma ciò che rende davvero speciale il nostro PCB personalizzato è la sua capacità di integrare perfettamente le diverse componenti del nostro sistema, inclusi il controllo dell’irrigazione e la registrazione dei dati. Questo significa che il nostro sistema è ora più efficiente e pronto a fornire un servizio affidabile per l’irrigazione delle piante, oltre a registrare dati importanti per il monitoraggio delle condizioni ambientali.

Ma cosa è un PCB?

Un PCB, o Printed Circuit Board, è uno dei componenti fondamentali dell’elettronica moderna. Si tratta di una sottile scheda isolante generalmente realizzata in materiale composito o vetroresina, sulla quale sono stampati circuiti elettrici conduttivi che collegano componenti elettronici. Il PCB funge da piattaforma fisica su cui montare componenti come resistenze, condensatori, transistor e microchip. La disposizione precisa dei circuiti stampati su un PCB è importante per il funzionamento stabile di qualsiasi dispositivo elettronico. Grazie alla sua capacità di semplificare e organizzare i collegamenti elettrici, i PCB sono diventati un elemento chiave in una vasta gamma di applicazioni, dalla telefonia mobile all’automazione industriale. Per progettare un PCB in modo efficiente e preciso, gli ingegneri e gli appassionati di elettronica utilizzano strumenti software di progettazione PCB avanzati. Tra i tanti presenti sul mercato c’è KiCad (open source e gratuito) che ha raggiunto un eccellente livello di professionalità e che ho usato per questo progetto. Questo software consente di creare schemi elettrici dettagliati, disegnare il layout dei componenti e dei circuiti, instradare tracce elettriche in modo ottimale e generare file di produzione per la fabbricazione del PCB. Con l’aiuto di questa potente suite di progettazione, è possibile realizzare PCB personalizzati che soddisfano le specifiche esigenze del proprio progetto, garantendo una connettività affidabile e un funzionamento efficiente.

Una volta che il progetto è stato completato, lo si manda ad una delle aziende specializzate nella loro realizzazione.

Il PCB di questo articolo è stato materialmente realizzato dall’azienda PCBWay dato che KiCad ha un plug-in che consente di realizzare i files di progetto in formato compatibile con quello richiesto da tale azienda.

Ovviamente puoi scaricare il progetto KiCad da questo link:

Ecco lo schema elettrico realizzato con Kicad 6
Ecco lo schema elettrico realizzato con KiCad 6

Ed ecco le immagini del rendering 3D eseguito da KiCad 6:

Il lato TOP del PCB
Il lato TOP del PCB
Il lato BOTTOM del PCB
Il lato BOTTOM del PCB

Vediamo in pratica come sono i PCB realizzati

Il PCB accoglierà i componenti che abbiamo già usato e che sono attualmente presenti sulla breadboard. Prima di tutto è consigliabile saldare sul PCB dei connettori header femmina con passo da 2.54mm in modo da poter inserire agevolmente i vari componenti. Questo per evitare di doverli saldare sul PCB in maniera permanente e consentire di poterli staccare al bisogno. Se non sei pratico di saldatura puoi dare un’occhiata all’articolo Un altro tutorial su come saldare presente su questo blog.

Ecco come si presentano i connettori header femmina passo 2.54 mm
Ecco come si presentano i connettori header femmina passo 2.54 mm

Di seguito possiamo vedere il PCB con i connettori saldati e i componenti che dovranno essere inseriti sui connettori:

PCB con i connettori
PCB con i connettori

In genere questi connettori sono venduti in strisce da 40 pin quindi è necessario accorciarli con delle piccole tronchesine.

Questa foto mostra invece i vari componenti, che prima stavano sulla breadboard, montati sui connettori del PCB:

PCB con i componenti inseriti
PCB con i componenti inseriti

Infine vediamo come è stato montato il modulo relè: sono sufficienti 4 distanziatori in nylon e relativi viti/dadi per fissarlo nei fori predisposti sul PCB. Per finire occorrerà collegare i fili provenienti dal modulo relè (VCC, IN1, IN2, GND) sull’apposito connettore.

Modulo relè montato sul PCB
Modulo relè montato sul PCB

Modulo relè montato sul PCB (visto da dietro)
Modulo relè montato sul PCB (visto da dietro)

Newsletter

Se vuoi essere aggiornato sui nuovi articoli, iscriviti alla newsletter. Prima dell’iscrizione alla newsletter leggi la pagina Privacy Policy (UE)

Se ti vuoi disiscrivere dalla newsletter clicca sul link che troverai nella mail della newsletter.

Inserisci il tuo nome
Inserisci la tua email
Torna in alto