Cisterna Automatica INFO

Ragazzi ho trovato questo post e volevo chiedervi alcune informazioni in merito.

Da poco dei topi hanno distrutto l'impianto di un pozzo con pompa sommersa in casa mia, quindi forzatamente abbiamo dovuto cambiare tutto quanto considerando che la pompa e tutto il sistema è andato completamente bruciato. Avendo speso circa un migliaio di euro tra pompa, scheda, tubi, fili e chi più ne ha più ne metta, volevo approfittare per fare un lavoro apparte nella cisterna però. Ossia automatizzare l'accensione della pompa quando il livello della cisterna scende sotto un valore stabilito. Per farlo vorrei usare le vecchie sonde che ho recuperato dalla pompa e arduino. In pratica usarle come segnale per l'acqua e quando quella superiore va a secco accendere il relè al quale è collegato l'interruttore della pompa. Una cosa abbastanza semplice insomma. Volevo solo chiedervi che cosa ne pensate del codice semplice semplice che ho scritto e se avete qualche suggerimento a riguardo. L'accensione dura 15min impostata con delay. Vorrei avere un segnale di "pieno cisterna" però non so se sia il caso di utilizzare altre due sonde.

/*
  *********CISTERNA AUTOMATICA************
  Le sonde vengono immerse nella cisterna ad una distanza tra  loro stabilita arbitrariamente. La corrente 
  scorre da un elettrodo all'altro in presenza di acqua; quando la sonda superiore va a secco, e quindi il segnale letto da arduino è zero
  viene acceso il relè che automaticamente fa partire il pozzo e si inizia a riempire la cisterna per una durata di 15min (TEMPO VARIABILE).
 

 */

int sensorPin = A0;    // ingresso segnale sonde.
int start = 13;       // relè accensione pozzo.
int sensorValue;  // variable valore letto dalle sonde



void setup() {
  
  pinMode(start, OUTPUT); //imposto il pin del relè come uscita.
}

void loop() {
 
 sensorValue = analogRead(sensorPin); //leggo il valore delle sonde.

 
 if (sensorValue == 0)  //se il valore è zero e quindi il livello è basso...
                      {
                      digitalWrite(start, HIGH); //accendo il relè per riempire il pozzo
                      delay(900000); // durata di accensione pozzo 15min
                      digitalWrite(start, LOW); //finiti i 15min spengo il pozzo.
                      }
  
else                  //altrimenti il relè è spento.              
                      {
                      digitalWrite(start, LOW);  //relè rimane spento e il pozzo NON si accende.
                      }
  
  delay(1000);         //eseguo la lettura della sonda ogni 1000ms=1s.
}

Perchè ritieni che serva arduino (un microcontrollore) quando 2 sonde possono attivare 1 relè e spegnerlo?
Correndo anche il rischio che si inchiodi lasciando la pompa girare a vuoto e bruciarla...
Se è un problema di timer, ne esistono molti modulari per utilizzo industriale affidabili e a prezzi contenuti.
Se ci metti arduino ne spenderai altri 1000 un altr'anno.

Ciao, come hai fatto dovrebbe funzionare!..ci sono delle migliorie che potresti fare però…ti do qualche suggerimento:
quando il tuo programma entrerà nel ciclo if considerando la condizione Vera, tieni presente che quel ciclo durerà sempre quel tempo stabilito, anche se la sonda cambia stato! È questo che vuoi? Questo perché quando utilizzi la funzione delay è come se blocchi ingressi e uscite di Arduino…ovvero rimane paralizzato per tutto il tempo del delay mantenendo tutti gli stati com’erano l’istante prima di entrare nella funzione delay! Se non vuoi questo devi usare la funzione millis(). Ci sono post che spiegano come usarla :wink:

pablos:
Perchè ritieni che serva arduino (un microcontrollore) quando 2 sonde possono attivare 1 relè e spegnerlo?

Le sonde presumo che non siano con uscita a contatto NC, NO ma bensì analogica.. Quando c'è contatto con acqua la resistenza verso la carcassa della cisterna cambia, rispetto a quando non sarà a contatto con l'acqua...se non vuoi usare un micro, devi comunque fare un mini circuito analogico con comparatore e transistor per pilotare un relè..tenendo presente comunque al tempo che perdi per calcolo di resistenze e alla realizzazione del circuito (OK non complesso, ma devi saperlo fare)...con una board di Arduino diventa già tutto più configurabile con i moduli relè già pronti e le soglie di intervento le decidi via software cosi, facendo tutte le prove che vuoi :wink:

2 galleggianti a sfera di min e max e volendo uno intermedio te li tirano dietro, con questi raffreddiamo le turbine delle centrali di produzione energia dove l'unico modo per trovare acqua è attraverso lo scavo di pozzi, io sto solo indicando una soluzione semplice e affidabile nel tempo che offre una garanzia, poi liberi di complicarsi la vita...

Sistemi di controllo livello elettronici ad aste accoppiate sono stati installati con grande delusione e inefficienza.

Ciao, condivido Pablo, meglio un sistema semplice robusto ed affidabile per queste esigenze......

Ciao pablos,
La sonda non dovrebbe bruciarsi perché non continua ad andare a vuoto. Nel senso che la pompa, che sta nel pozzo ha le sue sonde e la sua scheda di controllo. Se nel pozzo non c'è più acqua da pompare nella cisterna le sonde lo rilevano e bloccano il funzionamento della pompa in automatico. Avresti ragione se lasciassi impostata la pompa in modalità manuale. In quel caso andrebbe a vuoto fino a bruciarla. Io infatti la pompa non la tocco prorpio per niente..:slight_smile: si tratta solo di evitare la scocciatura di guardare la cisterna e se vuota schiacciare l'interruttore. Per quanto riguarda invece il fatto cheil programma si inchiodi alla funzione delay per 15 min non penso sia un problema nel senso che la cisterna è da 8000l. Stavo pensando più che altro alla tensione con la quale alimentare le eventuali sonde.. (?) Basta una tensione bassa o bisogna salire un po di più visto e considerando il volume ingente di acqua.?

Per quanto riguarda un lavoro evitando arduino si si potrebbe fare, e risparmierei anche, però un domani vorrei implementare cose nuove, magari con uno schermo e un controllo a distanza che gestisca altri parametri come pH e quant'altro e allora.....

Poi comunque sinceramente mi viene più difficile e impiegherei più tempo a creare un sistema senza microcontrollore. Effettivamente si, mi sto complicano la vita ma nel mio caso, paradossalmente, la sto semplificando data la mia ignoranza in Materia...:confused:

Mi sta invece interessando l'utilizzo dei galleggianti a sfera.. forse sarebbe anche meglio delle sonde. Visto che costano anche una fesseria. Dite che possono essere anche alimentati direttamente da arduino? E che tipo di comando dovrei utilizzare nel codice per far si che la cisterna rimanga accesa fino a livello max?

Ah ok.....
Allora ho pensato agli ultrasuoni.....
Link

A sto punto se devi comprare materiale, compra una sonda di livello liquidi, cosi sai il livello della cisterna! E con quello ti regoli come vuoi...

I galleggianti a sfera danno dei contatti puliti NA/NC, quindi nei pin di INPUT

Consigli su quale sonda livello liquidi comprare.? E il meccanismo come risulta.. considerando che la capienza è di 8000l.?

Su eBay trovi sonde di livello per acque bianche e nere.. Ne ho trovate anche lunghe 70cm..senza parti in movimento...

Se no un'altro sistema potresti saldare un tubo nella parte più bassa della cisterna, portandolo però fino alla parte alta della cisterna. Per principio dei vasi comunicanti il livello che vedi fuori nel tubo è quello dentro la cisterna. Ora, se metti un trasduttore di pressione chiudendo questo tubo, avresti una corrispondenza tra pressione e livello di acqua nella cisterna! È il principio utilizzato nelle lavatrici, solo che quelli hanno solo contatto di uscita NC/NO. Forse le lavatrici moderne hanno pressostati analogici..

...o più facilmente immerge verticalmente un tubo tappato con il sensore di pressione :slight_smile:
....ripropongo la misura con gli ultrasuoni......

http://blog.elettronicain.it/2011/07/22/tidigino-contest-display-livello-cisterna-di-danilo-abbasciano/

Ragazzi ho ultimato il sistema per automatizzare il riempimento della cisterna; vorrei usare sia due sonde per attivare il relè che controlla l’accensione e lo spegnimento della pompa di aspirazione dell’acqua dal pozzo, sia degli ultrasuoni per indicare il livello della stessa mediante dei led (dovrei ordinare il “display” con tutti i led incorporati e di colori diversi, a segmenti). ; ora, lo sketch l’ho realizzato prendendo spunto da codici già fatti (copiandoli insomma:)). Ho un problema sul tempo di accensione del Relè; io uso la funzione delay() che cosi facendo però mi inchioda il codice a quel livello. Qualche anima pia saprebbe dirmi come usare la funzione millis per ovviare a questo problema?
Grazie.

I valori presenti nel codice vogliono ancora calcolati, sono di prova (da scrivania).

/*
  *********CISTERNA AUTOMATICA************
  Le sonde vengono immerse nella cisterna ad una distanza tra  loro stabilita arbitrariamente. La corrente 
  scorre da un elettrodo all'altro in presenza di acqua; quando la sonda superiore va a secco, e quindi il segnale letto da arduino è zero
  viene acceso il relè che automaticamente fa partire il pozzo e si inizia a riempire la cisterna per una durata di 15min. Un sensore di prossimità
  legge il livello segnandolo su dei led.
 

 */

int sensorPin = A0;    // ingresso segnale sonde.
int start = 13;       // relè accensione pozzo.
int sensorValue;     // variable valore letto dalle sonde
int ledRosso = 11;    // imposto l'uscita per il led di allarme e riempimento 
int ledVerde = 12;     // imposto l'uscita per il led di cisterna non vuota.

const int numOfReadings = 10;                   // numero di letture
int readings[numOfReadings];                    
int arrayIndex = 0;                             // contatore per ciclare nell'array
int total = 0;                                  
int averageDistance = 0;                        // distanza media

// inizializzo i PIN per collegare la scheda SFR05
int echoPin = 2;                                // echo (digital 2)

int initPin = 3;                                // trigger  (digital 3)
unsigned long pulseTime = 0;                    
unsigned long distance = 0;                     // distanza in cm
int pin5 = 4;
int pin4 = 5;
int pin3 = 6;
int pin2 = 7;
int pin1 = 8;
int buzzer = 13;

void setup() {
  
  pinMode(start, OUTPUT);        //imposto il pin del relè come uscita.
  pinMode(ledRosso, OUTPUT);     //imposto il pin del ledRosso come uscita.
  pinMode(ledVerde, OUTPUT);     //imposto il pin del ledVerde come uscita.
  pinMode(pin5, OUTPUT);
  pinMode(pin4, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin2, OUTPUT);
  pinMode(pin1, OUTPUT);
  pinMode(buzzer, OUTPUT);

    pinMode(initPin, OUTPUT);                     
    pinMode(echoPin, INPUT); 
    Serial.begin(9600);
  
  // inizializza un array delle letture
  for (int thisReading = 0; thisReading < numOfReadings; thisReading++) {
    readings[thisReading] = 0;
  }
  digitalWrite(pin5, HIGH); 
  digitalWrite(pin4, HIGH); 
  digitalWrite(pin3, HIGH); 
  digitalWrite(pin2, HIGH); 
  digitalWrite(pin1, HIGH); 
  digitalWrite(buzzer, LOW);
 

}

void loop() {
  //manda un impulso di ampiezza 10 us
  digitalWrite(initPin, HIGH);                    
  delayMicroseconds(10);                          
  digitalWrite(initPin, LOW);                     
  pulseTime = pulseIn(echoPin, HIGH);             // Aspetta l'eco di risposta
  distance = pulseTime/58;                        // Distance = tempo impulso / 58 per calcolare i [cm] di distanza.
  
 //Per diminuire l'errore crea un array con le letture e calcola la media
  total= total - readings[arrayIndex];            
  readings[arrayIndex] = distance;               
  total= total + readings[arrayIndex];            
  arrayIndex = arrayIndex + 1;                    
  
  if (arrayIndex >= numOfReadings)  {
      arrayIndex = 0;
  }
  averageDistance = total / numOfReadings;      //Media dei valori delle distanze acquisite

  Serial.println(averageDistance);
  if(averageDistance > 4){
    digitalWrite(pin5, LOW);
  }
  else{
    digitalWrite(pin5, HIGH);
  }

  if(averageDistance > 5){
    digitalWrite(pin4, LOW);
  }
    else{
       digitalWrite(pin4, HIGH);
    }
    
  if(averageDistance > 6){
     digitalWrite(pin3, LOW);
  }
  else{
     digitalWrite(pin3, HIGH);
  }
  if(averageDistance > 25){
     digitalWrite(pin2, LOW);
     digitalWrite(buzzer, HIGH);
     delay(250);
     digitalWrite(buzzer, LOW);
     delay(250);
     
  }
  else{
     digitalWrite(pin2, HIGH);
    
     digitalWrite(buzzer, LOW);
     

  
  }
  
 
 sensorValue = analogRead(sensorPin); //leggo il valore delle sonde.

 
 if (sensorValue > 30)  //se il valore è basso (rimane un minimo di conducibilità lungo il filo bagnato) 
                      {
                      digitalWrite(ledRosso, HIGH);    //accendo il ledRosso
                      digitalWrite(start, HIGH);      //accendo il relè per riempire il pozzo
                      delay(900000);                  // durata di accensione pozzo 15min
                      digitalWrite(start, LOW);       //finiti i 15min spengo il pozzo.
                      }
  
else                  //altrimenti il relè è spento.              
                      {
                      digitalWrite(start, LOW);            //relè rimane spento e il pozzo NON si accende.
                      digitalWrite(ledVerde, HIGH);        //accendo il ledVerde
                      digitalWrite(ledRosso, LOW);        //spengo il ledRosso
                      }
  
  delay(1);         //eseguo la lettura della sonda ogni 1000ms=1s.
}

Ciao, battezzi una variabile unsigned long delayRele ed una variabile boolean toggleRele=false;

if (sensorValue < 30 && toggleRele=false;) delayRele=millis();
if (sensorValue>30) toggleRele=true; 
if( toggleRele==true && millis()-delayRele <900000){
digitalWrite(start, LOW);
}else{
digitalWrite(start, HIGH); toggleRele=false;
}

Scritto al volo: verificalo!
Poi aggiungi anche i led… dovrebbe andare bene!

Stefano

Grazie mille..:slight_smile: tra non molto verifico..:slight_smile:

Ciao l'ho provato ma mi da errore; ho inserito le variabili come mi hai detto.
L'errore è il seguente:"

Cisterna_3.0:37: error: lvalue required as left operand of assignment
Cisterna_3.0.ino: In function 'void loop()':
Cisterna_3.0:129: error: lvalue required as left operand of assignment
Cisterna_3.0:129: error: expected ')' before ';' token
Cisterna_3.0:129: error: expected primary-expression before ')' token
Cisterna_3.0:129: error: expected ';' before ')' token
lvalue required as left operand of assignment

if (sensorValue < 30 && toggleRele=false) delayRele=millis();
if (sensorValue>30) toggleRele=true; 
if( toggleRele==true && (millis()-delayRele) <900000){
digitalWrite(start, LOW);
}else{
digitalWrite(start, HIGH); toggleRele=false;
}

E già, c’era un ; di troppo nella prima riga.
Ho anche aggiunto una parentesi!
Stefano

Niente da fare.:frowning: