Arduino: water sensor

Per le attività in programma per il corso sui laboratori green, spiegherò come controllare il livello d’acqua in una cisterna utilizzata per l’irrigazione. A livello prototipale svolgerò prima sperimentazioni su singola pianta utilizzando il “water sensor” che potete acquistare per pochi centesimi online. In una fase successiva impiegherò dei sensori di livello che vengono comunemente impiegati in cisterne e controlleremo il riempimento e lo svuotamento della cisterna.

Il “water sensor” misura il livello di conduttività elettrica del liquido, conduttività che sarà funzione della quantità di superficie del sensore immerso.
Nell’acqua ed in generale nei liquidi, il passaggio di corrente è dovuto alla presenza di sali, infatti l’acqua pura non risulta conduttiva.
Le piste parallele di rame presenti sul sensore sono connesse al potenziale positivo e al GND, quando il sensore viene immerso nel liquido viene misurata una differenza di potenziale tra i due poli, d.d.p. che dipenderà dalla quantità di superficie immersa, pertanto al variare della quantità d’acqua varierà il valore di resistenza tra i due potenziali.

Sottolineo che il sensore non è preciso e richiede una taratura iniziale che dipende prevalentemente dall’acqua, inoltre sensori diversi potrebbero fornirvi misure diverse.

Il segnale di uscita del sensore (pin S) verrà inviato su un pin analogico di Arduino e da esso convertito in un valore numerico che oscillerà tra ~ 0 e ~500, pertanto se il sensore non è immerso il valore misurato sarà di circa 0, mentre se sarà totalmente immerso raggiungerà il valore massimo rilevato.

Sul sensore sono presenti 10 piste di rame parallele, connesse in modo alternato, in modo che vi siano 5 piste connesse ad un potenziale alto e 5 piste connesse a GND. E’ presente inoltre un LED che indica quando il sensore viene alimentato.

  • S (Signal): uscita analogica da connettere ad un ingresso analogico di Arduino
  • +Vcc: potenziale positivo dell’alimentazione. Si consiglia di alimentare il sensore con una tensione compresa tra 3,3 V e 5V. Si ricorda che l’uscita analogica del sensore varierà in funzione della tensione di alimentazione del sensore.
  • – : da connettere al GND

Attenzione che il sensore non è progettato per essere completamente immerso, fate in modo che solo le tracce ramate parallele esposte sul PCB vengano a contatto con l’acqua.

Connessione del sensore e calibrazione

Come indicato ad inizio lezione, uno dei problemi maggiori di questi dispositivi è la loro breve durata di vita dovuta all’ossidazione delle parti esposte ad un ambiente umido.
Un’alimentazione continua al sensore accelera l’ossidazione dei terminali. Per ridurre il degrado del sensore è consigliabile non alimentare costantemente il sensore, quindi l’alimentazione viene fornita solamente quando bisogna effettuare la lettura.

La modalità più semplice è quella di connettere il pin +Vcc del sensore ad un pin digitale di Arduino a porlo ad HIGH quando vogliamo effettuare la lettura e porlo a LOW quando non effettuiamo la lettura.

Colleghiamo il +Vcc del sensore al pin digitale 12 di Arduino e il Pin S (Segnale) al pin analogico A0 di Arduino.

// Prof. Maffucci Michele
// Data: 09/03/2022
// Rilevazione livello liquido - v01

// pin sensore
#define alimentazioneSensore 12
#define lettura A0

// livelloLiquidoue per memorizzare il livello dell'acqua
int livelloLiquido = 0;

void setup() {
  // Impostiamo il pin digitale 12 come OUTPUT
  pinMode(alimentazioneSensore, OUTPUT);
  
  // Impostiamo a LOW il +Vcc del sensore
  digitalWrite(alimentazioneSensore, LOW);

  // impostiamo la velocità della porta seriale
  Serial.begin(9600);
}

void loop() {
  // rileviamo la lettura del sensore
  int livello = leggiSensore();
  
  Serial.print("Livello acqua: ");
  Serial.println(livello);
  
  delay(1000);
}

// Funzione che permette la lettura del livello dell'acqua
int leggiSensore() {
  digitalWrite(alimentazioneSensore, HIGH);  // Attiva il sensore - viene fornita alimentazione
  delay(50);                                 // breve attesa di 50 ms prima di effettuare la lettura
  livelloLiquido = analogRead(lettura);      // Legge il valore e lo si memorizza nella variabile livelloLiquido
  digitalWrite(alimentazioneSensore, LOW);   // Togliamo alimentazione al sensore
  return livelloLiquido;                     // invia alla funzione chiamante il valore letto
}

Dalla Serial Monitor leggiamo i valori rilevati e nel mio caso rilevo che il valore 0 indica non immersione, valori tra 400 e 410, parziale immersione e valori prossimi a 450 o superiori indicano una completa immersione.

Come detto ad inizio di questa lezione, l’acqua pura non è conduttiva, la conduttività dipende dai sali immersi nell’acqua, quindi è buona norma procedere prima con una calibrazione del sensore con l’acqua il cui livello intendete monitorare.

Con lo sketch mostrato sopra annotate i valori quando il sensore non è immerso, quando è parzialmente immerso e quando è completamente immerso.

0: sensore non a contatto con l’acqua
~ 410: parzialmente immerso
~ 460: completamente immerso

E’ essenziale che la calibrazione venga fatta mantenendo ben fisso il sensore e attendendo che i valori letti si stabilizzino, questa operazione richiede qualche minuto.

Quando avete annotato i valori che corrispondono alle tre situazioni possiamo procedere con l’utilizzo del sensore in altri progetti.

Realizziamo ora un progetto in cui con tre LED si vogliono indicare le tre situazioni: vuoto, metà, pieno.

// Prof. Maffucci Michele
// Data: 09/03/2022
// Rilevazione livello liquido - v02

// pin sensore
#define alimentazioneSensore 12
#define lettura A0

// livelloLiquidoue per memorizzare il livello dell'acqua
int livelloLiquido = 0;

// Limite inferiore e superiore ottenuti in funzione della calibrazione
int limiteInferiore = 410;
int limiteSuperiore = 450;

// Dichiarazione pin a cui connettiamo il LED
byte ledRosso  = 11;
byte ledGiallo = 10;
byte ledVerde  = 9;

void setup() {
  // Impostiamo il pin digitale 12 come OUTPUT
  pinMode(alimentazioneSensore, OUTPUT);
  
  // Impostiamo a LOW il +Vcc del sensore
  digitalWrite(alimentazioneSensore, LOW);

  // Impostiamo i pi a cui connettiamo i LED come OUTPUT
  pinMode(ledRosso, OUTPUT);
  pinMode(ledGiallo, OUTPUT);
  pinMode(ledVerde, OUTPUT);

  // impostiamo la velocità della porta seriale
  Serial.begin(9600);
}

void loop() {
  // rileviamo la lettura del sensore
  int livello = leggiSensore();

  if (livello == 0) {
    
    Serial.println("Livello acqua: Vuoto");
    Serial.print("Livello acqua: ");
    Serial.println(livello);
    Serial.println("--------------------");
    
    digitalWrite(ledRosso, LOW);
    digitalWrite(ledGiallo, LOW);
    digitalWrite(ledVerde, LOW);
  }
  else if (livello > 0 && livello <= limiteInferiore) {
    Serial.println("Livello acqua: Basso");
    Serial.print("Livello acqua: ");
    Serial.println(livello);
    Serial.println("--------------------");
    
    digitalWrite(ledRosso, HIGH);
    digitalWrite(ledGiallo, LOW);
    digitalWrite(ledVerde, LOW);
  }
  else if (livello > limiteInferiore && livello <= limiteSuperiore) {
    Serial.println("Livello acqua: Medio");
    Serial.print("Livello acqua: ");
    Serial.println(livello);
    Serial.println("--------------------");
    
    digitalWrite(ledRosso, LOW);
    digitalWrite(ledGiallo, HIGH);
    digitalWrite(ledVerde, LOW);
  }
  else if (livello > limiteSuperiore) {
    Serial.println("Livello acqua: Medio");
    Serial.print("Livello acqua: ");
    Serial.println(livello);
    Serial.println("--------------------");
    
    digitalWrite(ledRosso, LOW);
    digitalWrite(ledGiallo, LOW);
    digitalWrite(ledVerde, HIGH);
  }
  delay(1000);
}

// Funzione che permette la lettura del livello dell'acqua
int leggiSensore() {
  digitalWrite(alimentazioneSensore, HIGH);  // Attiva il sensore - viene fornita alimentazione
  delay(50);                                 // breve attesa di 50 ms prima di effettuare la lettura
  livelloLiquido = analogRead(lettura);      // Legge il valore e lo si memorizza nella variabile livelloLiquido
  digitalWrite(alimentazioneSensore, LOW);   // Togliamo alimentazione al sensore
  return livelloLiquido;                     // invia alla funzione chiamante il valore letto
}

Esercizi per i miei studenti e per i colleghi iscritti al corso edugreen

Esercizio 01

Realizziamo ora uno sketch che stampa sulla serial monitor il livello del liquido nel contenitore espresso in percentuale.

Esercizio 02

Ripetiamo le medesime funzionalità dello sketch precedente, ma in questo caso mostriamo la percentuale su un display 16×2 I2C

Esercizio 03

All’esercizio precedente aggiungere un buzzer che emette un suono quando viene superato il livello massimo.

Buon Making a tutti 🙂

2 pensieri su “Arduino: water sensor

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

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