Pluviometro arduino

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.

pluviometro arduino il 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.

pluviometro arduino schema

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:

pluviometro arduino

Risultato attraverso il browser

Il risultato collegandoti con il tuo browser all’indirizzo del pluviometro:

pluviometro arduino via browser

Buona misurazione !!!

Prima di inserire un commento, per favore, leggi il regolamento

Permanent link to this article: http://www.mauroalfieri.it/elettronica/pluviometro-arduino.html

16 comments

Skip to comment form

    • lmikonos on 19 Dic 2013 at 20:11
    • Reply

    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

    1. 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

    • cricolo on 31 Gen 2014 at 16:45
    • Reply

    ciao dove posso trovare un pluviometro a bascula??

    1. Ciao Cricolo,
      se non lo trovi sui siti dedicati ad arduino puoi cercare su google o costruirtene uno come in questo articolo.

      Mauro

    • Alan on 16 Mar 2014 at 22:23
    • Reply

    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

    1. 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.

    • Alan on 18 Mar 2014 at 18:27
    • Reply

    grazie mille per la risposta

    saluti

    Alan

    • Alan on 27 Mar 2014 at 22:41
    • Reply

    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

    1. 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.

    • Alan on 28 Mar 2014 at 21:41
    • Reply

    grazie e sempre molto gentile. hai azzeccato la risposta 🙂

    • Gennaro on 2 Gen 2015 at 16:05
    • Reply

    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

    1. 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.

    • Lorenzo on 1 Giu 2015 at 17:25
    • Reply

    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

    1. 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.

    • luigi on 3 Mar 2016 at 12:12
    • Reply

    potresti dirmi dove comprare la bascula a cucchiaio? Vorrei provare a fare un pluvio come il tuo
    Grazie
    Luigi

    1. Ciao Luigi,
      lascio il commento on-line perché Giordano, autore del progetto, possa risponderti.

Lascia un commento

Your email address will not be published.

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