domenica 19 gennaio 2014

Meteo - DHT22

DHT22

- Stazione meteo con Arduino - 

- Weather Station with Arduino -

- 19/01/2014 -

  Con questo post continua la costruzione della "nostra"  stazione meteorologica.

This post continue the project for the weather station.


Qui vedremo come utilizzare il sensore DHT22.

 

 

  Questo sensore è in grado di rilevare la temperatura e l' umidità relativa.


E' un sensore di tipo capacitivo, con buona sensibilità.

In questa prova abbiamo utilizzato il sensore RTH03 della Maxdetect  


Model RHT03
Power supply 3.3-6V DC
Output signal digital signal via MaxDetect 1-wire bus
Sensing element Polymer humidity capacitor
Operating range humidity 0-100%RH; temperature -40~80Celsius
Accuracy humidity +-2%RH(Max +-5%RH); temperature +-0.5Celsius
Resolution or sensitivity humidity 0.1%RH; temperature 0.1Celsius
Repeatability humidity +-1%RH; temperature +-0.2Celsius


Come si vede dalle caratteristiche il campo di lavoro per l'umidità e la temperatura è il più ampio possibile. Il sistema di trasmissione dei dati avviene tramite il pin 2 e la GND, si tratta di bus con un filo.

Il segnale digitale viene trasmesso in 2 gruppi da 16 bit per umidità e temperatura e 8 bit per il check

0000 0010 1000 1100      0000 0001 0101 1111                 1110 1110
16 bits RHdata                   16 bits T data                             check sum

Questa caratteristica lo rende ben utilizzabile in applicazioni con Arduino, inoltre esiste una libreria già predisposta che svolge i conteggi e rende disponibili i due valori UR% e Temperatura.

Materiale occorrente:

Arduino, Sensore DHT22 o compatibile, 2 resistenze da 10Komm, 1 pulsnte s.a, display LCD, potenziometro da 10Komm (per Lcd), filo per collegamenti.

Questi i collegamenti realizzati:

 





Questo lo schema elettrico:

 

  Qui sotto a confronto lo Psicrometro con LM35 descritto nel precedente post e la realizzazione dell'igrometro con DTH22.


Questo lo sketch:




/*
 *** Sergio & Adriano Prenleloup ****
 
 ***** Stazione Meteo *********
 *** Temperatura e Umidità ****
 *** Versione 1.01 ************
 ******   18/01/2014 **********
 ******************************
 
 
 * Rileva Temperatura e Umidità mediante il sensore DHT22
 * e mostra i dati su display LCD 2002A (20 caratteri, 2righe)
 * Inoltre gestisce con pulsante la lettura
 * di temperatura minima e massima e lo switch
 * per mostrare le informazioni sul display
 *
 * schema e ulteriori informazioni
 * sul sito http://avventurarduino.blogspot.it
 * Circuito
 * LCD GND     -> blu     -> pin 14
 * LCD RS      -> marrone -> pin 13
 * LCD ENABLE  -> giallo  -> pin 12
 * LCD D4 (11) -> marrone -> pin 10
 * LCD D5 (12) -> rosso   -> pin 9
 * LCD D6 (13) -> verde   -> pin 11
 * LCD D7 (14) -> arancio -> pin 8
 * LCD 5v      -> rosso   -> pin 5v
 *
 * Pin DHT 22 -> pin 5
 * Pin bottone switch -> pin 2
 */
//correggere include
#include &lt LiquidCrystal.h &gt // libreria LCD
#include &lt dht.h           &gt // libreria sensore

// Configurazione PIN
// -------------------------------------------------------------------------------- 
//
#define MIN_MAX_BUTTON_PIN 2 //pulsante

#define DHT22_PIN 5   // piedino dati sensore

// pin digitali utilizzati per il display LCD
#define LCD_RS_PIN 13 
#define LCD_EN_PIN 12
#define LCD_D4_PIN 10
#define LCD_D5_PIN 9
#define LCD_D6_PIN 11
#define LCD_D7_PIN 8

// Dichiarazione classi lcd e dht e chiamate costruttori
// -------------------------------------------------------------------------------- 

// Inizializa la libreria per la gestione dell'LCD 
// LiquidCrystal(rs, enable, d4, d5, d6, d7) 
LiquidCrystal lcd(LCD_RS_PIN, LCD_EN_PIN, LCD_D4_PIN, LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN);

// Inizializza la libreria per comunicare con il sensore DHT22
dht DHT;

// Costanti e variabili gestione stato corrente dei bottoni
// -------------------------------------------------------------------------------- 
const int MODO_AMBIENTE = 0; // questo stato visualizza Temp. ambiente ed umidità
const int MODO_MINMAX   = 1; // questo stato visualizza Temp MIN e Temp. MAX

int stato_bottoni[3];
boolean stato_switch[3];

// Costanti e variabili gestione temp max e temp min
// -------------------------------------------------------------------------------- 
double temp_Max = 0.0;
double temp_Min = 99.0;

// Variabili gestione temp e umidita
// -------------------------------------------------------------------------------- 
double temp_old = -1.0;
double umid_old = -1.0;
double temp_corrente = 0.0;
double umid_corrente = 0.0;

// Variabili gestione lettura
// -------------------------------------------------------------------------------- 
const int DELAY_LETTURE = 10000;  //tempo tra le letture in millisecondi
unsigned long ora_lettura = millis();

// -------------------------------------------------------------------------------- 
// Metodi gestione bottoni
// -------------------------------------------------------------------------------- 
void setup_bottoni() 
{
  pinMode (MIN_MAX_BUTTON_PIN, INPUT);
  stato_bottoni[0] = 0;
  stato_switch[0] = false;
}    
 
void aggiorna_stato_bottone(int bottone, int& statoBottoneVecchio, boolean& statoSwitch)
{
  //Si legge lo stato corrente del bottone (se premuto o no)
  int statoBottoneCorrente = digitalRead (bottone);
  
  //Se lo stato corrente del bottone è cambiato (diverso dal vecchio stato)
  //si deve gestire il nuovo stato
  if (statoBottoneCorrente != statoBottoneVecchio)
  {
      //se stiamo passando da rilasciato a premuto allora gestiamo la 
      //logica antirimbalzo e attiviamo/disattiviamo lo swith
     if (statoBottoneCorrente == HIGH)
     {
       delay(10);
       statoSwitch = !statoSwitch;
     }
     //il nuovo stato diventa lo stato corrente
     statoBottoneVecchio = statoBottoneCorrente;  
  }
}

void controlla_bottone()
{
    aggiorna_stato_bottone(MIN_MAX_BUTTON_PIN, stato_bottoni[0], stato_switch[0]);
}

int modo_operativo()
{
  if (stato_switch[0])
    return MODO_MINMAX;
  else
    return MODO_AMBIENTE;
}

// Metodi gestione aggiornamento e Min, Max temp
// -------------------------------------------------------------------------------- 

// Aggiorna le temperature minime e massime solo se necessario
void aggiorna_min_max(double temp)
{
  if (temp > temp_Max)
  {
      temp_Max = temp;
  }
  if (temp < temp_Min)
  {
      temp_Min = temp;
  }
}

// ritorna true se una tra le due (temperatura o umidità) è cambiata rispetto all'ultima lettura effettuata
boolean da_aggiornare(double temp_corrente, double umid_corrente, double temp_old, double umid_old)
{
  return temp_corrente != temp_old || umid_corrente != umid_old;  
}

// Metodi lettura dati sensore
// -------------------------------------------------------------------------------- 
void setup_DHT()
{
    lcd.print("Configurazione...");
    
    // All'avvio il sensore DHT e' disponibile dopo due secondi
    delay(2000);
    lcd.clear();
    //Serial.begin(9600);
    //Serial.println("DHT TEST PROGRAM ");
    //Serial.print("LIBRARY VERSION: ");
    //Serial.println(DHT_LIB_VERSION);
    Serial.println();
    //Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");  
    Serial.println("Umid (%),\tTemp (C),\tTemp MIN (C),\tTemp MAX (C)");  
}

// legge i valori di temperatura e umidità interrogando il sensore
// ritorna true se la lettura ha avuto successo false in caso di errore
boolean leggi_temperatura_e_umidita(double& temp, double& umidita)
{
    // Avvia la lettura e legge lo stato
    int chk = DHT.read22(DHT22_PIN);
    switch (chk)
    {
        case DHTLIB_OK: 
            //Serial.print("OK,\t"); 
            break;
        case DHTLIB_ERROR_CHECKSUM: 
            Serial.println("Checksum error,\t"); 
            return false;
        case DHTLIB_ERROR_TIMEOUT: 
            Serial.println("Time out error,\t"); 
            return false;
        default: 
            Serial.println("Unknown error,\t"); 
            return false;
    }
    
    // se la lettura ha avuto successo, i due valori sono disponibili nelle
    // due variabili corrispondenti
    temp = DHT.temperature;
    umidita = DHT.humidity;

    return true;
}

// Gestione LCD
// -------------------------------------------------------------------------------- 

void setup_LCD()
{
  lcd.begin(20, 2);
}

// funzioni di utilità per stampare i valori su lcd (min e max)
void print_min_max_lcd(double t_min, double t_max)
{
  lcd.setCursor(0, 0);
  lcd.print("T MAX: ");
  lcd.print(t_max, 1);  
  lcd.print(" C");  
  lcd.setCursor(0, 1);
  lcd.print("T MIN: ");
  lcd.print(t_min, 1);
  lcd.print(" C");
}

// funzioni di utilità per stampare i valori su lcd (temp e umid)
void print_temp_umid_lcd(double temp, double umid)
{
    lcd.setCursor(0, 0);
    lcd.print("Temp : ");
    lcd.print(temp, 1);  
    lcd.print(" C");  
    lcd.setCursor(0, 1);
    lcd.print("Umid : ");
    lcd.print(umid, 1);
    lcd.print(" %");
}

// in base al modo operativo stampa le info ambiente o min e max registrati
// il modo operativo si cambia agendo sullo switch
void print_dati_lcd(double temp, double umid, double t_min, double t_max)
{
  int modo = modo_operativo();
  if (modo == MODO_MINMAX)
  {
    print_min_max_lcd(t_min, t_max);
  }
  else
  {
    print_temp_umid_lcd(temp, umid);
  }
}

void print_dati_console(double temp, double umid, double t_min, double t_max)
{
  Serial.print(umid, 1);
  Serial.print(",\t");
  Serial.print(temp, 1);
  Serial.print(",\t");
  Serial.print(t_min, 1);
  Serial.print(",\t");
  Serial.println(t_max, 1);
}

// Logica per lettura e aggiornamento dati
// -------------------------------------------------------------------------------- 

// ritorna true se dall'ultima lettura è trascorso il tempo fissato
boolean check_timeout()
{
  unsigned long ora_corrente = millis();
  return ora_corrente > ora_lettura;
}

void effettua_lettura()
{
  // si leggono i dati dal sensore
  if (leggi_temperatura_e_umidita(temp_corrente, umid_corrente))
  {
    // se la lettura ha avuto successo e i dati sono cambiati...
    if (da_aggiornare(temp_corrente, umid_corrente, temp_old, umid_old))
    {
      //... si aggiornano con i nuovi valori
      temp_old = temp_corrente;
      umid_old = umid_corrente;
      // e si mostrano su lcd e console
      print_dati_lcd(temp_corrente, umid_corrente, temp_Min, temp_Max);
      print_dati_console(temp_corrente, umid_corrente, temp_Min, temp_Max);
    }
    // si controlla se min e max sono cambiati
    aggiorna_min_max(temp_corrente);
  }

  //imposta l'ora della prossima lettura, da ora a "DELAY_LETTURE" millisecondi
  ora_lettura = millis() + DELAY_LETTURE;
}

// setup generale
// e loop principale sketch
// 
// -------------------------------------------------------------------------------- 

void setup() 
{
  Serial.begin(9600);
  setup_bottoni();
  setup_LCD();  
  setup_DHT();
}

int modo_corrente = MODO_AMBIENTE;

void loop() 
{
  controlla_bottone();
  int modo = modo_operativo();
  
  // si controlla se è giunto il momento di effettuare le letture
  if (check_timeout())
  {
    // se si, allora si recuperano i dati e si imposta l'ora della prossima lettura
    effettua_lettura();
  }
  else if (modo != modo_corrente)
  {
    // se è stato premuto il bottone ed è cambiato il modo si fa refresh dell'lcd
    print_dati_lcd(temp_corrente, umid_corrente, temp_Min, temp_Max);
    modo_corrente = modo;
  }
  
//  delay(10);
}
// END 


Note allo sketch:

La scrittura dello sketch è stata fatta da Adriano, la parte metodi e gestione bottoni è stata utilizzata e descritta in altri post di questo blog, ( nel Luxmetro avevamo 3 bottoni o pulsanti).
Le righe 33 e 34 si devono correggere  inserendo i simobli  nel listato sostituito da &lt, ed il simbolo > nel listato sostituito da &gt , in ogni caso nello sketch scaricabile sotto risultano già corrette.
 Le note e descrizioni nello sketch sono abbondanti e credo sia tutto molto leggibile, si deve tener conto che questo listato farà parte poi della gestione della stazione meteo.

Scarica qui lo sketch

La libreria dht si può scaricare dal sito di  Arduino

Libreria dht

Nei prossimi post vedremo misura di pressione, velocità del vento, pioggia ecc..
Come avrete notato nel post precedente ho annunciato l'arrivo di Arduino Yun, su questa scheda baseremo lo sviluppo della comunicazione dei dati (ma c'è molto lavoro da fare).

Qui sotto il video del lavoro :


Al prossimo post meteo .... At the next post weather.


12 commenti:

  1. Quella riga inizializza la libreria.
    Bisogna scaricare la libreia e inserirla neel'IDE.
    Attenzione come ho scritto nel listato non risultano corrette le righe 33 e 34 perchè il soft che uso non accetta i tag < > , quelle righe devono essere scritte così:

    #include // libreria LCD
    #include // libreria sensore

    come vedi include la libreria, se scarichi il listato dal link non c'è bisogno di correggere nulla, ma devi importare sempre la libreria.
    Appena possibile farò un'aggiunta per spiegare come aggiungere una libreria.
    Grazie comunque della segnalazione che potrà essere utile anche ad altri.
    Se riesci dammi un oK, se ci sono ulteriori problemi o domande chiedi.
    Un saluto.

    RispondiElimina

  2. Come vedi nemmeno qui si riescono a far apparire nel modo giusto ( scarica lo sketch ) è meglio!!

    RispondiElimina
  3. puoi aggiungere il link della libreria da usare?
    grazie tante

    RispondiElimina
  4. risolto...prova a copiare e incollare dht.h e nell'ultima riga compare VISUALIZZA TUTTI "senza davanti //"

    RispondiElimina
  5. Bene ora va! ( oK?)

    Nei prossimi post cercheremo di sottolineare l'uso delle librerie...

    In ogni caso presenterò presto altri post sulla costruzione della stazione meteo.
    Stiamo lavorando per anemometro e per pluviometro....
    A presto!!

    RispondiElimina
  6. Ho provato a compilare il tuo sketch per il sensore DHT22, ma mi da un erorre all'istruzione di inizializzazione della libreria (dht DHT;) e non riesco a trovare dove è l'errore. Potresti aiutarmi ?
    Inoltre la libreria per il sensore devo copiarla sul bocco note e salvarla con il suo nome, per poterla utilizzare?

    Grazie

    Alberto

    RispondiElimina
    Risposte
    1. Ciao! Come puoi leggere qui sopra anche xarsoft aveva un problema con la libreria.
      ( problema risolto!)
      Ho aggiunto in seguito il link per scaricare la libreria ( in questo post) "libreria dht"
      Attenzione però di usare nella chiamata la stessa libreria, perchè ci sono più librerie per il dht.
      la cosa importante è avere coerenza fra la libreria installata e quella che richiami nello sketch.
      A questo proposito non fare copia incolla del testo sul blog, ma scarica dai due link su questo post listato e libreria.
      Per quanto riguarda l'aggiunta delle librerie riguarda quanto scritto sul sito di arduino, oppure sul sito del prof Michele Maffucci.
      Il file deve essere copiato nella apposita "libraries" cartella dell'IDE di arduino, il file dovrà a sua volta essere contenuto nella cartella dht, ed i file *.ccp e *.h dovranno avere lo stesso nome che chiamerai nella inizializzazione dello sketch. (attenzione maiuscole e minuscole fanno differenza!!).

      Fammi sapere.
      Se non riesci vedrò come posso aiutarti di più.
      Saluti
      Sergio

      Elimina
    2. OK. Grazie, ci sono riuscito. Una domanda, però, sia con il tuo sketch che con uno sketch fatto da me le temperature sono uguali ma superiori di circa 1 °C a quella reale. Perchè? Il sensore dovrebbe essere abbastanza preciso.

      Grazie

      Ciao

      Elimina
    3. In effetti anche io ho notato una differenza fra i due termometri quello del DHT e quello del BMP180 dove si misura anche la pressione.
      E' comunque una cosa da approfondire con un termometro di riferimento, e non ho in questo momento questa possibilità.
      Certo che una volta verificato questa differenza se questa rimane costante nel campo delle misure che ci interessano, è possibile intervenire con una correzione software.
      In questo momento non ho la possibilità materiale di fare prove .... in futuro vedrò di ritornare sull'argomento.
      Ti ringrazio per il commento.
      Sergio.

      Elimina
  7. Ho un termometro preciso di riferimento. Effettuerò alcune prove sia di temperatura, sia di umidità poi ti farò sapere. Ciao
    Alberto

    RispondiElimina

Vi ringrazio per la lettura e vi invito al prossimo post.
Se il post vi è stato utile, vi è piaciuto oppure no, scrivete un commento.

Un saluto a tutti.
Sergio

Copyright - Condizioni d’uso - Disclaimer
http://avventurarduino.blogspot.it/2012/10/inizia-lavventura-arduino-12-settembre.html