Irrigazione Arduino – Gregory

Qualche giorno fa mi ha scritto un appassionato: Gregory per raccontarmi il suo progetto di irrigazione arduino:

centralina 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:

Gregory's House

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:

  1. riutilizza acqua piovana, risparmiando il consumo di acqua corrente
  2. irriga i propri terreni con acqua ricca di sali minerali che fanno davvero bene alle coltivazioni non contaminata da agenti chimici

Lo schema elettrico

Lo schema elettrico utilizzato per il progetto è il seguente:

schema elettrico

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
a ciascun pin corrisponde un relé che a sua volta attiva una elettrovalvola.
le successive righe impostano l’ora di avvio e di chiusura dei settori relativi all’orto, al frutteto ed alle patate:
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;
la parte dello sketch che si occupa di gestire poi l’apertura e la chiusura delle elettrovalvole è ripetuta in fondo al ciclo di loop() per ciascun settore o zona di irrigazione:
// 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();
}
in cui noti che al raggiungimento dell’orario h_alarm dei giorni 1,3,5 e 0 ( rispettivamente lun, merc, ven, dom ) parte l’irrigazione del settore indicato, chiamando la funzione irrigazione_orto() o una delle altre definite in fondo allo sketch di Gregory:
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 !!!

  • Questo sito ed i suoi contenuti è fornito "così com'è" e Mauro Alfieri non rilascia alcuna dichiarazione o garanzia di alcun tipo, esplicita o implicita, riguardo alla completezza, accuratezza, affidabilità, idoneità o disponibilità del sito o delle informazioni, prodotti, servizi o grafiche correlate contenute sul sito per qualsiasi scopo.
  • Ti chiedo di leggere e rispettare il regolamento del sito prima di utilizzarlo
  • Ti chiedo di leggere i Termini e Condizioni d'uso del sito prima di utilizzarlo
  • In qualità di Affiliato Amazon io ricevo un guadagno dagli acquisti idonei qualora siano presenti link al suddetto sito.

Permalink link a questo articolo: https://www.mauroalfieri.it/elettronica/irrigazione-arduino-gregory.html

10 commenti

Vai al modulo dei commenti

    • Massimo il 7 Giugno 2013 alle 14:17
    • Rispondi

    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?

    1. 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

  1. 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….

    1. 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

        • Alberto il 8 Giugno 2013 alle 14:11
        • Rispondi

        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.

        1. Grande Alberto,
          grazie 1000 per il tuo prezioso contributo, correggerò l’informazione aggiungendo le tue considerazioni.

          Mauro

    • Massimo Lucchese il 10 Settembre 2013 alle 01:05
    • Rispondi

    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.

    1. 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

        • Massimo Lucchese il 12 Settembre 2013 alle 11:54
        • Rispondi

        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.

        1. 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

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.