Qualche settimana fa mi ha scritto Giordano, un appassionato makers, e autore di un pluviometro arduino che ha voluto condividere con tutti noi appassionati il suo progetto.
Giordano oltre al pluviometro arduino ha realizzato un vero e proprio articolo in merito, dopo la mia segnalazione di non essere affatto esperto di questa materia e voglio condividerlo così come lo ha scritto lui, farò solo copia e incolla.
Il progetto pluviometro arduino
In questo progetto utilizzeremo Arduino per gestire e memorizzare la pluviometria.
I dati relativi alla pioggia verranno memorizzati un una microSD in formato CSV, pronti per essere direttamente visualizzati su Excel.
Tramite l’ausilio della ethernet shield, se Arduino è connesso alla tua LAN, potrai visualizzare i dati con un comune browser.
Componenti del pluviometro arduino
I componenti necessari per il progetto sono:
- Arduino Uno
- Ethernet Shield
- RTC shield
- Comune pluviometro a bascula
- 1 resistenza da 10Kohm
- 1 condensatore da 0,1uF
Principio di funzionamento
La bascula che segna la pluviometria che vedi nella prima foto è soltanto un pezzo di un pluviometro arduino.
Il pluviometro completo comprende un cilindro all’interno del quale è posizionato un imbuto, con il quale l’acqua piovana viene convogliata sulla bascula.
Il cucchiaio, che caratterizza la bascula, contiene 0,2mm di acqua piovana, oltrepassati i quali il peso della stessa fa inclinare il cucchiaio che vuota il contenuto.
Il principio di funzionamento è abbastanza semplice: ogni qualvolta il cucchiaio esegue una “basculata” (oscillazione con acqua a perdere), il pluviometro arduino conteggia 0,2mm tramite l’ingresso interrupt 0 (pin 2 arduino).
Schema elettrico del pluviometro arduino
Nello schema che segue nota l’introduzione di una resistenza ed un condensatore.
Essi servono per creare un ritardo al contatto, affinché una singola basculata non venga conteggiata più volte.
I componenti che ti occorrono per realizzare il circuito sono:
- R=10Kohm
- C=0,1uF
Quando il sistema si avvia, il condensatore si carica e sul pin 2 di Arduino ci sono 5V.
Quando il pluviometro bascula il condensatore si scarica portando per un istante basso il pin 2. Successivamente il condensatore si ricarica con un tempo pari a 5 τ ( tau costante di carica/scarica di un condensatore ) seguendo la formula:
τ = R*C=10000ohm * 0,1*10^-6F=0,001s
5 τ = 0,005s
Sketch del pluviometro arduino
#include <SPI.h> #include <SD.h> #include <Wire.h> #include "RTClib.h" #include <Ethernet.h> RTC_DS1307 RTC; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte ip[] = { 192,168,1, 130 }; EthernetServer server(80); //imposta il server a rispondere sulla porta 80 float TotPioggia; String strNow; boolean blnWrite=false; void setup(){ Serial.begin(9600); Serial.println("Start"); Wire.begin(); //inizializzo libreria per protocollo I2C RTC.begin(); //inizializzo libreria RTC RTC.sqw(1); //0 Led off - 1 Freq 1Hz - 2 Freq 4096kHz - 3 Freq 8192kHz - 4 Freq 32768kHz if (! RTC.isrunning()) { Serial.println("RTC is not running!"); RTC.adjust(DateTime(__DATE__, __TIME__)); //imposta RTC con orario del pc } //attivo interrupt 0 dove si passa da 5V a 0V quando il pluvio bascula attachInterrupt(0, Basculata, FALLING); //LOW CHANGE RISING FALLING Ethernet.begin(mac, ip); server.begin(); Serial.print("Server is at "); Serial.println(Ethernet.localIP()); if (!SD.begin(4)) { Serial.println("Card failed, or not present"); return; } Serial.println("Card initialized."); } void loop(){ String strTmp; DateTime now = RTC.now(); strTmp=""; strTmp=strTmp+now.day() + "/"; strTmp=strTmp+now.month() + "/"; strTmp=strTmp+now.year() + " "; strTmp=strTmp+now.hour() + ":"; strTmp=strTmp+now.minute() + ":"; strTmp=strTmp+now.second(); strNow=strTmp; Serial.println(strNow); EthernetClient client = server.available(); if (client) { //verifico esistenza connessione da parte di un client boolean currentLineIsBlank = true; while (client.connected()) { //ciclo fino a che la connessione del client è attiva if (client.available()) { //verifico sempre che il client comunichi con il server char c = client.read(); //leggo dal client la richiesta della pagina if (c == '\n' && currentLineIsBlank) { //se la richiesta è un car di linea nuova inizio comunicazione con il client client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<h2>Arduino: Dati acquisiti di Pluviometria:</h2>"); File htmlFile = SD.open("rain.csv"); if (htmlFile) { while (htmlFile.available()) { client.write(htmlFile.read()); } // close the file: htmlFile.close(); } client.println("</html>"); break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { //se ricevo dal client un carriage return currentLineIsBlank = false; } } } delay(1); client.stop(); } interrupts(); delay(1000); //se è avvenuto un interrupt, quindi una basculata, vado a scrivere sulla microSD if (blnWrite==1) { Serial.println("il momento di scrivere"); blnWrite=false; //scrivo su file File dataFile = SD.open("rain.csv", FILE_WRITE); if (dataFile) { dataFile.println(strNow + ";0,2;mm;<br/>"); dataFile.close(); } else { Serial.println("errore apertura file"); } } } void Basculata(){ noInterrupts(); TotPioggia=TotPioggia+0.2; //conta la pioggia Serial.println(strNow); Serial.println(TotPioggia); blnWrite=true; //segnalo che è avvenuta una basculata }
Ed ecco la descrizione dello sketch proposta da Giordano del suo pluviometro arduino:
linee 1-5: implementazione librerie necessarie al progetto;
linea 7: creazione oggetto RTC;
linee 9-11: dichiarazioni necessarie per utilizzare la parte di rete;
linee 18-19: inizializzazione comunicazione seriale;
linea 21:inizializzazione libreria per I2C;
linee 22-27: inizializzazione RTC;
linea 29: attivazione interrupt 0. Come mostrato nel grafico sotto allo schema elettrico, dobbiamo utilizzare il fronte di discesa dell’interrupt, poiché il pulsante porta a massa la scarica del condensatore. Per utilizzare questa funzionalità occorre che l’interrupt funzioni in FALLING, ossia che venga scaturito quando si passa dai 5V a 0V (soglie teoriche);
linee 31-34:inizializzazione connessione ethernet;
linee 36-40:inizializzazione sd card;
linee 44-54: lettura dell’orario dall’RTC, che viene preparato componendo a step la stringa strTmp. Solo al termine viene aggiornata la variabile globale strNow. Spiego di seguito il perché. La routine di interrupt che vedremo, può scaturire in qualsiasi momento, poiché è insito nel comportamento di tale funzionalità ed anche della pluviometria. All’interno di tale routine viene utilizzata la stringa di ora globale strNow. Pertanto potrebbe essere utilizzata in un istante durante il quale la loop() stà ancora eseguendo la lettura. Di conseguenza si andrebbe ad utilizzare una variabile ancora incompleta ed errata. Nella riga 53, mediante una sola istruzione, limitiamo che avvenga il fenomeno;
linee 56-92: parte di gestione della richiesta via ethernet. Se giunge una richiesta dalla rete all’indirizzo IP del nostro Arduino, verrà spedito il file csv scritto dall’applicativo per memorizzare la pluviometria;
linea 93: riattivazione interrupt. Un altro metodo per evitare che vengano scaturiti interrupt multipli, è quello di disattivare l’interrupt non appena viene scaturito. Solo nel loop() immediatamente successivo (qualche msec) verrà ripristinato;
linee 97-109: se il flag blnWrite è true, significa che è avvenuto un interrupt e quindi una basculata da parte del pluviometro. In tal caso vado a scrivere nella microSD una stringa preparata. In tale stringa viene messa la dataora prelevata dall’RTC seguita dai mm piovuti (il nostro “cucchiaio” del pluviometro contiene 0,2mm tutte le volte che bascula, cioè quando si inclina per vuotare via l’acqua contenuta all’interno). Viene anche aggiunto il carattere br, per consentire una corretta consultazione anche tramite browser;
linea 112:routine scaturita dall’interrupt;
linea 113:disattivazione interrupt;
linea 114: aggiornamento della variabile che contiene il cumulato della pioggia;
linee 116-117: stampa a video di informazioni di debug;
linee 119: segnalo tramite opportuno flag che è avvenuta una basculata;
Risultato in formato Excel
Di seguito il file in formato csv caricato in Excel leggendolo dalla scheda SD opportunamente estratta dal pluviometro arduino:
Risultato attraverso il browser
Il risultato collegandoti con il tuo browser all’indirizzo del pluviometro:
Buona misurazione !!!
18 commenti
Vai al modulo dei commenti
Gracias por compartir sus proyectos. Compile algunos de sus proyectos y hay una variable que siempre tengo que anular para que se ejecuten los mismos es la siguiente // RTC.sqw(1); //0 Led off – 1 Freq 1Hz – 2 Freq 4096kHz – 3 Freq 8192kHz – 4 Freq 32768kHz.
No se porque la misma no compila? Gracias espero su respuesta. atte, LM
Autore
Hola LM,
usted tiene que usar la biblioteca RTClib cambiado por el fabricante de la pantalla en la que se añadió RTC.sqw no está presente en la biblioteca original.
Puede omitir esta línea si no te importa encender los LEDs en el escudo.
Mauro
ciao dove posso trovare un pluviometro a bascula??
Autore
Ciao Cricolo,
se non lo trovi sui siti dedicati ad arduino puoi cercare su google o costruirtene uno come in questo articolo.
Mauro
Software molto carino e completo, ringrazio Mauro Alfieri e Giordano.
Ho solo una domanda, mi sono approcciato ad arduino da pochissimo e mi scuso se è banale:
Mentre trasferisco i dati e sto ciclando la parte Web arriva un interrupt si aggiorna la variabile TotPioggia, ma non scrivo il file. Avrei chiaramente che ad una data ed ora non sarà piovuto 0.2 mm ma per esempio 0.4 o 0.6 mm.
Per ovviare a questo problema potrebbe essere scritto il file dentro all’interrupt funzione (Basculata) o risulterebbe troppo lenta?
spero di essere stato chiaro. Saluti
Alan
Autore
Ciao Alan,
come hai letto il pluviometro non è un mio progetto 🙂 tuttavia provo a risponderti.
Potresti modificare il codice in modo che allo scattare di un evento interrupt salvi il dato tuttavia avresti senza dubbio un disallineamento tra il numero di interrupt letti e quelli salvati dovuti al tempo necessario al salvataggio.
grazie mille per la risposta
saluti
Alan
Mauro ho una domanda per un esperto come te. Sto cercando……. e non nego che sto perdendo le speranze :9 di inviare un file da arduino a Pc.
Mi spiego meglio ho utilizzato il programma di Giordano per registrare un file sulla sd card. Poi ho cercato ma fino ad ora senza successo di inviare il file al pc da una pagina web. Ho creato un pulsante che mi scarica il file ma haime il file è vuoto…… sai che qualcuno si riuscito nell’intento?
posto il programma magari a te è già capitato di risolvere il problema
< codice rimosso in automatico >
saluti
Alan
Autore
Ciao Alan,
non penso di aver capito cosa tu voglia ottenere.
Gli sketch incollati nei commenti vengono eliminati in automatico in quanto non sono leggibili ed in ogni caso non avrei tempo di poterli verificare , provare e correggere.
Da quanto ho compreso hai salvato il file con il datalog del pluviometro su una SD e vorresti scaricare questo file dalla SD al Pc via Web.
Se questo è il tuo obiettivo puoi leggere il file e scrivertelo a video come ho fatto in altri tutorial ( es.: pagine multiple su sd via ethernet ) in quel tutorial io uso un file htm, che il browser interpreta, ma se ti fai restituire un file di testo (txt,log,ecc) lo vedrai printato a video nel browser.
grazie e sempre molto gentile. hai azzeccato la risposta 🙂
Ciao Mauro per prima cosa auguri di buon anno.
Ho trovato questo pluviometro http://www….uk/MISOL-Spare-weather-station-measure/dp/B00QDMBXUA va bene per il progetto? Ê poco documentato su sito
Autore
Ciao Gennaro,
grazie per gli auguri, ricambio.
Ti ricordo che i link nei commenti preferisco non siano riportati per evitare pubblicità e problemi legali ad essa connessi.
In merito al pluviometro che hai trovato concordo sulla mancanza di documentazione adeguata che rischia di farti trovare con un prodotto inadeguato al progetto o non utilizzabile.
Ciao Mauro, complimenti per il bel progetto.
Premetto che ho integrato il tuo circuito insieme ad un DHT22 e ad un BMP180 ma ho un problema: il programma registra alcune basculate che non esistono; cioè mentre sta eseguendo il loop() e quindi registrando e scrivendo i dati nella sd relativi a temperatura, pressione ed umidità, in modo del tutto random registra alcuni interrupt che di fatto non avvengono mai, scrivendo sul file dei numeri non reali.
Ho pensato che ci fossero dei problemi di interferenza con i cavi del bus I2C, quindi ho scollegato il tutto e lasciato solo il pluviometro collegato, ma il problema ha continuato a presentarsi; ho provato anche a cambiare l’interrupt zero con l’interrupt uno ma senza nessun risultato. Hai idea di quale potrebbe essere il problema?
In rete non riesco a trovare nulla di simile. Grazie dell’aiuto.
Ciao
Autore
Ciao Lorenzo,
il pluviometro non è un mio progetto ma di Giordano come hai letto.
Dalla tua descrizione sembra che il problema sia più di tipo elettrico che nello sketch, l’interrupt rileva qualche variazione fantasma dovuta magari ad una caduta di tensione sui cavi o ad un cattivo collegamento della resistenza di pull-up indicata da Giordano.
Verfica con cavi di 10cm se si verifica il problema e controlla anche la resistenza che hai usato.
potresti dirmi dove comprare la bascula a cucchiaio? Vorrei provare a fare un pluvio come il tuo
Grazie
Luigi
Autore
Ciao Luigi,
lascio il commento on-line perché Giordano, autore del progetto, possa risponderti.
Grazie per aver condiviso questo progetto, ma volevo chiederti, per cortesia, se potevi mettere anche lo schema di collegamento…almeno quello del pluviometro…
Grazie
Autore
Ciao Antonio,
il progetto è di un appassionato maker a cui ho offerto la possibilità di divulgare il progetto.
Nell’articolo lo schema del pluviometro è presente, è quello molto semplice formato da una resistenza ed un condensatore.