Arduino: Sensore resistivo di umidità del terreno

Abbiamo visto nei precedenti post come rilevare l’umidità del terreno con micro:bit per controllare l’irrigazione di una pianta, vediamo ora una soluzione estremamente economica che può essere adottata con Arduino e che mostrerò nel dettaglio durante il mio prossimo corso sulla realizzazione dei laboratori green.

Il funzionamento del sensore di umidità del suolo è estremamente semplice.

La sonda a forma di forcella, con due conduttori esposti, agisce come un resistore variabile (come un potenziometro) la cui resistenza varia in base al contenuto di acqua nel terreno.

La resistenza è inversamente proporzionale all’umidità del suolo:

  • più acqua è presente nel terreno implica maggiore conduttività e quindi minore resistenza;
  • meno acqua è presente nel terreno implica minore conduttività e quindi maggiore resistenza.

Pertanto il sensore fornisce una tensione di uscita proporzionale alla resistenza misurata, in tal modo possiamo determinare il livello di umidità.

La sonda ha la forma di una forcella su cui sono disposte delle piste conduttive esposte. Le forcelle saranno da inserire all’interno del terreno o in qualsiasi altro elemento di cui bisogna misurare l’umidità.

La forcella viene connessa ad un modulo elettronico e quest’ultimo dovrà poi essere connesso ad Arduino. Il modulo fornirà una tensione di uscita proporzionale alla resistenza rilevata dalla sonda, questa tensione verrà resa disponibile ad un pin analogico di Arduino, nell’esempio che segue collegheremo la sonda al pin A0.

Nella foto si notano, sulla sinistra i due pin a cui collegheremo i pin di uscita della forcella e sulla destra quattro pin:

  • A0: uscita analogica
  • D0: uscita digitale
  • GND: ground
  • Vcc: tensione positiva di alimentazione (da 3,3V a 5V)

Il modulo è dotato di un potenziometro per la regolazione della sensibilità dell’output digitale (DO). Con il trimmer sarà possibile impostare la soglia di sensibilità, in modo tale che, quando il livello di umidità e al di sopra o al di sotto di un determinato valore, sul D0 vi sarà un segnale HIGH che potrebbe, ad esempio, attivare un relè che controlla l’avvio di una pompa di irrigazione.

Sulla scheda sono presenti inoltre un LED che segnala il funzionamento della scheda ed un LED che segnala lo stato del pin D0.

Rilevazione dell’umidità del terreno tramite l’uscita analogica

Questo sensore, così come il “water sensor” di cui ne abbiamo analizzato il funzionamento nella precedente lezione, è soggetto a deterioramento se esposto ad ambiente umido. L’alimentazione applicata alla sonda accelera l’ossidazione delle parti conduttive della forcella. Per evitare un rapido degrado è consigliabile fornire alimentazione solo quando bisogna effettuare la lettura.

Per fornire alimentazione alla scheda solo nel momento della lettura adottiamo la stessa strategia che abbiamo adottato per il “water sensor” il Vcc della scheda lo colleghiamo ad un pin digitale. Questa scelta non preclude un funzionamento non corretto della scheda in quanto la corrente massima assorbita dal sensore, anche nella situazione di accensione contemporanea dei LED, è di circa 8 mA, quindi ben al di sotto della corrente massima che può fornire il singolo pin digitale di Arduino.

Calibrazione

Anche per questo sensore bisogna procedere con la calibrazione.

E’ opportuno effettuare la calibrazione sul terreno su cui verrà poi inserito in via definitiva il sensore. Terreni diversi possono influenzare il funzionamento del sensore.
Quindi disponete in un vaso terreno secco ed in un altro ponete terreno saturo di umidità.

Utilizzate lo sketch che segue per verificare le misure in caso di terreno secco e di terreno umido:

1/* Prof. Maffucci Michele
2   Data: 12/03/2022
3   Rilevazione umidità del terreno - v01
4   (Utilizzo del pin analogico del sensore)
5 */
6 
7const byte alimentazioneSensore = 12;
8const byte pinSensore = A0;
9 
10void setup() {
11  // Impostiamo il pin digitale 12 come OUTPUT
12  pinMode(alimentazioneSensore, OUTPUT);
13   
14  // All'avvio impostiamo a LOW il +Vcc del sensore
15  digitalWrite(alimentazioneSensore, LOW);
16 
17  // impostiamo la velocità della porta seriale
18  Serial.begin(9600);
19}
20 
21void loop() {
22  // Lettura del sensore
23  Serial.print("Uscita analogica: ");
24  Serial.println(leggiSensore());
25  Serial.println("-----------------------------");
26  Serial.println();
27   
28  delay(3000);
29}
30 
31// Funzione che permette la lettura del livello di
32// umidità del terreno
33 
34int leggiSensore() {
35  digitalWrite(alimentazioneSensore, HIGH);    // attiva il sensore - viene fornita alimentazione
36  delay(50);                                   // breve attesa di 50 ms prima di effettuare la lettura
37  int valoreUmidita = analogRead(pinSensore);  // legge il valore e lo si memorizza nella variabile livelloLiquido
38  digitalWrite(alimentazioneSensore, LOW);     // togliamo alimentazione al sensore
39  return valoreUmidita;                        // invia alla funzione chiamante il valore letto
40}

Sul monitor seriale ho rilevato i seguenti valori:

Terreno secco: ~ 300
Terreno completamente bagnato: ~ 950

Sicuramente dovrete fare un po’ di test prima di ottenere valori sufficientemente stabili per stabilire i limiti di attivazione del vostro sistema di irrigazione.

Attenzione che potreste ottenere valori diversi dai miei, questi valori dipendono, come detto sopra, dal terreno e dalla quantità di sali discoli nell’acqua.

Basandovi sui valori di calibrazione sarete in grado di stabilire quando il terreno è secco, quando è sufficientemente umido e quando è eccessivamente umido.

Di seguito lo sketch che rileva il livello di umidità in funzione della calibrazione effettuata. Inviamo tutti i messaggi sulla serial monitor.

1/* Prof. Maffucci Michele
2   Data: 12/03/2022
3   Rilevazione umidità del terreno - v02
4   (Utilizzo del pin analogico del sensore)
5*/
6 
7const byte alimentazioneSensore = 12;
8const byte pinSensore = A0;
9 
10// cambiare i valori in in funzione della calibrazione
11 
12// Valore limite di terreno umido.
13// Valori inferiori indicano terreno troppo umido
14const int terrenoUmido = 300;
15 
16// Valore limite di terreno secco.
17// Valori superiori indicano terreno troppo secco
18const int terrenoSecco = 950;
19 
20void setup() {
21  // Impostiamo il pin digitale 12 come OUTPUT
22  pinMode(alimentazioneSensore, OUTPUT);
23 
24  // All'avvio impostiamo a LOW il +Vcc del sensore
25  digitalWrite(alimentazioneSensore, LOW);
26 
27  // impostiamo la velocità della porta seriale
28  Serial.begin(9600);
29}
30 
31void loop() {
32  // Lettura del sensore
33   
34  int umiditaTerreno = leggiSensore();
35  Serial.print("Uscita analogica: ");
36  Serial.println(umiditaTerreno);
37  Serial.println("-----------------------------");
38  Serial.println();
39  Serial.println("----- Stato del terreno -----");
40  Serial.println();
41   
42  // verifica livello umidità del terreno
43 
44  if (umiditaTerreno < terrenoUmido) {
45    Serial.println("    Terreno troppo umido");
46    Serial.println();
47  } else if (umiditaTerreno >= terrenoUmido && umiditaTerreno < terrenoSecco) {
48    Serial.println("-----------------------------");
49    Serial.println("Umidità del terreno ottimale");
50  } else {
51    Serial.println("    Terreno troppo secco");
52    Serial.println();
53  }
54  Serial.println("-----------------------------");
55  Serial.println();
56 
57  // Lettura ogni secondo
58  // Per evidare il degrado del sensore leggere il valore
59  // poche volte al giorno (1 o 2 volte al massimo)
60  // (Potrebbe essere opportuno utilizzare un RTC per regolare il tempo di lettura)
61 
62  delay(3000);
63}
64 
65// Funzione che permette la lettura del livello di
66// umidità del terreno
67 
68int leggiSensore() {
69  digitalWrite(alimentazioneSensore, HIGH);   // attiva il sensore - viene fornita alimentazione
70  delay(50);                                  // breve attesa di 50 ms prima di effettuare la lettura
71  int valoreUmidita = analogRead(pinSensore); // legge il valore e lo si memorizza nella variabile livelloLiquido
72  digitalWrite(alimentazioneSensore, LOW);    // togliamo alimentazione al sensore
73  return valoreUmidita;                       // invia alla funzione chiamante il valore letto
74}

Rilevazione dell’umidità tramite l’uscita digitale

Rimuoviamo la connessione del pin analogico ed utilizziamo il pin digitale della scheda. Per la realizzazione dello sketch si tenga conto che l’uscita della scheda sarà:

  • Terreno umido: uscita LOW – LED acceso
  • Terreno secco: uscita HIGH – LED spento

Per impostare la sensibilità inserite la sonda nel terreno umido, ruotate il potenziometro in senso orario in modo che il LED di stato si accenda, poi ruotate il potenziometro in senso antiorario fino a quando il LED si spegne, in questo modo avrete calibrato il sensore.

Attenzione, potreste notare che durante la calibrazione, nella situazione limite, passaggio da secco a umido il LED Status passi da una luminosità intensa ad una meno luminosa, non preoccupatevi è un comportamento normale.

1/* Prof. Maffucci Michele
2   Data: 12/03/2022
3   Rilevazione umidità del terreno - v03
4   (Utilizzo del pin digitale del sensore)
5*/
6 
7const byte alimentazioneSensore = 12;
8const byte pinSensore = 8;
9 
10void setup() {
11  // Impostiamo il pin digitale 12 come OUTPUT
12  pinMode(alimentazioneSensore, OUTPUT);
13 
14  // All'avvio impostiamo a LOW il +Vcc del sensore
15  digitalWrite(alimentazioneSensore, LOW);
16 
17  // Impostiamo il pin digitale 8 come OUTPUT
18  pinMode(pinSensore, INPUT);
19 
20  // impostiamo la velocità della porta seriale
21  Serial.begin(9600);
22}
23 
24void loop() {
25  // Lettura del sensore
26   
27  int umiditaTerreno = leggiSensore();
28  Serial.print("Uscita digitale: ");
29  Serial.println(umiditaTerreno);
30  Serial.println("-----------------------------");
31  Serial.println();
32  Serial.println("----- Stato del terreno -----");
33  Serial.println();
34 
35  // verifica livello umidità del terreno
36 
37  if (umiditaTerreno) {
38    Serial.println("Terreno troppo secco, irrigare!");
39    Serial.println();
40  } else {
41    Serial.println("Umidità del terreno ottimale");
42    Serial.println();
43  }
44  Serial.println("-----------------------------");
45  Serial.println();
46 
47  // Lettura ogni secondo
48  // Per evidare il degrado del sensore leggere il valore
49  // poche volte al giorno (1 o 2 volte al massimo)
50  // (Potrebbe essere opportuno utilizzare un RTC per regolare il tempo di lettura)
51 
52  delay(3000);
53}
54 
55// Funzione che permette la lettura del livello di
56// umidità del terreno.
57// Restituisce:
58// 0: umidità ottimale
59// 1: terreno poco umido
60 
61int leggiSensore() {
62  digitalWrite(alimentazioneSensore, HIGH);    // attiva il sensore - viene fornita alimentazione
63  delay(50);                                   // breve attesa di 50 ms prima di effettuare la lettura
64  int valoreUmidita = digitalRead(pinSensore); // legge il valore e lo si memorizza nella variabile livelloLiquido
65  digitalWrite(alimentazioneSensore, LOW);     // togliamo alimentazione al sensore
66  return valoreUmidita;                        // invia alla funzione chiamante il valore letto
67}

Buon Making green a tutti 🙂

2 pensieri su “Arduino: Sensore resistivo di umidità del terreno

  1. Umberto

    Buongiorno, vorrei creare un sensore di umidità del terreno senza l’utilizzo di una sonda, ma con un metodo a infrarossi. È possibile?

    Rispondi

Lascia un commento

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

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.