Datalogger Arduino LCD DHT11

Il progetto presentato lunedì scorso ti ha permesso di monitorare i temperatura ed umidità, se ci aggiungi una Keypad Lcd puoi ottenere il Datalogger Arduino LCD DHT11.

Datalogger Arduino LCD DHT11

Rispetto al Datalogger Arduino temperatura umidità l’agginta di un display LCD e dei relativi pulsanti ti evitano di dover interrompere il monitoraggio della tua casa per visualizzare i valori rilevati.

Grazie al display LCD 16×2 della Keypad LCD puoi visualizzare il dato istantaneo misurato e non perdere il salvataggio continuo del dato.

Quali componenti puoi acquistare per il Datalogger Arduino LCD DHT11 ?

Per realizzare il progetto ti occorrono i medesimi componenti visti nel precedente progetto:

  • n.1 arduino uno
  • n.1 RTC Shield
  • n.1 SD Card Shield
  • n.1 sonda DHT11 con relativo cavetto di connessione
  • n.1 Memory card SD da 2Gb max
  • n.3 cavetti per breadboard

a cui devi aggiungere la keypad lcd:

  • n.1 keypad lcd

Collegamenti del Datalogger Arduino LCD DHT11

I collegamenti non sono molto differenti dal precedente progetto a parte il pin OUTPUT della sonda DHT11 che dovrai collegare ad un pin digitale differente dai pin 4,5,6,7,8,9 utilizzati dalla Keypad LCD, io ho scelto il pin 15.

Non è un errore, i pin digitali arduino sono 13, tuttavia il pin A0 puoi utilizzarlo come 14 ed a seguire A1 = 15, A2 = 16 … A5 = 19

In questo progetto A0 è usato dalla Keypad LCD per i pulsanti ed A4-A5 sono utilizzati dalla RTC Shield per l’orologio, restano quindi liberi A1,A2,A4 rispettivamente 15,16,17.

Puoi usare anche i pin digitali 2 o 3, ho scelto di usare il pin 15 in quanto la keypad LCD ha un connettore a 3 contatti:

  • +5v
  • gnd
  • segnal

per tutti i pin oltre A0, che usa per i pulsanti, molto comodo per collegare il connettore in dotazione alla sonda DHT11.

Datalogger Arduino LCD DHT11 montaggio

Lo sketch del progetto

Il Datalogger Arduino LCD DHT11 ha uno sketch un po’ più complesso rispetto al precedente in quanto devi controllare il Display LCD 16×2 e i pulsanti.

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

#define CS 10
#define DHT11_PIN 15
#define BUTTON A0

int SELECT[]  =  {720,760};
int LEFT[]    =  {480,520};
int RIGTH[]   =  {0,20};
int UP[]      =  {120,160};
int DOWN[]    =  {300,350};

RTC_DS1307 RTC;
dht11 DHT;
LiquidCrystal lcd(8,9,4,5,6,7);
char buffer[50];
char lcdBuffer[16];

File myFile;

void setup () {
    Serial.begin(57600);
    Serial.print("Initializing SD card...");
    pinMode(CS, OUTPUT);

    lcd.begin(16, 2);

    lcd.setCursor(0,0);
    lcd.print("DataLogger LCD ");
    lcd.setCursor(0,1);
    lcd.print("mauroalfieri.it");

    delay( 3000 );

    lcd.clear();  
    lcd.setCursor(0,0);
    lcd.print("Init SD Card...");
    lcd.setCursor(0,1);

    if (!SD.begin(CS)) {
      Serial.println("initialization failed!");
      lcd.print("... Failed   ");
      return;
    }
    Serial.println("initialization done.");
    lcd.print("... Ready    ");

    delay( 2000 );

    lcd.clear(); 
    Wire.begin();
    RTC.begin();
    RTC.sqw(0);		//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__));
    }
}

void loop () {
    DateTime now = RTC.now();

    lcd.clear(); 
    sprintf(lcdBuffer, "%02d/%02d/%04d", now.day(), now.month(), now.year() );
    lcd.setCursor(0,0);
    lcd.print(lcdBuffer);
    sprintf(lcdBuffer, "%02d:%02d:%02d", now.hour(), now.minute(), now.second() );
    lcd.setCursor(0,1);
    lcd.print(lcdBuffer);

    if ( now.minute() == 00 || now.minute() == 10 || now.minute() == 20 || now.minute() == 30 || now.minute() == 40 || now.minute() == 50 ) {
       saveData( now );
    }   

    if ( ctrlButton( analogRead( BUTTON ) ) != 0 ) {  
       readSensor( now );
    }

    delay( 1000 );
}

void readSensor( DateTime now ) {
    lcd.clear(); 
    lcd.setCursor(0,0);
    lcd.print("Lettura DHT11");
    lcd.setCursor(0,1);

    // -----------------------------------------------------------------------
    int chk;
    chk = DHT.read(DHT11_PIN);    // READ DATA
    switch (chk){
        case DHTLIB_OK:  
                Serial.print("OK,\t"); lcd.print("SUCCESS");
                break;
        case DHTLIB_ERROR_CHECKSUM: 
                Serial.print("Checksum error,\t"); lcd.print("Checksum error");
                break;
        case DHTLIB_ERROR_TIMEOUT: 
                Serial.print("Time out error,\t"); lcd.print("Time out error");
                break;
        default: 
                Serial.print("Unknown error,\t"); lcd.print("Unknown error");
                break;
     }
     delay(1000);
    // -----------------------------------------------------------------------

    lcd.clear(); 
    lcd.setCursor(0,0);
    sprintf(lcdBuffer,  "%s %02d", "Humidty     ", DHT.humidity );
    lcd.print(lcdBuffer);
    lcd.setCursor(0,1);
    sprintf(lcdBuffer,  "%s %02d", "Temperatura ", DHT.temperature );
    lcd.print(lcdBuffer);

    delay( 3000 );
}

void saveData( DateTime now ) {
    int chk;
    chk = DHT.read(DHT11_PIN);    // READ DATA
    sprintf(buffer,  "%02d/%02d/%d %02d:%02d:%02d %d %d", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second(), DHT.humidity, DHT.temperature );
    Serial.println( buffer );

    myFile = SD.open("dati.log", FILE_WRITE);
    if (myFile) {
      myFile.println(buffer);
      myFile.close();
    } else {
      Serial.println("error opening data.log");
      lcd.clear(); 
      lcd.setCursor(0,0);
      lcd.print("Err SD Write");
    }
    delay(1000);
}

int ctrlButton( int button ) {
  if ( SELECT[0] <= button && button <= SELECT[1] ) { return 1; }
  if ( LEFT[0] <= button && button <= LEFT[1] ) { return 2; }
  if ( RIGTH[0] <= button && button <= RIGTH[1] ) { return 3; }
  if ( UP[0] <= button && button <= UP[1] ) { return 4; }
  if ( DOWN[0] <= button && button <= DOWN[1] ) { return 5; }
  return 0;
}

riprendendo le principali modiche evito di ripeterti le stesse spiegazioni già descritte in passato:

linea 005: includi la libreria LiquidCrystal.h necessaria alla gestione del display LCD;

linea 007: cambia l’impostazione del pin a cui hai collegato la sonda DHT11, dal pin 4 al pin 15;

linea 009: definisci una costante a cui assegni il valore del pin su cui sono connessi i pulsanti della keypad lcd;

int SELECT[]  =  {720,760};
int LEFT[]    =  {480,520};
int RIGTH[]   =  {0,20};
int UP[]      =  {120,160};
int DOWN[]    =  {300,350};

linee 011-015: definisci un array di due elementi ( min,max ) per ciascun pulsante;

linea 019: definisci una istanza della classe LiquidCrystal impostando i pin a cui il display è connesso;

linea 021: definisci un buffer lcdBuffer di 16 caratteri in cui memorizzerai tutti i testi da visualizzare sul display;

    lcd.begin(16, 2);

    lcd.setCursor(0,0);
    lcd.print("DataLogger LCD ");
    lcd.setCursor(0,1);
    lcd.print("mauroalfieri.it");

    delay( 3000 );

linea 030: imposta il display per funzionare in modalità 16×2, 16 colonne e 2 righe;

linee 032-033: posiziona il cursore al primo carattere della prima riga e scrivi “Datalogger LCD”;

linee 034-035: posiziona il cursore al primo carattere della seconda riga e scrivi “mauroalfieri.it”;

linea 037: aspetta 3 secondi per permettere la lettura del messaggio;

linee 039-063: sono identiche a quanto presente nei precedenti articoli  a meno delle linee aggiunte per scrivere sul display;

La funzione loop() è notevolmente cambiata grazie all’introduzione di altre funzioni che semplificano il lavoro che deve svolgere:

void loop () {
    DateTime now = RTC.now();

    lcd.clear(); 
    sprintf(lcdBuffer, "%02d/%02d/04d", now.day(), now.month(), now.year() );
    lcd.setCursor(0,0);
    lcd.print(lcdBuffer);
    sprintf(lcdBuffer, "%02d:%02d:%02d", now.hour(), now.minute(), now.second() );
    lcd.setCursor(0,1);
    lcd.print(lcdBuffer);

    if ( now.minute() == 00 || now.minute() == 10 || now.minute() == 20 || now.minute() == 30 || now.minute() == 40 || now.minute() == 50 ) {
       saveData( now );
    }   

    if ( ctrlButton( analogRead( BUTTON ) ) != 0 ) {  
       readSensor( now );
    }

    delay( 1000 );
}

L’unica linea identica è la linea 066, a seguire:

linee 068-075: scrivi sul display la data e l’ora corrente;

Datalogger Arduino LCD DHT11 data ora

linee 077-080: controlla i minuti trascorsi e ogni 10 min ( 00,10,20,30,40,50 ) lancia la funzione saveData( now );

linee 082-084: verifica la pressione di uno qualsiasi dei pulsanti presenti sulla KeyPad LCD per richiamare la funzione readSensor( now ) il cui scopo, lo vedrai meglio dopo, è d leggere il valore di temperatura e umidità istantaneo e scriverlo sul display.

linea 086: imposta un attesa di 1sec per ogni ciclo di loop() in modo da non sovraccaricare Arduino ed ottenere un aggiornamento del display ogni secondo;

Passa alle funzioni nuove introdotte con il Datalogger Arduino LCD DHT11: readSensor(), saveData(), ctrlButton()

readSensor()

void readSensor( DateTime now ) {
    lcd.clear(); 
    lcd.setCursor(0,0);
    lcd.print("Lettura DHT11");
    lcd.setCursor(0,1);

    // -----------------------------------------------------------------------
    int chk;
    chk = DHT.read(DHT11_PIN);    // READ DATA
    switch (chk){
        case DHTLIB_OK:  
                Serial.print("OK,\t"); lcd.print("SUCCESS");
                break;
        case DHTLIB_ERROR_CHECKSUM: 
                Serial.print("Checksum error,\t"); lcd.print("Checksum error");
                break;
        case DHTLIB_ERROR_TIMEOUT: 
                Serial.print("Time out error,\t"); lcd.print("Time out error");
                break;
        default: 
                Serial.print("Unknown error,\t"); lcd.print("Unknown error");
                break;
     }
     delay(1000);
    // -----------------------------------------------------------------------

    lcd.clear(); 
    lcd.setCursor(0,0);
    sprintf(lcdBuffer,  "%s %02d", "Humidty     ", DHT.humidity );
    lcd.print(lcdBuffer);
    lcd.setCursor(0,1);
    sprintf(lcdBuffer,  "%s %02d", "Temperatura ", DHT.temperature );
    lcd.print(lcdBuffer);
}

linee 090-093: pulisci il display LCD e scrivi sulla prima riga “Lettura DHT11”;

Datalogger Arduino LCD DHT11 lettura success

linee 095-113: non sono differenti dalle precedenti descritte se non per l’aggiunta del comando lcd.print() con cui scrivi per ciascun codice di ritorno dalla sonda un messaggio sulla seconda llinea del display;

linee 115-121: scrivi sul monitor i valori relativi ad umidità e temperatura letti dal Datalogger Arduino LCD DHT11 sulle sue righe del display;

Datalogger Arduino LCD DHT11 temperatura umidita

saveData()

void saveData( DateTime now ) {
    int chk;
    chk = DHT.read(DHT11_PIN);    // READ DATA
    sprintf(buffer,  "%02d/%02d/%d %02d:%02d:%02d %d %d", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second(), DHT.humidity, DHT.temperature );
    Serial.println( buffer );

    myFile = SD.open("dati.log", FILE_WRITE);
    if (myFile) {
      myFile.println(buffer);
      myFile.close();
    } else {
      Serial.println("error opening data.log");
      lcd.clear(); 
      lcd.setCursor(0,0);
      lcd.print("Err SD Write");
    }
    delay(1000);
}

tutta la funzione nel Datalogger Arduino LCD DHT11 non presenta differenze con il codice che già conosci.

ctrlButton()

int ctrlButton( int button ) {
  if ( SELECT[0] <= button && button <= SELECT[1] ) { return 1; }
  if ( LEFT[0] <= button && button <= LEFT[1] ) { return 2; }
  if ( RIGTH[0] <= button && button <= RIGTH[1] ) { return 3; }
  if ( UP[0] <= button && button <= UP[1] ) { return 4; }
  if ( DOWN[0] <= button && button <= DOWN[1] ) { return 5; }
  return 0;
}

puoi trovare la descrizione completa di questa funzione nell’articolo dedicato alla Keypad LCD o al Dolly.

Buon monitor domotico !!!

Cortesemente, prima di inserire i commenti leggi il regolamento

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

30 comments

2 pings

Skip to comment form

    • Paolo on 3 gennaio 2014 at 23:44
    • Reply

    Questo è il progetto per realizzare un ambiente controllato come l’incubatrice. Una lampada a raggi infrarossi da 150 watt potrebbe essere comandata dal datalogger. Devo impostare una temperatura e mantenerla tale anche con una tolleranza di + – 2 %. Coem fare?

    1. Ciao Paolo,
      perdona la mia incomprensione, mi stai chiedendo un preventivo per realizzare il progetto?

      Mauro

    • Andrea on 9 gennaio 2014 at 20:12
    • Reply

    Se volessi avere la temperatura e l’umidità con i decimali come devo fare ( Es 20 gradi -> 20,5 ).. Per capire indento le righe 117 e 120. PS Bellissimo blog molto utile!!

    1. Ciao Andrea,
      devi definire tutte le variabili di lettura del dato da DHT11 di tipo float e considerare che avrai dei decimali da visualizzare sul display quindi almeno 3 caratteri in più ( ,xx )

      Mauro

    • mauro on 19 gennaio 2014 at 10:59
    • Reply

    Ciao,ho un problema con la compilazione dello sketch,penso che sia causato dalla libreria del display,mi riesci ad indicare che libreria utilizzi in questo codice (…magari mi segnali il link ) se possibile.

    Ti allego l’errore di Compilazione :
    In file included from C:\Programmi\arduino-1.0.5\libraries\LiquidCrystal\LiquidCrystal.cpp:1:
    C:\Programmi\arduino-1.0.5\libraries\LiquidCrystal\/LiquidCrystal.h:7:17: warning: SPI.h: No such file or directory
    C:\Programmi\arduino-1.0.5\libraries\LiquidCrystal\LiquidCrystal.cpp: In member function ‘void LiquidCrystal::initSPI(uint8_t)’:

    Grazie,Mauro

    1. Ciao Mauro,
      l’errore riguarda proprio la LiquidCrystal.cpp che non sembra corretta, io uso quella di default dell’IDE arduino.

      Prova a re installare l’IDE.

      Mauro

    • Antonio on 28 febbraio 2014 at 19:45
    • Reply

    Ciao, come si chiama la sd card shield che hai utilizzato? Non è che mi potresti linkare la pagina web su cui comprarla?

    1. Ciao Antonio, la SD Card la trovi su robot-domestici.it. Quella mostrata nel progetto è una versione superata oggi esiste la ver successiva che non ho ancora provato. Sul blog trovi la nuova versione del progetto con una shield che unisce SD ed RTC ti consiglio di acquistare tutto il kit nuovo perché le evoluzioni saranno solo su quella versione.

    • Leo on 6 marzo 2014 at 19:33
    • Reply

    Ciao Muro, sto realizzando “Datalogger Arduino LCD DHT11” ma c’è un problema nella compilazione dello sketch, sblocca alla riga 18, se detta riga lo metto come commento si blocca alla riga 127.
    Io ho Arduino uno Rev3, data logger ( Futura elettronica), display Keypad 16×2 e DHT11.
    Puoi aiutarmi? Grazie

    1. Ciao Leo, cosa intendi per datalogger futura elettronicaleggi l’errore che ti restituisce e interpretalo di solito l’IDE arduino se si blocca su una riga ti dice anche cosa manca o che errore rileva.

    • Leo on 7 marzo 2014 at 09:04
    • Reply

    Scusa intendevo SD card shield, “dht11” does not name type. Se fosse la library del sensore dove posso scaricare quella giusta?
    Grazie.

    • Leo on 7 marzo 2014 at 12:47
    • Reply

    Ultime dalle prove: facendo girare lo sketch del sito Arduino, il sensore DHT11 funziona e riesco a leggere temp. e um.
    potrebbe essere un errore di sintassi ?

    1. Ciao Leo, dipende dall’errore che ricevi.

    • Leo on 7 marzo 2014 at 15:22
    • Reply

    Questo è lo sketch che funziona

    • Idris cesa on 7 aprile 2014 at 21:49
    • Reply

    Buonasera,Mauro.Ho realizzato il tuo datalogger con risultati molto soddisfacenti.
    Vorrei adesso ,ampliare il progetto in modo da utilizzarlo come “orologio sveglia”.Potresti darmi qualche consiglio per realizzare il tutto? Grazie ancora e buona serata.
    Vorrei poter utilizzare i tasti del kaypad per le regolazioni dell’ora ,della data ,dell’inserzione della sveglia….

    1. Ciao Idris, sono contento. Posso consigliarti la lettura dei miei articoli dedicati all’impostazione dell’ora con la Keypad LCD ed arduino e come esempio di sveglia potresti leggere l’articolo sulla centralina di irrigazione, anche se non c’é scritto come renderla impostabile da display puoi aggiungerlo tu.

    • Roberto Carlos on 18 agosto 2014 at 03:44
    • Reply

    Boa noite Mauro, parabens pelo trabalho.
    Gostei do Datalogger LCD Arduino DHT11, voce poderia enviar para o meu e-mail. Eu quero testar, preciso aprender como funciona.

    obrigado.

    1. Olá Roberto Carlos,
      estão todos descritos neste link.

    • Roberto Carlos on 18 agosto 2014 at 12:58
    • Reply

    Bom dia Mauro, obrigado pela resposta. Qual link?

    1. Olà Roberto Carlos, nesta página.

    • Simone on 12 novembre 2014 at 19:38
    • Reply

    Buonasera, sto studiando un sistema con arduino molto simile al suo (la ringrazio intanto per la sua grande condivisione dei suoi lavori tramite queste guide) ma ahime sto facendo i conti con la mia enorme inesperienza. Il dubbio che mi e’ sorto (chiedo scusa per l’eventuale banalita’…) sono i collegamenti che da arduino partono verso le varie “utenze”: e’ possibile che i pin 4 e 5 siano condivisi da piu’ shield? Seguendo le sue guide precedenti e provando a unirle (rtc+sd card + lcd keypad) ho notato che quei 2 pin vengono sempre chiamati in causa, suppongo che arduino li sappia gestire di suo tramite le librerie ma, se le fosse possibile, gradirei conferma (o anche un link che purtroppo il buon google non mi ha trovato provando a cercare).
    Ringrazio in anticipo per l’eventuale risposta.
    Cordiali saluti.

    1. Ciao Simone,
      spero di aver compreso la domanda.
      Se i pin a cui ti riferisci sono i pin A4 ed A5 e li usi con il protocollo I2C puoi condividerli tra più shield a patto che abbiano indirizzi differenti.
      Non è il caso del mio progetto in cui l’unica shield che usa tale protocollo e tali pin è la RTC.

    • Vincenzo on 21 marzo 2015 at 03:40
    • Reply

    Ciao Mauro sto realizzando il Datalogger loho caricato lo sketch del progetto e nella compilazione mi vengono segnalati questi errori: Arduino:1.6.1 (Windows XP), Scheda:”Arduino Uno”

    H:\Programmi\Arduino\libraries\SD\src\utility\Sd2Card.cpp:26:17: fatal error: SPI.h: No such file or directory

    #include

    ^

    compilation terminated.

    Errore durante la compilazione

    ho inserito #include e l’ errore non si presenta più. Rimane un’ altro problema, l’ orologio non funziona mentre i parametri della sonda vengono visualizzati correttamente.
    Un altra informazione ma se l’ orologio funzionasse i pulsanti come farebbero a cambiare le impostazioni.
    Mi scuso ma ho iniziato solo da qualche giorno ad utilizzare Arduino.
    Grazie
    Enzo

    1. Ciao Vincenzo,
      quando inizi con arduino è buona regola provare sketch semplici per comprendere le basi del funzionamento.
      Nel tuo caso sembra che tu abbia un errore nell’installazione dell’IDE in quanto non trova una libreria SPI.h che è inclusa nell’IDE stesso.
      Non ho ancora provato la tua versione dell’IDE ( 1.6.1 ) per cui potrebbe trattarsi anche di una evoluzione dalle precedenti, controlla sui changelog del sw.

    • federico on 27 aprile 2015 at 18:48
    • Reply

    Ciao Mauro, grazie per questo progetto molto interessante con il quale mi sto avvicinando al mondo Arduino!
    Ho un problema, lo shield della scheda di memoria funziona e funziona anche l’LCD, l’unico probema lo ho con lo shield RTC, una volta caricato lo sketch completo su arduino, sull’LCD mi si fissa su una data e un’ora e i secondi non scorrono, quindi non percepisce il trascorrere del tempo e quindi registra i dati solo quando premo il tasto “right” ma non automaticamente. Da cosa può essere causato il problema?
    Ti ringrazio anticipatamente per la pazienza. 🙂

    Ciao.

    Federico

    1. Ciao Federico,
      il comportamento è anomalo potrebbe dipendere dalla scheda RTC o dallo sketch.
      Hai acquistato il Kit o hai preso i componenti da fornitori differenti?

    • Luca on 16 maggio 2016 at 11:56
    • Reply

    Ciao Mauro, ho provato a cercare sul tuo sito e su quello di futura elettronica, ma non riesco a trovare la libreria RTClib modificata che consente l’utilizzo del comando RTC.sqw.
    Puoi aiutarmi?
    Grazie, Luca

    1. Ciao Luca,
      rimuovi la linea dallo sketch, come descritto nei commenti e risolverai il problema, tanto non occorre quella funzionalità al fine di far funzionare lo sketch stesso.

    • Stefano on 11 giugno 2016 at 15:41
    • Reply

    Ciao Mauro. Sto facendo una semplice stazione meteo con Arduino, temperatura + umidità, usando il dht11 e un display con interfaccia I2C….c’è un problema… Non visualizzo i dati… O meglio, vedo:
    temperatura: 0°C
    umidità 0%

    Provando lo sketch per testare il DHT11 mi dice “Time out error” nello stato del sensore… cosa potrebbe essere?
    La resistenza da pull-up da 10KOhm è troppo grande?

    Grazie

    1. Ciao Stefano,
      il secondo sintomo è spiegazione del primo.
      Se già con lo sketch di test non leggi i valori del sensore è impossibile che tu li veda sul display.
      Verifica i collegamenti del sensore ed eventualmente il pin a cui lo hai collegato, potrebbe essere difettoso il sensore o qualche saldatura, devi indagare meglio sul sensore stesso.

  1. […] per realizzare in modo semplice progetti di raccolta dati con arduino simili al mio progetto: Datalogger Arduino LCD DHT11 che utilizza due shield, una come RTC e una per scrivere su SD […]

  2. […] sketch è identico a quello presentato e descritto nella versione uno del display, che […]

Lascia un commento

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.