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: https://www.mauroalfieri.it/elettronica/pluviometro-arduino.html

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.