Pluviometro con Arduino RKE05.2012

Un controllore per pluviometri

Questo articolo nasce durante uno dei pomeriggi più caldi dell’estate… quando la voglia di un po’ di refrigerio magari portato da un temporale è ai massimi livelli…e così, mentre si aspetta Giove pluvio, si ragiona e ci si interroga…

Il pluviometro

La pioggia è la forma più comune di precipitazione atmosferica e si misura in millimetri attraverso i pluviometri o pluviografi. In meteorologia solitamente 10 mm di pioggia equivalgono a 10 litri d’acqua caduti in un’ora su una superficie di 1 mq.

Lo strumento per misurare la pioggia è detto pluviometro ed è sempre uno strumento a “valore medio”, indicando la quantità di precipitazione in un lasso di tempo definito.

Due sono i metodi di misura comunemente impiegati:

  • quantità totale: è l’accumulo totale di precipitazione in un periodo temporale. Può essere ad esempio annuale dal 1 Gennaio al 31 Dicembre, oppure per gli agricoltori, l’annata agraria dal 1 Settembre al 31 Agosto
  • intensità del fenomeno cioè quanto “forte piove”: la pioggia caduta viene misurata in millimetri su un arco di tempo specificato. Alla misura di x millimetri di pioggia corrisponde la caduta di x litri d’acqua piovana, equivalenti a x decimetri cubi, su una superficie di 1 metro quadro.

Secondo gli studiosi della materia è possibile catalogare le precipitazioni come segue:

  • Pioviggine (< 1 mm ogni ora)
  • Pioggia debole (1-2 mm/h)
  • Pioggia moderata (2-6 mm/h)
  • Pioggia forte (> 6 mm/h)
  • Rovescio (> 10 mm/h ma limitato nella durata)
  • Nubifragio (> 30 mm/h)

La stazione pluviometrica amatoriale

Come anticipato, lo strumento che ne permette la misurazione è il pluviometro, una volta ad appannaggio dei soli “addetti ai lavori”, è da anni disponibile a costi molto contenuti anche ai semplici appassionati e curiosi.

Lo strumento si compone in genere di due parti: un sensore da porre all’esterno a raccogliere la pioggia ed una unità di visualizzazione digitale che ci indica in vari modi quanto piove.

Il sistema commerciale è di per sé molto piacevole, ma risulta “chiuso” nel momento si desiderasse visualizzare od impiegare l’informazione pluviometrica in altro modo o sistema. Sarebbe quindi utile poter disporre dell’informazione su una linea analogica o dati.

Per cercare il modo di “esportare” la lettura, vediamo anzitutto come è realizzata l’unità di misura (quella che mettiamo all’esterno).

La quasi totalità dei sensori pluviometri disponibili al mercato amatoriale è costituita da una sezione ad imbuto che ha lo scopo di raccogliere l’acqua piovana e portarla ad un dispositivo di misurazione. Il sistema, detto a doppia vasca oscillante o basculante, ha un equilibrio che varia a seconda della quantità d’acqua contenuta nelle vaschette.

Man mano che il recipiente posto in quel momento sotto l’imbuto si riempie, il baricentro del sistema basculante si sposta. Una volta raggiunto un certo grado di riempimento la vaschetta si ribalta: sotto l’imbuto arriva la vaschetta vuota, mentre quella piena si svuota rapidamente. Durante la transizione, viene chiuso (per alcune decine di millisecondi in genere), un contatto elettrico (reed, sensore hall, etc.) il cui segnale, inviato all’unità interna, permette il calcolo e la visualizzazione della precipitazione in corso. Quanto più forte è la pioggia quindi, tanto più elevata sarà la frequenza degli impulsi in uscita dal sensore, come illustrato di seguito:

sensore_pluvio_bascula_fmt

schema di principio pluviometro a doppia vasca basculante

sensore_pluvio_org_fmt

Dipendenza della frequenza degli impulsi dall’intensità della pioggia

tantapioggia-pocapioggi_fmt

Volendo quindi trasformare il segnale del pluviometro ad esempio in una tensione per avere una indicazione analogica su uno strumentino, oppure registrarlo con un data-logger magari assieme ad altre grandezze, pare che il compito possa essere banalmente assolto realizzando un comune convertitore frequenza-tensione.

Se in linea teorica questo corrisponde al vero, i problemi nascono nel momento in cui si considerino le grandezze in gioco.

Un pluviometro medio amatoriale infatti, ribalta la vaschetta (quindi eroga un impulso) solo ogni alcune decine di secondi quanto investito da un vero nubifragio. Nei casi più comuni di precipitazione, dovremo attendere vari minuti fra un impulso ed il successivo. Parliamo quindi di frequenze nell’ordine dei mHz che, verosimilmente, nessun convertitore F-V analogico potrà mai gestire.

Occorre quindi abbandonare la soluzione classica, analogica, ed intraprendere un nuovo approccio al problema, senza perdere di vista la semplicità realizzativa e la flessibilità.

La soluzione proposta

Dovendo per i motivi sopra esposti trovare una soluzione semplice, flessibile, economica e non analogica, una possibilità viene dall’impiego del noto sistema open-source Arduino.

Di questo fantastico prodotto esistono molte versioni, per questo progetto non occorre nulla di particolare e quella già in casa o a miglior prezzo può divenire una ottima base di partenza.

Nel mio caso, l’idea è stata sviluppata su un Arduino Uno, in previsione anche di importanti sviluppi futuri del sistema.

La configurazione HW

Arduino Uno viene collegato come descritto nello schema qui a fianco:

Il sensore pioggia è collegato fra massa e l’ingresso digitale n°2. Una resistenza di pull-up mantiene l’ingresso a livello alto fra un impulso di ribaltamento ed il successivo. Nel caso il circuito sia collegato in parallelo all’originale unità di lettura, occorrerà probabilmente rimuovere la resistenza di pull-up (non più necessaria) e verificare i livelli, assicurandosi che lo stato “alto” sia significativamente maggiore di 3V.

L’uscita è il pin9, un PWM (pulse width modulation) a frequenza fissa di 1 kHz, il cui livello medio varierà proporzionalmente all’attività di Giove pluvio. Se collegato direttamente ad un piccolo voltmetro analogico, lo stesso colla sua inerzia provvederà ad indicare il valore medio del segnale. Nel caso invece l’uscita andasse collegata ad altro dispositivo non in grado di “mediare”, è opportuno inserire un filtro integratore RC (passo basso) con valori nell’ordine di 5-10kOhm e 220-470nF.

Il codice

Piuttosto che descrivere approfonditamente il programma sviluppato e visibile qui a fianco, credo più interessante vedere e commentare l’algoritmo di misura e conversione messo a punto.

La caratteristica un po’ particolare di questo sistema è che l’informazione che il sensore comunica non è continua ma aggiornata solo al verificarsi di un preciso evento, nel nostro caso il ribaltamento della bascula. Ovviamente non è possibile conoscere ciò che accade fra un evento ed il successivo né tantomeno possiamo sapere quando si verificherà il prossimo aggiornamento.

Vediamo quindi l’algoritmo pensato:

dopo una prima sezione di inizializzazione delle porte del micro, della comunicazione seriale e delle variabili usate, il programma avvia un loop senza fine all’interno del quale “cerca” il fronte di discesa del segnale del pluviometro, indice dell’avvenuta commutazione. Quando detto evento è rilevato, viene comunicato all’operatore con un messaggio specifico sulla seriale e accendendo per 1” il led sulla board di Arduino; segue il calcolo del valore aggiornato di intensità di pioggia, che è bene ricordare, è il valor medio dell’intensità nel periodo di tempo compreso fra l’ultima e la penultima commutazione.

Il valore viene trasmesso sulla seriale e usato per impostare il PWM conseguentemente. Detta così, la soluzione sembra logica e semplice ma.. se rimanessimo in passiva attesa del prossimo fronte di discesa e la pioggia cessasse di colpo (classico dei temporali!), l’algoritmo, non aggiornando più i calcoli, perpetuerebbe il settaggio della porta di uscita dando così l’impressione di una pioggia costante e senza fine!

parallelo algoritmi_fmt

Quindi?

Ecco la soluzione! Ad ogni “giro del loop” di ricerca del fronte, ricalcolo sempre il valore di pioggia come se avessi trovato un fronte. Così operando, al trascorrere del tempo in assenza di “nuove informazioni” da parte del pluviometro, il valore della lettura cala asintoticamente verso lo zero e dando conto correttamente della pioggia media dall’ultima lettura valida. È chiaro che operando in questo modo, nei primi istanti dopo una misura valida, occorre saturare il calcolo all’ultimo valore corretto.

Una dimostrazione grafica e qualitativa del diverso funzionamento delle versioni “base” e “evoluta” dell’algoritmo è riportata in figura a fianco:

configurazioneHW_fmt

/*

programma per convertire il pluviometro in tensione, con fondo scala di 5V=10mm/ora

1mm/ora=2670” di periodo del pluviometro

ingresso sensore sul Pin 2 digitale

uscita pwm proporzionale a pioggia: pin 9

il led pin 13 lampeggia ad ogni commutazione del pluviometro

*/

//dichiarazioni costanti

const float pluvio_k=2670000; //cost. calibr. pluviomentro pari a periodo per 1mm/ora, in msec!

const int ledPin = 13; // the number of the LED pin

// dichiarazione variabili

int sensorValue_old=0; //init a 0 del vecchio valore del sens. rain

unsigned long millis_old=0; //init a 0 del primo valore di millis_old

unsigned long rain_per; //variabile contiente periodo pluviometro, time in msec

unsigned long rain_per_last=2670; //periodo ultima misura pioggia, init a 10mm/ora

float rain_raw; //pioggia in mm/ora

float rain; //pioggia saturata fra 0,1 e 10mm/ora

int ledState = LOW; // ledState used to set the LED

long previousMillis = 0; // will store last time LED was updated

long interval = 5000; // interval at which to update serial (milliseconds)

int PWM_rain;

float Volt_pwm;

void setup() {

Serial.begin(9600); // init seriale

pinMode(2, INPUT); //ingresso sensore pioggia

pinMode(9, OUTPUT); //uscita pwm sul pin 9

pinMode(ledPin, OUTPUT); //attivo il led su PCB come monitor attività

}

void loop() {

int sensorValue = digitalRead(2); //leggo valore stato sens. rain

unsigned long millis_current=millis(); //leggo tempo corrente in msec dall’avvio

if (sensorValue<sensorValue_old) {

Serial.println(“ho visto transizione 1->0 \n”); //se il livello è andato da 1 a 0, allora…

rain_per_last=rain_per=millis_current-millis_old; //store periodo ultima misura certa

millis_old=millis_current; //azzero contatore del periodo pluviometro

ledState = HIGH;

digitalWrite(ledPin, ledState);

delay(1000);

ledState = LOW;

digitalWrite(ledPin, ledState);

}

sensorValue_old=sensorValue;

rain_per=millis_current-millis_old;

if (rain_per < rain_per_last) rain_per=rain_per_last;

if (rain_per>26700000) rain_per=26700000; //se pioggia <0,1mm/ora, allora pioggia minima 0,1mm/ora

rain_raw=pluvio_k/rain_per;

rain=rain_raw;

if (rain_raw>10) rain=10;

PWM_rain=rain*25,50;

Volt_pwm= rain/2,0; //valore in volt dell’uscita PWM filtrata

analogWrite(9, PWM_rain);

unsigned long currentMillis = millis();

if(currentMillis – previousMillis > interval) {

// save the last time you blinked the LED

previousMillis = currentMillis;

Serial.print(“\n dati aggiornati \n”);

Serial.print(“\t sensorValue=”);

Serial.println(sensorValue, DEC);

Serial.print(“\t rain_per=”);

Serial.println(rain_per, DEC);

Serial.print(“\t rain_raw,mm/ora=”);

Serial.println(rain_raw, DEC);

Serial.print(“\t rain,mm/ora=”);

Serial.println(rain, DEC);

Serial.print(“\t PWM_rain=”);

Serial.println(PWM_rain, DEC);

Serial.print(“\t Volt_pwm=”);

Serial.println(Volt_pwm, DEC);

Serial.println(millis_current, DEC);

Serial.println(millis_old, DEC);

}

}

Configurazione proposta

screen_out_fmt

La calibrazione

Per eseguire una misura corretta, occorre inserire nel codice un valore che indica il periodo fra due commutazioni della bascula quando l’intensità della pioggia sia di 1mm.

Se abbiamo fortuna, il dato è fornito dal costruttore del sensore, ma più frequentemente, specie nei modelli economici, occorrerà determinarlo sperimentalmente, ma per buona sorte, l’operazione è abbastanza semplice.

Prendiamo il nostro sensore e mettiamoci nella condizione di poter misurare il numero delle commutazioni, magari con un tester, una piccola lampadina, un contatore elettronico, un cicalino.. quello che volete, purché sia comodo ed efficace.

Prendiamo anche una quantità nota d’acqua, ad esempio 500ml e molto lentamente la versiamo nell’imbuto del pluviometro. Mentre versiamo, contiamo i ribaltamenti della vaschetta.. Poniamo ad esempio che 100g di acqua versata, provochino 20 “bip”, equivalenti a 5g di pioggia raccolta ad ogni ribaltamento della bascula. Tanto più elevati sono i valori di acqua versata e commutazioni, tanto più preciso sarà il calcolo.

Con un metro misuriamo la “bocca” del sensore, ad esempio 125x54mm. Moltiplicando le due quote, calcoliamo l’area di raccolta che risulta in questo caso pari a 0,00675m2, cioè un 1/148 di metro quadro.

Moltiplicando ora 148 per 5 ottengo il valore di 741 che esprime i grammi di pioggia per m2 che fanno riempire una vaschetta.

Moltiplicando ancora questo valore per 3,6 si ottiene il tempo (in secondi) fra due commutazioni in presenza di una pioggia di 1mm/ora. Nel caso di questo esempio, il risultato è 2670 (pari ad una frequenza di 374μHz!!). Detto valore va riportato nel codice dell’algoritmo (pluvio_K) per la dovuta messa in scala della misura.

Conclusioni

In questo articolo si sono esplorati vari ambiti della scienza, dalla meteorologia alla programmazione di un microcontrollore. Un piacevole viaggio fra vari campi della tecnica, senza pretese di perfezione (specie il codice, che sicuramente può essere riscritto più “elegantemente”) ma con l’obiettivo di imparare e di riflettere sulla scelta delle soluzioni software ed hardware.

Non mi resta che augurare a tutti un po’ di pioggia per sperimentare e migliorare il lavoro!

Bibliografia

www.arduino.cc

www.lacrosse-psmall.com

it.wikipedia.org/wiki/Pluviometro

it.wikipedia.org/wiki/Pioggia

Add a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.