Gestione di una cisterna per la raccolta acqua piovana con Arduino

di Girolamo D’Orio
Trattiamo qui della realizzazione di un dispositivo per la gestione di una cisterna per acqua piovana. La visualizzazione del livello avviene su display LCD 2×16. Tramite rotary encoder è possibile effettuare la scelta del quantitativo riempibile in caso di siccità con elettrovalvola per afflusso di acqua diretta. I dati impostati sono salvati su Eeprom. Si può escludere la pompa aspirante quando il livello dell’acqua è minimo.
Questa realizzazione è nata da una mia esigenza che ho dovuto affrontare nell’estate siccitosa del 2015. Purtroppo i mutamenti climatici hanno la tendenza a manifestarsi con caratteristiche di un clima tropicale, nel nostro paese. Lunghi periodi di siccità vengono interrotti da violenti temporali e nubifragi. Nel mio lavoro, nel periodo da Aprile ad Agosto, occorre avere sempre una notevole disponibilità di acqua per eseguire i trattamenti nel vigneto. Anche con le nuove attrezzature, come gli atomizzatori a basso volume, occorrono almeno 200 litri di acqua per ettaro di vigneto per effettuare un trattamento per ottenere una buona copertura. Purtroppo l’acqua potabile ha un costo e l’obbiettivo è di consumarla il meno possibile per il suo costo e il relativo rispetto civico. L’installazione di una cisterna per l’accumulo di acqua piovana raccolta da un tetto è un’ottima soluzione, ma se non piove come la riempiamo? Per anni ho fatto come, penso, fanno un po’ tutti in caso di siccità: la classica tubazione in gomma “volante” per riempire la cisterna. Spesso la portata è minima, occorre molto tempo per arrivare al livello desiderato per fronteggiare l’emergenza. Il problema è quindi chiuderla al momento giusto per evitare sprechi di acqua. Il dispositivo creato serve proprio a questo. Quattro interruttori galleggianti, opportunamente installati, rilevano il livello con uno step del 25% rispetto alla capacità massima. Gli interruttori galleggianti non solo comunicano costantemente il livello della cisterna su lcd, ma svolgono la funzione anche di interruttore di minimo e di massimo per la fase riempimento. Il valore di riempimento massimo è configurabile.
[iscritti]

Figura 1: Schema elettrico.
Figura 1: Schema elettrico.

Tramite rotary encoder, tenendolo premuto almeno per circa 1 secondo, entreremo nel menù per scegliere fino a quale percentuale la cisterna dovrà essere riempita con acqua potabile. Il dato scelto verrà immagazzina nella eeprom del microcontrollore, così il dispositivo, anche in caso di momentaneo blackout svolgerà correttamente il suo compito. Ad ogni riavvio, il dispositivo, visualizza su lcd, durante la fase di inizializzazione, il livello di riempimento precedentemente impostato, per evitare tutte le volte di selezionarlo e di continuare a fare il suo lavoro anche dopo il blackout momentaneo. La mia esigenza è di avere sempre una cisterna che abbia un livello minimo da permettermi di svolgere un trattamento, non mi devo trovare nella condizione che mi manchi acqua. Ognuno di noi avrà la propria esigenza, quindi il sorgente dovrà essere compilato inserendo dati corretti per ottimizzare le vostre necessità. Ecco la mia condizione per farvi capire come dovrà essere impostato, per arrivare all’obbiettivo di sprecare inutilmente acqua potabile.

Figura 2: PCB (148mm x 61mm).
Figura 2: PCB (148mm x 61mm).

La cisterna ha una capacità di 150 hl e ad ogni trattamento mi occorrono circa 80 hl. Il trattamento necessità di 2 giorni lavorativi per effettuarlo. Mettiamoci nella condizione che non è prevista pioggia nei giorni antecedenti al trattamento. Accendo il dispositivo e scelgo che la cisterna dovrà riempirsi con acqua potabile fino al 50% della sua capacità. L’elettrovalvola a questo punto si apre se la cisterna è al di sotto della soglia imposta, si chiuderà solamente quando l’acqua ha raggiunto il livello del 50%. Il dispositivo rimane quindi acceso e io incomincio a prelevare l’acqua per il mio scopo. L’elettrovalvola rimane chiusa, si apre solamente quando scenderò sotto il livello del 25%. Arrivati a questa soglia si commuta anche il relè che disabilita la pompa di prelievo acqua. Perché questa scelta? Oltre a salvaguardare la pompa che non lavori in assenza di acqua, se la cisterna, come nel mio caso, è interrata, se rimane vuota, si può andare incontro ad un notevole problema.

Figura 3: Disposizione componenti.
Figura 3: Disposizione componenti.

Nel caso di forti temporali può capitare che le gronde del tetto non riescano a far defluire correttamente l’acqua. Molto spesso, quando accadono questi fenomeni, la prima cosa che scorre nei canali, sono i nidi di volatili, foglie o altro che vanno ad ostruire il canale. Quindi, in questo caso, ci troviamo in una condizione dove l’acqua piovana non arriva alla cisterna, ma sta piovendo molto. Se la cisterna è vuota, e in caso di temporale si infiltra l’acqua dal sottosuolo alla base della cisterna, si verifica il principio fisico che permette alle grandi navi di galleggiare. In questo caso vi vedrete riemergere dal terreno la cisterna, che sia di cemento, in pvc o di acciaio. Un vero disastro. E’ per questo motivo che ho deciso che la cisterna deve almeno avere un livello pari ad ¼ della sua capacità totale.

Descrizione del circuito

Prima di trattare della descrizione hardware, faccio notare che il PCB, in molti punti, ha la presenza di tensione di 230 Vac, quindi occorre prestare molta attenzione, soprattutto in fase di collaudo. Fate attenzione a dove lo appoggiate, a farsi male sul serio ci vuole poco. L’alimentatore, costituito dal trasformatore, dal ponte a diodi, dallo stabilizzatore a 5Vcc e contornato dalle capacità di livellamento e di filtraggio, alimenta tutto il circuito. L’assorbimento, non modestissimo quando capita che anche i due relè sono eccitati, può arrivare ad assorbire oltre 500 mA, quindi si deve “alettare” generosamente il 7805, soprattutto se reperite un trasformatore con un secondario superiore a 9Vac. Per gli interruttore galleggianti, ho scelto questa soluzione di proposito, in modo da non portare tensioni e correnti a contatto diretto con l’acqua. Lavorando con tensioni continue e non alternate, per non complicare il progetto, il fenomeno dell’elettrolisi si farebbe notare subito con un conseguente errore di lettura del livello. Questi galleggianti-interrutori al loro interno hanno un reed e aggirano questo problema, e dato il loro limitato costo (si parla di pochi euro) ho pensato che sia un giusto compromesso costo-beneficio.

Figura 4: Encoder rotativo.
Figura 4: Encoder rotativo.

Gli ingressi al microcontrollore ATmega328 li ho configurati in come se fossero comuni pulsanti, quindi, per come ho scritto nel sorgente, li ho equipaggiati con resistenze di pulldown da 10K. L’encoder rotativo, modulo già assemblato, può essere collegato direttamente al microcontrollore. Per LCD 2×16, la comunicazione avviene tramite I2C, passando dall’integrato I/O expander PCF8574n. Con questa comunicazione semplifico cablaggi dal micro a lcd e risparmio preziose porte di I/O. Il piccolo circuito separato può essere saldato direttamente dietro l’LCD, in modo di avere solo quattro collegamenti: alimentazione +/- e comunicazione SDA/SCL. Come avete notato dallo schema, gli scambi dei relè sono NA e NC. Ho fatto questa scelta per un risparmio di consumo di energia elettrica. Si presuppone che la cisterna sia almeno sempre sopra il livello minimo, quindi il relè che comanda la pompa RL2 è usato in NC, mentre l’attivazione dell’elettrovalvola si presuppone che sia un uso limitato, quindi il contatto è in NA. Tutto ciò per tenere il meno possibile le bobine dei rispettivi relè eccitate.

Descrizione del software per Arduino

Il sorgente è ben commentato e non troverete nessuna difficoltà nel capirlo. Per prima cosa richiamo le librerie installate per salvare i dati in eeprom e per il dialogo in I2C per LCD. In LCD compare costantemente il livello di acqua presente nella cisterna. Premendo il pulsante sul rotary encoder entreremo nel menù al fine di scegliere il livello a cui la cisterna dovrà essere riempita con acqua potabile. Ruotando il rotary encoder su LCD compare la percentuale di riempimento, che andrà confermata premendo nuovamente il pulsante. Fatto ciò, il dato viene salvato in eeprom, al prossimo riavvio il software andrà a recuperarlo, quindi niente paura per eventuali blackout. Quando l’elettrovalvola si apre, perché il software la abilita in base ai parametri fissati, nella seconda riga di LCD compare la voce “RIEMPIMENTO”. Ricordo ancora una volta che, una volta raggiunto l’obbiettivo di riempimento impostato precedentemente, l’elettrovalvola che permette il riempimento non si apre fino a quando l’interruttore-galleggiante di minimo non si apre. Quando si apre questo ultimo interruttore commuta anche il relè che disabiliterà la pompa di aspirazione dell’acqua della cisterna. Quindi per vostre esigenze diverse, lavorate sul sorgente o sul posizionamento dei galleggianti-interruttori.

Figura 5: Interruttore galleggiante di livello liquidi.
Figura 5: Interruttore galleggiante di livello liquidi.

Consigli per il montaggio

Il montaggio non presenta particolari difficoltà. Per i collegamenti con l’esterno ho utilizzato dei connettori di recupero in disuso. Per collegare i galleggianti-interruttori ho usato un cavo multipolare tipo un fror 5×1.5mm. La sezione non è modesta, considerando che la corrente che circola è prossima allo zero. La scelta è dovuta al fatto di limitare la caduta di tensione, considerando che la tensione è 5Vcc e nel mio caso la lunghezza di linea tra PCB e i galleggianti-interruttori si aggira intorno ai 15 Mt. Per l’elettrovalvola a 230 Vac da almeno ½ pollice, il collegamento va effettuato con un 3×1.5 e si deve collegare il connettore di messa a terra predisposto sul essa. Consiglio di usare l’uscita del relè che abilita/disabilita la pompa, per comandare direttamente la bobina di un teleruttore, il quale accende/spegne la pompa stessa, se quest’ultima dovesse avere un generoso assorbimento.

Figura 6: Realizzazione.
Figura 6: Realizzazione.

Conclusioni

Questo semplice dispositivo, con semplici correzioni al sorgente, può essere impiegato in notevoli applicazioni, non solo ad uso agricolo-professionale, basta pensare all’irrigazione del giardino di casa. Cerchiamo di ottimizzare con efficienza una risorsa importante come l’acqua. Purtroppo il suo maggiore utilizzo avviene quando non piove. Quindi, con un occhio alle previsioni meteo e all’utilizzo intelligente di questo piccolo dispositivo, facciamo sicuramente del bene al portafoglio e all’ambiente. Buon divertimento e buona realizzazione a tutti.
Giro.

Figura 7: installazione dei galleggianti-interruttori su un profilato.
Figura 7: installazione dei galleggianti-interruttori su un profilato.
Figura 8: Vista dall’alto dell’interno della cisterna inox interrata.
Figura 8: Vista dall’alto dell’interno della cisterna inox interrata.
Figura 9: Foto del dispositivo installato.
Figura 9: Foto del dispositivo installato.
LISTATO
#include <EEPROM.h>
 #include <Wire.h>
 #include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2);  // 0x38 utilizzando il pcf8574AN con A1,A2,A3 a gnd----0x20 utilizzando il pcf8574N con A1,A2,A3 a gnd
// PIN 10 SW PULSANTE NORMALMENTEAPERTO LIVELLO LOGICO ALTO
 int val;
 int encoder0PinA = 9;// CLK
 int encoder0PinB = 10;// DT
 int encoder0Pos = -1;
 int encoder0PinALast = LOW;
 int n = LOW;
 int menu; //variabile di comodo per entrare nel menu scelta riempimento
 int livello;
 int range;
 void encoder(){ //menu per selezionare il livello di riempimento
 n = digitalRead(encoder0PinA);
 if ((encoder0PinALast == LOW) && (n == HIGH)) {
 if (digitalRead(encoder0PinB) == LOW) {
 encoder0Pos--;
 } else {
 encoder0Pos++;
 }
 Serial.println (encoder0Pos);
 if ((encoder0Pos<-4) || (encoder0Pos>4)){
 encoder0Pos=0;
}
 }
 if (encoder0Pos <0){
 encoder0Pos=(encoder0Pos * -1);
}
 livello=encoder0Pos;
lcd.setCursor(0,1);
if (livello==0){
 lcd.print("  0%");
 }
 if (livello==1){
 lcd.print(" 25%");
 }
 if (livello==2){
 lcd.print(" 50%");
 }
 if (livello==3){
 lcd.print(" 75%");
 }
 if (livello==4){
 lcd.print("100%");
 }
//      lcd.setCursor(0,1);
 //   lcd.print(encoder0Pos);
 encoder0PinALast = n;
 if (digitalRead(11)==LOW){
 delay(500);
 EEPROM.write(1, livello); // memorizzo nella eeprom la percentuale di livello scelta
 delay(50); // piccola pausa per assicurare la corretta scrittura
 menu=0;
 }
 }
 void setup()
 {
 pinMode(5,INPUT);//25%
 pinMode(6,INPUT);//50%
 pinMode(7,INPUT);//75%
 pinMode(8,INPUT);//100%
 pinMode (encoder0PinA,INPUT);//9
 pinMode (encoder0PinB,INPUT);//10
 pinMode(11,INPUT);//PULSANTE ENCODER
 pinMode(4,OUTPUT);// RELè USANDO CONTATTO NC PER DISATTIVARE POMPA ASPIRAZIONE
 pinMode(3,OUTPUT);// ELETTROVALVOLA apertura acqua
digitalWrite(13,LOW);
Serial.begin (9600);
 lcd.init();                      // inizializzazione  lcd
lcd.backlight();
 lcd.setCursor(0,0);
 lcd.print("LIVELLO CISTERNA");
 lcd.setCursor(0,1);
 lcd.print("     HL 150     ");
 delay(2000);
delay(300);
lcd.setCursor(5,1);
 lcd.print("BY GIRO");
delay(2000);
 lcd.clear();
 livello=EEPROM.read(1);// lettura dalla eeprom del livello precedentemente impostato
 delay(50);
 lcd.setCursor(0,0);
 lcd.print("LIV. RIEMPIMENTO");
 lcd.setCursor(5,1);
 if (livello==0){
 lcd.print("  0%");
 }
 if (livello==1){
 lcd.print(" 25%");
 }
 if (livello==2){
 lcd.print(" 50%");
 }
 if (livello==3){
 lcd.print(" 75%");
 }
 if (livello==4){
 lcd.print("100%");
 }
 delay(2000);
 lcd.clear();
 }
void loop() {
 if (digitalRead(11)==LOW){// pulsante encoder per entrare nel menu
 delay(500);
 menu=1;
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("  % RIEMPIMENTO");
 }
 while (menu==1){
encoder();
 if (menu==0){
 lcd.clear();
 break;
 }
 }
 if ((digitalRead(5)==LOW)&&(digitalRead(6)==LOW) && (digitalRead(7)==LOW) && (digitalRead(8)==LOW)){
 digitalWrite(4,HIGH); // DISABILITO LA POMPA ASPIRANTE
 lcd.setCursor(0,0);
 lcd.print("LIVEL:   <35  Hl");
 if (livello==0){
 digitalWrite(3,LOW);
 }
 else{
 lcd.setCursor(0,1);
 lcd.print("  RIEMPIMENTO...");
 digitalWrite(3,HIGH);
 }
 }
 if ((digitalRead(5)==HIGH)&&(digitalRead(6)==LOW) && (digitalRead(7)==LOW) && (digitalRead(8)==LOW)){  // siamo al 25%
 digitalWrite(4,LOW); //ABILITO POMPA ASPIRANTE
 lcd.setCursor(0,0);
 lcd.print("LIVEL: 35-75  Hl");
 if ((digitalRead(3)==HIGH)&&(livello>=2)){
 lcd.setCursor(0,1);
 lcd.print("  RIEMPIMENTO...");
 }
 else {
 lcd.setCursor(0,1);
 lcd.print("                ");
 digitalWrite(3,LOW);
 }
 }
if ((digitalRead(5)==HIGH)&&(digitalRead(6)==HIGH) && (digitalRead(7)==LOW) && (digitalRead(8)==LOW)){  // siamo al 50%
 digitalWrite(4,LOW);// ABILITO POMPA ASPIRANTE
 lcd.setCursor(0,0);
 lcd.print("LIVEL: 75-110  Hl");
 if ((digitalRead(3)==HIGH)&&(livello>=3)){
 lcd.setCursor(0,1);
 lcd.print("  RIEMPIMENTO...");
 }
 else {
 lcd.setCursor(0,1);
 lcd.print("                ");
 digitalWrite(3,LOW);
 }
 }
if ((digitalRead(5)==HIGH)&&(digitalRead(6)==HIGH) && (digitalRead(7)==HIGH) && (digitalRead(8)==LOW)){  // siamo al 75%
 digitalWrite(4,LOW);// ABILITO POMPA ASPIRANTE
 lcd.setCursor(0,0);
 lcd.print("LIVEL:110-150  Hl");
 if ((digitalRead(3)==HIGH)&&(livello>=4)){
 lcd.setCursor(0,1);
 lcd.print("  RIEMPIMENTO...");
 }
 else {
 lcd.setCursor(0,1);
 lcd.print("                ");
 digitalWrite(3,LOW);
 }
 }
if ((digitalRead(5)==HIGH)&&(digitalRead(6)==HIGH) && (digitalRead(7)==HIGH) && (digitalRead(8)==HIGH)){  // siamo al 100%
 digitalWrite(4,LOW); //ABILITO POMPA ASPIRANTE
 lcd.setCursor(0,0);
 lcd.print("LIVEL:   150  Hl");
lcd.setCursor(0,1);
 lcd.print("                ");
 digitalWrite(3,LOW);
 }
delay(1000);
}//end loop

Elenco componenti

R2         470 Ω ¼ W
R1,R3,R4,
R6-R9      10 KΩ ¼ W
R5,R10,R11 2,2 KΩ ¼ W
C7         1000uF 24V elettr.
C9         100uF 16V elettr.
C1,C2      22 pF poliestere
C3,C4,C8,
C10,C11    100 nF poliestere
U1         7805
U2         ATmega328p-pu
U3         PCF8574N
D1-D4      1N4007
D5,D6      1N4148
Q1         BC557 PNP
Q2,Q3      BC337NPN
XTAL       16 Mhz
TR1        Trasformatore 0-9v 700mA
GIOVANNI DI MARIA