«

»

Mag 18

Stampa Articolo

Meteo shield seconda parte

Riprendendo l’articolo sulla Meteo shield prima parte ti presento oggi lo sketch che ho realizzato con l’aiuto dei partecipanti al corso Avanzato Arduino proprio con questa shield:

meteo shield lcd

Avrai notato che nell’immagine è presente un display LCD, bene è il display che abbiamo utilizzato per visualizzare i dati meteo del progetto.

Nel progetto abbiamo incluso anche una SD Card con apposita shield per poter memorizzare i dati rilevati dai sensori ed ottenere un datalogger meteo.

Il progetto Meteo shield

Il progetto meteo shield è composto quindi dai seguenti componenti:

  • n.1 arduino uno
  • n.1 meteo shield
  • n.1 lcd 1602
  • n.1 SD Card shield
  • n.1 SD Card 2Gb

la descrizione dei sensori a disposizione e delle tolleranze la puoi trovare nel mio precedente articolo o nella scheda tecnica del produttore.

Lo sketch del progetto

Lo sketch che abbiamo realizzato in circa 4 ore tutti insieme parte dall’esempio rilasciato dal produttore per essere arricchito delle componenti di Data Logging su sd card.

#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
#include <SD.h>

LiquidCrystal lcd(8,9,4,5,6,7);
RTC_DS1307 RTC;
File myFile;

// VARIABLES DEFINITION AND INITIALIZATION

#define TEMP 2      //TEMPERATURE ACQUISITION ON ANALOG PIN 2
#define UMID 1      //HUMIDITY ACQUISITION ON ANALOG PIN 1
#define PRESS 0     //PRESSURE ACQUISITION ON ANALOG PIN 0
float val = 0.0;
float T= 0.0;
double umidita = 0.0;
double RH = 0.0;
double RHout = 0.0;
double UM = 0.0;
double Pascal=0.0;
double PS=0.0;
double P=0.0;
float VADC= 5;
int DPR = 0;
int RHCORR = 0;
int PCORR = 0;
int TCORR= 0;
double STAMPA_T = 0;
double STAMPA_U = 0;
double STAMPA_P = 0 ;
byte degree[8] = { //  CHARACTER "°C" DEFINITION
  B10111,
  B01000,
  B10000,
  B10000,
  B10000,
  B01000,
  B00111,
};

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.createChar(0, degree); // "°C" SYMBOL
  Wire.begin();
  RTC.begin();
  if (! SD.begin(10)) { 
    Serial.println("Inizializzazione Fallita !!!");
    return;
  }
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}  

void loop() {
  DateTime now = RTC.now();
  lcd.setCursor(0, 1);
  if (now.hour() < 10) {
    lcd.print("0");
  }
  lcd.print(now.hour(),DEC);    // HOUR
  lcd.print(":");
  if (now.minute() < 10) {      
    lcd.print("0");
  }
  lcd.print(now.minute(), DEC);// MINUTES

  lcd.setCursor(6, 1);
  if (now.day() < 10) {        
    lcd.print("0");
  }
  lcd.print(now.day(), DEC);  // DAY
  lcd.print('-');
  if (now.month ()<10) {       
    lcd.print("0");
  }
  lcd.print(now.month(), DEC);//MONTH
  lcd.print('-');
  lcd.print(now.year(), DEC);  //YEAR

  // SERIAL METEO OUTPUT

  STAMPA_T= (temp()); 
  STAMPA_U= (readUMID());
  STAMPA_P = (pressure());

  myFile=SD.open("data.log",FILE_WRITE);
  if (myFile) {
     myFile.print( now.day() );
     myFile.print( "/" );
     myFile.print( now.month() );
     myFile.print( "/" );
     myFile.print( now.year() );
     myFile.print( " " );
     myFile.print( now.hour() );
     myFile.print( ":" );
     myFile.print( now.minute() );
     myFile.print( ":" );
     myFile.print( now.second() );
     myFile.print( " " );
     myFile.print( STAMPA_T );
     myFile.print( " " );
     myFile.print( STAMPA_U );
     myFile.print( " " );
     myFile.println( STAMPA_P );
     myFile.close();
  }
  
  // LCD METEO OUTPUT

  lcd.setCursor(0, 0);   
  lcd.print(STAMPA_T,1); //SHOW ONLY THE FIRST DECIMAL
  lcd.write((uint8_t)0); //PRINT "°C" CHARACTER (IDE 1.0.1)
  delay(200);

  lcd.setCursor(6, 0);
  lcd.print(STAMPA_U,1);//SHOW ONLY THE FIRST DECIMAL
  lcd.setCursor(10,0);
  lcd.print("%");
  delay(200);

  lcd.setCursor(12, 0);
  lcd.print(STAMPA_P,0);//SHOW ONLY THE INTEGER PART
  delay(600);
  
  myFile=SD.open("data.log");
  if (myFile) {
    while(myFile.available()) {
      Serial.write( myFile.read() );
    }
    myFile.close();
  }
}

float temp() {
  double nread = 100.0;          // NUMBER OF READINGS
  double somma = 0.0; 
  for (int i=0; i<nread; i++)
  {
    val = analogRead(TEMP);
    // val : stepGradoTensione = °C : precisioneADC 
    // °C = precisioneADC * val / stepGradoTensione
    // ( (precisioneADC * val)-0.5 ) / stepGradoTensione
    // ( ((VADC/1024) * val )-0.5  ) / stepGradoTensione
    T = (((VADC/1024.0*val)-0.5)* 100)+TCORR;   //TEMPERATURE 
    somma += T;
  }
  delay(100);
  return (somma/nread);
}

double readUMID(){
  double nread = 100.0;          // NUMBER OF READINGS 
  double somma = 0.0; 
  for (int i=0; i<nread; i++)
  {
    UM = analogRead( UMID );              
    RHout=(((UM*VADC/1024.0/3.3)-0.1515)/0.00636)+RHCORR;    //HUMIDITY
    somma += RHout;       
  }
  delay(100);
  return  ( somma / nread );
}

float pressure(){
  double nread = 100.0;           // NUMBER OF READINGS 
  double somma = 0.0; 
  for (int i=0; i<nread; i++)
  {
    Pascal=analogRead(PRESS);
    P=(((Pascal*VADC/1024)/VADC+0.095)/0.009)*10+DPR+PCORR;  //PRESSURE TRANSFERT FUNCTION
    somma += P;
  }
  delay(100);
  return  ( somma / nread ); 
}

alle linee 01-05: includi tutte le librerie necessarie allo sketch;

linee 07-09: definisci gli oggetti con i quali puoi controllare l’LCD, il Real Time Clock e l”SD Card;

linee 13-15: definisci i 3 pin a cui sono connessi rispettivamente il sensore di temperatura, l sensore di umidità ed il sensore di pressione della meteo shield;

linee 16-32: definisci le variabili che ti serviranno durante l’esecuzione dello sketch per tracciare valori relativi ai sensori ed alle campionature eseguite in fase di lettura degli stessi;

linee 33-41: componi il simbolo °C da visualizzare sul display, per farlo considera la maschera di bit in cui il valore 1 indica il corrispondente pixel del carattere da annerire ed il valore 0 da mantenere spento. Seguendo la seguente matrice capirai come funziona la creazione di un simbolo:

lcd-special-simbol

linea 44: definisci la comunicazione seriale a 9600baud;

linea 45: imposta il display 16 colonne 2 righe;

linea 46: crea un carattere prelevando la sua composizione dall’array degree ed assegnandogli il valore 0, ossia il primo puntatore ai caratteri speciali;

line47-48: inizializza le istanze per l’RTC e la SDCard;

linee 49-56: controlla che l’istanza SD e l’istanza RTC siano state create e siano valide, questo significa che le rispettive shield sono state riconosciute dallo sketch e che puoi procedere al loro utilizzo nelle successive linee;

linea 60: definisci una variabile di tipo DateTime chiamata now al cui interno memorizzi il valore estituito dal metodo now() dell’RTC;

linea 61: posizionati alla colonna 0 della riga 1, la seconda riga;

linee 62-83: scrivi sull’LCD la data e l’orario corrente aggiungendo lo 0 per i valori numerici inferiori al 10;

linee 87-89: imposta il valore delle variabili STAMPA_ per temperatura, umidità e pressione prelevando il valore dalle rispettive funzioni di interrogazione che analizzeremo dopo;

linee 91-111: apri il file “data.log” e scrivi in sequenza: data, ora, temperatura, umidità, pressione;

linee 115-118: è ora di scrivere anche sul display i valori letti dai sensori per cui posizionati alla prima colonna della prima linea ( 0,0 ) e scrivi prima il valore di temperatura ed a seguire il simbolo °C che hai creato alla line 46. Infine aspetta 200 millisecondi prima di procedere oltre;

linee 120-124: posizionati al 6 carattere della prima linea, la stessa del blocco precedente, e scrivi il valore di umidità seguito dal simbolo %. Aspetta altri 200 millisecondi;

linee 126-128: posizionati al carattere 12 e scrivi il valore di pressione. Attendi 600 millisecondi;

linee 130-136: apri il file “data.log” in sola lettura e scrivi sul monitor seriale tutto il contenuto scorrendo carattere per carattere;

linea 139: definisci una funzione di tipo float in modo che possa restituire un valore con virgola;

linee 140-141: definisci due variabili: nread e somma. La prima rappresenta il numero di letture da eseguire per ritenere il valore valido. La seconda memorizzerà la somma di tutti i valori delle successive letture;

linea 142: crea un ciclo for da 0 al numero di letture definito dalla variabile nread;

linea 144: leggi il valore analogico del sensore di temperatura;

linea 149: calcola T con la formula vista nello scorso articolo per questo sensore:

meteo shield MCP9700A valori

da cui deduci la formula applicata allo sketch;

linea 150: somma T al precedente valore di somma, in pratica sommi tutti i valori rilevati per le n letture eseguite;

linea 153: restituisci alla funzione che ha richiamato la temp() il valore di somma diviso il numero di letture eseguite, in pratica la media delle 100 letture.

linee 156-167: crei la funzione readHum il cui scopo è evidentemente quello di registrare il valore di umidità rilevato;

linee 169-181: crei la funzione pressure con la quale interroghi il sensore di pressione e ne recuperi il valore di media su 100 letture successive;

In definitiva avrai una scrittura su SD Card ed un aggiornamento almeno ogni 31 secondi ai quali vanno aggiunti i tempi necessari per eseguire tutte le istruzioni presenti nello sketch, ciascuna linea di codice impiega un tempo di cpu per essere eseguita che dipende dalla linea stessa.

Buona stazione meteo !!!

Permalink link a questo articolo: http://www.mauroalfieri.it/elettronica/meteo-shield-seconda-parte.html

4 comments

Vai al modulo dei commenti

  1. Davide

    Ciao Mauro,

    complimenti per l’articolo, molto intressante.
    Secondo te con i dati salvati su sd posso realizzare un grafico dell’andamento della temperatura per esempio, utilizzando “processing” come linguaggio? e se si potresti darmi qualche dritta su come farlo?
    In quel caso si potrebbe realizzare un grafico con andamento della temperatura in tempo reale, giusto?

    ciao
    Davide

    1. Mauro Alfieri

      Ciao Davide,
      penso sia possibile realizzare dei grafici con Preocessing ma non sono un esperto.
      Io per farlo di solito uso un foglio di calcolo, estraggo la SD Card ed importo il csv realizzando poi i grafici, dovrei aver scritto anche un articolo su come farlo.

  2. samuele

    Bel progetto. Sto realizzando un progetto simile per misurare la pressione dell’area volevo chiederti dei consigli dove posso inviarti il progetto? Ti ringrazio in anticipo

    1. Mauro Alfieri

      Ciao Samuele,
      se vuoi scrivere un articolo e condividerlo puoi seguire le istruzioni presenti nel “Sostienimi” -> “Collabora al Blog”
      Se invece desideri inviarmi lo sketch perché io lo corregga, mi spiace, questo non è possibile posso solo darti consigli se leggi i miei articoli su come risolvere le cose che non comprendi.

Lascia un commento

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

Puoi usare i seguenti tag ed attributi HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>