Qualche giorno fa mi ha scritto un appassionato: Gregory per raccontarmi il suo progetto di irrigazione arduino:
Gregory ha realizzato una sua personale versione della centralina di irrigazione arduino e lo ha fatto anche prima che io pubblicassi i miei esperimenti.
Gregory ha realizzato anche un blog in cui pubblica i suoi lavori, veramente ben fatto graficamente e con una filosofia già nel titolo che ti accoglie:
Il progetto di irrigazione arduino descritto sul blog di Gregory è molto interessante perchè arricchisce quello da me pubblicato “irrigare con Arduino” aggiungendo la possibilità di irrigare 3 differenti zone:
- un orto
- un campo di patate
- un frutteto
e lasciarti la possibilità di avere una uscita per la canna.
Inoltre Gregory è davvero attento all’ambiente ed ha costruito delle cisterne in cui raccoglie l’acqua piovana ottenendo almeno due ottimi risultati:
- riutilizza acqua piovana, risparmiando il consumo di acqua corrente
- irriga i propri terreni con acqua
ricca di sali minerali che fanno davvero bene alle coltivazioninon contaminata da agenti chimici
Lo schema elettrico
Lo schema elettrico utilizzato per il progetto è il seguente:
replicato per ciascuna delle elettrovalvole che vuoi controllare.
Lo sketch dell’irrigazione arduino di Gregory
Ho chiesto a Gregory di inviarmi lo sketch pe poterlo condividere ed ha confermato la mia prima intuizione: è davvero una splendida persona e disponibile a condividere i suoi successi con altri appassionati.
/* * SISTEMA DI IRRIGAZIONE IRRIGREG * 3 linee di irrigazione con comando manuale e automatico * + sistema di travaso tra due cisterne * * http://gregmaracas.blogspot.it/ */ #include <DS1307new.h> #include <Wire.h> int patate = 10; int frutta = 9; int orto = 8; int travaso = 11; int pompa = 7; int h_alarm = 15; int m_alarm = 30; int fine_alarm = 44; int h_alarm_frutta = 6; int m_alarm_frutta = 01; int fine_alarm_frutta = 15; int h_alarm_patate = 6; int m_alarm_patate = 16; int fine_alarm_patate = 31; boolean active_orto = false; boolean active_orto_man = false; boolean active_patate = false; boolean active_patate_man = false; boolean active_frutta = false; boolean active_frutta_man = false; boolean travaso_int = false; boolean orto_int = false; boolean frutta_int = false; boolean patate_int = false; boolean pompa_int = false; void setup() { Serial.begin(9600); //inizializzo la seriale pinMode (travaso, OUTPUT); pinMode (frutta, OUTPUT); pinMode (patate, OUTPUT); pinMode (orto, OUTPUT); pinMode (pompa, OUTPUT); pinMode (2, INPUT); pinMode (3, INPUT); pinMode (4, INPUT); pinMode (5, INPUT); pinMode (6, INPUT); digitalWrite(travaso, LOW); digitalWrite(frutta, LOW); digitalWrite(orto, LOW); digitalWrite(patate, LOW); digitalWrite(pompa, LOW); Wire.begin(); //inizializzo la libreria wire /*parte commentata da utilizzare solo per rimettere l'orologio, questione da sviluppare*/ //RTC.stopClock(); //RTC.fillByYMD(2013,4,21); //RTC.fillByHMS(14,39,0); //RTC.setTime(); //RTC.startClock(); //RTC.adjust(DateTime(__DATE__, __TIME__)); } /*nuovo loop con libreria DS1307new*/ void loop() { RTC.getTime(); //abilito l'acquisizione dei dati Serial.println(" "); Serial.println("giorno della settimana"); switch (RTC.dow) { case 1: Serial.print("LUNEDI'"); break; case 2: Serial.print("MARTEDI'"); break; case 3: Serial.print("MERCOLEDI'"); break; case 4: Serial.print("GIOVEDI'"); break; case 5: Serial.print("VENERDI'"); break; case 6: Serial.print("SABATO"); break; case 0: Serial.print("DOMENICA"); break; } Serial.println(" "); Serial.println(" "); Serial.println("GG/MM/AAAA"); Serial.print(RTC.day, DEC); Serial.print("/"); Serial.print(RTC.month, DEC); Serial.print("/"); Serial.print(RTC.year, DEC); Serial.println(" "); Serial.println(" "); Serial.println("hh:mm:ss"); Serial.print(RTC.hour, DEC); Serial.print(":"); Serial.print(RTC.minute, DEC); Serial.print(":"); Serial.print(RTC.second, DEC); Serial.println(" "); Serial.print(RTC.dow, DEC); delay (1000); if ((!travaso_int) && (!patate_int) && (!frutta_int) && (!orto_int) && (!pompa_int)) { fermato(); } if (digitalRead(5) == HIGH) { digitalWrite(frutta, LOW); digitalWrite(orto, LOW); digitalWrite(patate, LOW); digitalWrite(travaso, LOW); delay (1000); digitalWrite(pompa, HIGH); pompa_int = true; } else { pompa_int = false; } if (digitalRead(6) == HIGH) { //travaso faitravaso(); travaso_int = true; } else { travaso_int = false; } if (digitalRead(3) == HIGH) { //frutta irrigazione_frutta(); frutta_int = true; } else { frutta_int = false; } if (digitalRead(4) == HIGH) { //patate irrigazione_patate(); patate_int = true; } else { patate_int = false; } if (digitalRead(2) == HIGH) { //orto irrigazione_orto(); orto_int = true; } else { orto_int = false; } // automatico orto: lunedi mercoledi venerdi domenica if ((!active_orto) && (RTC.hour == h_alarm) && ((RTC.dow == 1) || (RTC.dow == 3) || (RTC.dow == 5) || (RTC.dow == 0)) && (RTC.minute >= m_alarm) && (!pompa_int) && (!travaso_int) && (!orto_int) && (!travaso_int) && (!frutta_int) && (!patate_int)) { irrigazione_orto(); } if ((active_orto) && (RTC.hour == h_alarm) && (RTC.minute >= fine_alarm) && (!pompa_int) && (!travaso_int) && (!orto_int) && (!travaso_int) && (!frutta_int) && (!patate_int)) { fermato(); active_orto = false; } //automatico frutta: martedì giovedi sabato if ((!active_frutta) && (RTC.hour == h_alarm_frutta) && ((RTC.dow == 2) || (RTC.dow == 4) || (RTC.dow == 6)) && (RTC.minute >= m_alarm_frutta) && (!pompa_int) && (!travaso_int) && (!orto_int) && (!travaso_int) && (!frutta_int) && (!patate_int)) { irrigazione_frutta(); } if ((active_frutta) && (RTC.hour == h_alarm_frutta) && (RTC.minute >= fine_alarm_frutta) && (!pompa_int) && (!travaso_int) && (!orto_int) && (!travaso_int) && (!frutta_int) && (!patate_int)) { fermato(); active_frutta = false; } //automatico patate: martedì giovedi sabato in coda alla frutta if ((!active_patate) && (RTC.hour == h_alarm_patate) && ((RTC.dow == 2) || (RTC.dow == 4) || (RTC.dow == 6)) && (RTC.minute >= m_alarm_patate) && (!pompa_int) && (!travaso_int) && (!orto_int) && (!travaso_int) && (!frutta_int) && (!patate_int)) { irrigazione_patate(); } if ((active_patate) && (RTC.hour == h_alarm_patate) && (RTC.minute >= fine_alarm_patate) && (!pompa_int) && (!travaso_int) && (!orto_int) && (!travaso_int) && (!frutta_int) && (!patate_int)) { fermato(); active_patate = false; } } void irrigazione_orto() { digitalWrite(frutta, LOW); digitalWrite(orto, HIGH); digitalWrite(patate, LOW); digitalWrite(travaso, LOW); delay (1000); digitalWrite(pompa, HIGH); } void irrigazione_frutta() { digitalWrite(frutta, HIGH); digitalWrite(orto, LOW); digitalWrite(patate, LOW); digitalWrite(travaso, LOW); delay (1000); digitalWrite(pompa, HIGH); } void irrigazione_patate() { digitalWrite(frutta, LOW); digitalWrite(orto, LOW); digitalWrite(patate, HIGH); digitalWrite(travaso, LOW); delay (1000); digitalWrite(pompa, HIGH); } void fermato() { digitalWrite(frutta, LOW); digitalWrite(orto, LOW); digitalWrite(patate, LOW); digitalWrite(travaso, LOW); digitalWrite(pompa, LOW); } void faitravaso() { digitalWrite(frutta, LOW); digitalWrite(orto, LOW); digitalWrite(patate, LOW); digitalWrite(travaso, HIGH); //da collegare due elettrovalvole in parallelo digitalWrite(pompa, HIGH); }
Il codice è scritto in modo chiaro per cui non dovresti avere difficoltà a comprenderne il funzionamento, evidenzio solo le parti più complesse dal punto di vista logico:
int patate = 10; int frutta = 9; int orto = 8; int travaso = 11; int pompa = 7;
in queste prime righe trovi l’impostazione dei pin corrispondenti a ciascuna delle zone:
- patate
- frutteto
- orto
- travaso da cisterna a cisterna
- canna o pompa a mano
int h_alarm = 15; int m_alarm = 30; int fine_alarm = 44; int h_alarm_frutta = 6; int m_alarm_frutta = 01; int fine_alarm_frutta = 15; int h_alarm_patate = 6; int m_alarm_patate = 16; int fine_alarm_patate = 31;
// automatico orto: lunedi mercoledi venerdi domenica if ((!active_orto) && (RTC.hour == h_alarm) && ((RTC.dow == 1) || (RTC.dow == 3) || (RTC.dow == 5) || (RTC.dow == 0)) && (RTC.minute >= m_alarm) && (!pompa_int) && (!travaso_int) && (!orto_int) && (!travaso_int) && (!frutta_int) && (!patate_int)) { irrigazione_orto(); }
void irrigazione_orto() { digitalWrite(frutta, LOW); digitalWrite(orto, HIGH); digitalWrite(patate, LOW); digitalWrite(travaso, LOW); delay (1000); digitalWrite(pompa, HIGH); }
Il cui scopo è inviare un comando di tipo digitalWrite( pin,HIGH ) al settore corrispondente.
Buona irrigazione !!!
10 commenti
Vai al modulo dei commenti
Mauro, una domanda banale: da dove viene il dato della data e dell’ora?
si puo’ impostare data e ora in Arduino e utilizzarla nei programmi in cui si necessita un’azione a un determinato orario?
Autore
Ciao Massimo,
l’informazione della data e dell’ora la prelevi dalla RTC Shield.
Prova leggere gli articoli che ho dedicato a questa shield per capire come si imposta la prima volta e come la puoi modificare.
Mauro
Senza entrare nel merito della programmazione e dell’ottimo lavoro, vorrei sapere come mai nell’articolo c’è scritto che irrigare con l’acqua piovana recuperata è ottimo perché è ricca di sali ? in realtà è l’esatto contrario, praticamente l’acqua piovana se non passa in mezzo alle pietre è praticamente acqua distillata….
Autore
Ciao Daniele,
la tua osservazione é acuta e precisa, io avevo letto su alcuni siti che l’acqua piovana fosse carica di sali ed ho riportato l’informazione ritenuta veritiera.
Hai delle fonti su cui posso leggere la verità sull’acqua piovana in merito ai sali? Correggerei l’articolo citandole.
Mauro
Confermo che l’acqua piovana é praticamente priva di sali ma ad un terreno fertile i sali non servono.
Direi piuttosto che l’irrigazione con acqua piovana ha il vantaggio di non inquinare con i disinfettanti che sono presenti nell’acqua potabile (normalmente cloro o derivati)
Alberto
P.S.
Vorrei dare il mio contributo a questo interessante progetto aggiungendo qualche possibile funzione.
Sensore di pioggia con registrazione in memoria in modo da evitare l’irrigazione se non sono passate almeno X ore dall’ultima pioggia. Pioggia che potrebbe essere quantificata in base al tempo di persistenza del bagnato sul sensore e che potrebbe quindi triggerare la decisione SI/NO all’irrigazione.
Per fare i fini si potrebbe anche mettere un misuratore di acqua piovana………..ma forse é eccessivo.
Se peró uno ce l’ha giá o ha una stazione meteo gestita da arduino, basta scambiare l’informazione ed il gioco é fatto.
Autore
Grande Alberto,
grazie 1000 per il tuo prezioso contributo, correggerò l’informazione aggiungendo le tue considerazioni.
Mauro
Complimenti vivissimi per questo bellissimo sito… Passiamo ora al mio problema. Ho seguito i vari tutorial sull’irrigazione con arduino ma non sono per niente bravo con la programmazione. Ho preso e montato come da tua descrizione (https://www.mauroalfieri.it/elettronica/centralina-irrigazione-arduino.html), arduino 1 rev.3, RTC shield ds 1307, e una relay shield da 6 relè (http://www.futurashop.it/index.php?route=product/product&filter_name=ft919k&product_id=559). Con questa scheda devo comandare 3 elettrovalvole, la pompa e l’illuminazione del giardino alla sera. Mi servirebbe quindi uno sketch tipo quello di Gregory ma mi dà qualche errore (sketch_sep10c.ino: In function ‘void loop()’:
sketch_sep10c:75: error: ‘RTC’ was not declared in this scope
).
Sai aiutarmi?
Grazie mille, Massimo.
Autore
Ciao Massimo,
L’errore ne hai é dovuto alla mancanza della libreria RTClib.h che dovresti trovare sul sito del produttore della shield.
Ti consiglio di leggere almeno il corso base pubblicato sul blog per apprendere le prime nozioni su arduino e riconoscere gli errori di sintassi o di librerie mancanti.
Mauro
Ma io l’ RTClib.h ce l’ho! Infatti il tuo sketch (https://www.mauroalfieri.it/elettronica/centralina-irrigazione-arduino.html) funziona a meraviglia! Ma quello è modificato, giusto? Devo mettere quello non modificato? Ci provo.
Autore
Ciao Massimo,
ho riletto l’errore che mi hai copiato e lo avevo mal interpretato, non ti manca la libreria ma la dichiarazione dell’oggetto RTC, probabilmente nello sketch di Gregorio é differente dalla dichiarazione necessaria per la libreria che hai.
Prendi la mia dichiarazione, visto che funziona, e riportala nello sketch che stai usando.
Dovrai fare un po’ di test e prove ma puoi riuscirci seguendo la descrizione dei miei sketch, sono li per aiutare tutti gli appassionati a imparare la programmazione arduino.
Mauro