Project showcase
Temperature and Humidity Logger (Using Arduino)

Temperature and Humidity Logger (Using Arduino) © GPL3+

Reads and stores in SD card, the temperature and humidity values over time.

  • 11,059 views
  • 8 comments
  • 37 respects

Components and supplies

Adafruit Data Logger Shield
SD CARD Writer, RTC, plus a prototyping area
×1
Adafruit LCD Shield Kit w/ 16x2 Character Display - Only 2 pins used!
This kit uses only 2 arduino pins (SCL and SDA) saving I/O pins for other purposes.
×1
20120702130508859
DHT11 Temperature & Humidity Sensor (4 pins)
×1
A000066 iso both
Arduino UNO & Genuino UNO
I used Arduino UNO R3
×1

Necessary tools and machines

09507 01
Soldering iron (generic)
Medium soldering skills needed

Apps and online services

About this project

I used to work with old mechanic devices that registered the temperature and humidity in computer rooms. Those devices use a piece of graduated paper and two different pens to write a graph of temperature and humidity over time.

That kind of device had several problems associated to the technology used:

They have to be calibrated regularly,

The pens have to be changed regularly

The paper have to be changed regularly

The data have to be stored in paper dossiers if you want long time history.

As today we have access to cheap microcontrollers, cheap and reliable sensors, cheap RTCs, we can measure data, put a timestamp and easily store data on an SD card, that can store years of information. That idea impelled me to start this project that can replace those old machines.

For this project I used

  • The Arduino Uno R3,
  • The ADAFRUIT ASSEMBLED DATA LOGGING SHIELD FOR ARDUINO,
  • The LCD SHIELD KIT W/ 16X2 CHARACTER DISPLAY also from ADAFRUIT
  • The temperature and Humidity sensor DHT11
  • As an option I used an LDR to measure ambient light. Sometimes is Important to know if lights are on or off or if case is open, for how long etc...
  • As a second option I also record the value of external voltage,using a voltage divider, to detect power failures.

The Adafruit Data Logger Shield can do most of the work, and keep the project simple, because it contains the RTC (Real Time Clock), The SD Interface and the prototyping area. This area is the place used to mount the Sensor DHT11 and the optional light and voltage sensors.

SD Data Logger – pins used

Digital:

02 – DHT11 sensor

03 – Green LED

04 – Red LED

10 – Output - SD CS – SD Library

11 – SD MOSI

12 – SD MISO

13 –SD CLK

Analog:

A0 – Vin Voltage measurement

A3 – Light Sensor (LDR)

A4 – I2C (RTC)

A5 - I2C (RTC)

For humidity and temperature sensor I used DHT11, wich is cheap. This part have a 5% humidity and 2ºC temperature tolerance. If you need better accuracy , use DHT22 instead, wich have a tolerance of 0.5ºC (Need diferent library).

For information about libraries and examples about using these DHT sensors, I recommend reading:

The optional Light sensor is a LDR connected between 5V and pin A3. From pin A3 to ground connect a 10K resistor, forming a voltage divider. The voltage present at pin A3 is variable depending on ambient light intensity.

The Vin sensor is comprised of a voltage divider composed by a resistor of 100k and another of 10k. The 100k is conected between Vin and A0 and the 10K conected between A0 and ground.

Display:

I chose "RGB LCD Shield " display kit from Adafruit because I can have a LCD display and 5 buttons, using only the 2 pins of the Arduino's I2C (and of course the power lines). The main objective was to save Arduino input/output pins for other purposes.

The kit itself is easy to assemble, just solder all the components in the right place. This kit is a shield and mounts on top of Arduino Uno, so hardware connection is not a big problem. Just sits on top. If you prefer to put the display elsewhere, the connection is also easy. You just need two I2c wires, plus power lines (+5/Gnd).

For more information about this kit and libraries needed, please refer to:

https://learn.adafruit.com/rgb-lcd-shield

https://cdn-learn.adafruit.com/downloads/pdf/rgb-lcd-shield.pdf

https://learn.adafruit.com/assets/1439

Code

DataLog_V55.inoArduino
This is the final code. Uses Temperature and humidity sensor DHT11.
/* Arduino Data Logger Version 2015 by Luis Sousa */

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
#include <dht11.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

#define ECHO_TO_SERIAL 1 // dados no porto serie?
#define DHT11PIN 2 //pino digital onde liga sensor de temp e humid
#define redLEDpin 4 //pino digital onde liga LED vermelho
#define greenLEDpin 3 //pino digital onde liga LED verde
#define chipSelect 10 //pino digital onde liga CS do SD Card
#define luzP 3 // pino analogico onde liga LDR
#define pausa 5000 //5s
#define ficheiro "dados.txt" //nome do ficheiro de dados
#define cabecalho "millis,Data,Hora,Vin,Luz,Temperatura,Humidade,DewPoint" //cabecalho da informaao a gravar
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7

dht11 DHT11; // sensor de temp e humidade
RTC_DS1307 RTC; // Real Time Clock
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// Inicializao de variaveis
float Vin = 0;
byte LCDColor = 1;
//char ficheiro[] = "dados.txt";
int year = 0;
int month = 0;
int day = 0;
int hour = 0;
int minute = 0;
byte buttons = 0;
DateTime now;

//Funoes
void erro(char *str)
{
  //Sinaliza erro no lcd
  lcd.clear();
  lcd.setBacklight(RED);
  lcd.setCursor(0, 0);
  //lcd.print("Erro ");
  lcd.setCursor(0, 1);
  lcd.print(str);

  //Sinaliza erro no porto serie
  Serial.print("Erro: ");
  Serial.println(str);
  // red LED = erro
  digitalWrite(redLEDpin, HIGH);
  while (1); // HALT
}
int RtcAdj(char *str, int valor)
{
  byte sair = 0;
  byte debounce = 80;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Acertar Relogio ");

  while (!sair)
  {
    lcd.setCursor(0, 1);
    lcd.print (str);
    lcd.print(valor);
    buttons = lcd.readButtons();
    if (buttons)
    {
      if (buttons & BUTTON_UP)
      {
        valor ++;
        delay(debounce);
      }
      if (buttons & BUTTON_DOWN)
      {
        valor --;
        delay(debounce);
      }
      if (buttons & BUTTON_LEFT)
      {
        valor --;
        delay(debounce);
      }
      if (buttons & BUTTON_RIGHT)
      {
        valor ++;
        delay(debounce);
      }
      if (buttons & BUTTON_SELECT)
      {
        sair = 1;
      }
    }
  }
  return (valor);
}
/*
//Celsius para Fahrenheit
double Fahrenheit(double celsius)
{
  return 1.8 * celsius + 32;
}

//Celsius para Kelvin
double Kelvin(double celsius)
{
  return celsius + 273.15;
}
*/
// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm
double dewPoint(double celsius, double humidity)
{
  double A0 = 373.15 / (273.15 + celsius);
  double SUM = -7.90298 * (A0 - 1);
  SUM += 5.02808 * log10(A0);
  SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / A0))) - 1) ;
  SUM += 8.1328e-3 * (pow(10, (-3.49149 * (A0 - 1))) - 1) ;
  SUM += log10(1013.246);
  double VP = pow(10, SUM - 3) * humidity;
  double T = log(VP / 0.61078); // temp var
  return (241.88 * T) / (17.558 - T);
}
/*
// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
  double a = 17.271;
  double b = 237.7;
  double temp = (a * celsius) / (b + celsius) + log(humidity / 100);
  double Td = (b * temp) / (a - temp);
  return Td;
}
*/
void setup()
{
  pinMode(10, OUTPUT);  // SD ChipSelect
  pinMode(13, OUTPUT);  // LED de monitorizaao
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);

  // Inicializaao do porto serie:
  Serial.begin(9600);

  //Inicializaao do I2C
  Wire.begin();

  //Inicializao do LCD
  lcd.begin(16, 2);
  lcd.setBacklight(TEAL);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Data Logger V5.5");
  lcd.setCursor(0, 1);
  lcd.print("Luis Sousa-2015");
  delay(900);
  lcd.clear();

  //Inicializaao do sensor de temperatura
  Serial.print("DHT11 LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
  int chk = DHT11.read(DHT11PIN);
  Serial.print("Sensor de Temperatura: ");
  switch (chk)
  {
    case 0: Serial.println("OK"); break;
    case -1: erro("DHT11 Checksum"); break;
    case -2: erro("DHT11 Time out"); break;
    default: erro("DHT11 Error"); break;
  }
  Serial.println();

  //Inicializao do SD Card
  if (!SD.begin(chipSelect)) // Verifica Presena do SD Card:
  {
    erro("Introduza SD");
    /*
    Serial.println("Introduza Cartao SD");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Introduza ");
    lcd.setCursor(0, 1);
    lcd.print("Cartao SD");
    // Sai por falta de Cartao
    return;
    */
  }
  else Serial.println("Cartao SD OK.");

  // cria novo ficheiro
  //char filename[] = "LOGDAT00.CSV";
  //for (uint8_t i = 0; i < 100; i++)
  //{
  // filename[6] = i / 10 + '0';
  // filename[7] = i % 10 + '0';
  //  if (! SD.exists(filename))
  //  {
  //    // se nao existir, cria novo
  File logfile = SD.open(ficheiro, FILE_WRITE);
  //    break; // sai do loop!
  //  }
  //}
  if (! logfile)
  {
    erro("Erro no ficheiro");
  }
  else
  {
    Serial.print("Gravando em: ");
    Serial.println(ficheiro);
    logfile.println(cabecalho);
    logfile.close();
  }
#if ECHO_TO_SERIAL
  Serial.println(cabecalho);
#endif //ECHO_TO_SERIAL

  //Inicializao do RTC
  if (!RTC.begin())
  {
    // logfile.println("RTC com avaria");
    // Serial.println("RTC com avaria");
    erro("RTC com avaria");
  }
  if (! RTC.isrunning())
  {
    Serial.println("RTC parado");
    // linha seguinte acerta RTC para data/hora da compilaao
    RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
    Serial.println("RTC ajustado");
    // para ajustar para uma determinada data/hora por ex:
    // 21 de Janeiro de 2014 as 03h escreveria:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop()
{
  digitalWrite(greenLEDpin, HIGH); // Inicia Escrita

  Vin = (55.00 * analogRead(0) / 1024);
  int chk = DHT11.read(DHT11PIN);
  float humid = DHT11.humidity;
  float tempC = DHT11.temperature;
  tempC = tempC - 2;  // Correco apos calibrao
  //float tempK = Kelvin(tempC);
  //float tempF = Fahrenheit(tempC);
  float dewP = dewPoint(tempC, humid);
  int luzV = analogRead(luzP);
  /*
    if (Vin < 7.50) lcd.setBacklight(0); //modo poupana de energia
    else lcd.setBacklight(TEAL);
  */
  DateTime now;
  now = RTC.now();
  uint32_t m = millis();

  //display data
  lcd.setCursor(0, 0);
  lcd.print(now.day(), DEC);
  lcd.print("/");
  lcd.print(now.month(), DEC);
  lcd.print("/");
  lcd.print(now.year(), DEC);
  lcd.print(" ");
  lcd.print(now.hour(), DEC);
  lcd.print(":");
  lcd.print(now.minute(), DEC);
  lcd.print("  ");
  lcd.setCursor(0, 1);
  lcd.print("T:");
  lcd.print(tempC, 0);
  lcd.print("C H:");
  lcd.print(humid, 0);
  lcd.print("% ");
  lcd.print("D:");
  lcd.print(dewP, 0);
  lcd.print("  ");

  // log data
  File logfile = SD.open(ficheiro, FILE_WRITE);
  if (logfile)
  {
    logfile.print(m); // millisegundos desde o inicio
    logfile.print(",");
    logfile.print(now.day(), DEC);
    logfile.print("/");
    logfile.print(now.month(), DEC);
    logfile.print("/");
    logfile.print(now.year(), DEC);
    logfile.print(",");
    logfile.print(now.hour(), DEC);
    logfile.print(":");
    logfile.print(now.minute(), DEC);
    logfile.print(":");
    logfile.print(now.second(), DEC);
    logfile.print(",");
    logfile.print(Vin, 2);
    logfile.print(",");
    logfile.print(luzV);
    logfile.print(",");
    logfile.print(tempC, 0);
    logfile.print(",");
    logfile.print(humid, 0);
    logfile.print(",");
    logfile.println(dewP, 0);
    logfile.close();
  }
  else
  {
    erro("Erro no ficheiro");
  }
#if ECHO_TO_SERIAL
  Serial.print(m); // millisegundos desde o inicio
  Serial.print(",");
  Serial.print(now.day(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.year(), DEC);
  Serial.print(",");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print(",");
  Serial.print(Vin, 2);
  Serial.print(",");
  Serial.print(luzV);
  Serial.print(",");
  Serial.print(tempC, 0);
  Serial.print(",");
  Serial.print(humid, 0);
  Serial.print(",");
  Serial.println(dewP, 0);
#endif //ECHO_TO_SERIAL

  digitalWrite(greenLEDpin, LOW); // acabou escrita

  //Teste aos butoes do LCD
  for (byte i = 0; i < 20; i++)
  {
    delay(pausa / 20);
    buttons = lcd.readButtons();
    if (buttons)
    {
      if (buttons & BUTTON_UP)
      {
        lcd.setCursor(0, 1);
        lcd.print("Vin: ");
        lcd.print(Vin, 2);
        lcd.print("V      ");
      }
      if (buttons & BUTTON_DOWN)
      {
        lcd.setCursor(0, 1);
        lcd.print("Luz: ");
        lcd.print(luzV);
        lcd.print("        ");
        delay(500); //debounce
        buttons = lcd.readButtons();
        if (buttons & BUTTON_DOWN)
        {
          now = RTC.now();
          year = now.year();
          month = now.month();
          day = now.day();
          hour = now.hour();
          minute = now.minute();
          year = RtcAdj("Ano: ", year);
          month = RtcAdj("Mes: ", month);
          day = RtcAdj("Dia: ", day);
          hour = RtcAdj("Hora: ", hour);
          minute = RtcAdj("Minutos: ", minute);
          RTC.adjust(DateTime(year, month, day, hour, minute, 0));
          lcd.setCursor(0, 1);
          char msg[] = "RTC Ajustado    ";
          lcd.print(msg);
          logfile.println(msg);
          Serial.println(msg);
        }
      }
      if (buttons & BUTTON_LEFT)
      {
        LCDColor = LCDColor - 1;
        if (LCDColor < 1) LCDColor = 1;
        lcd.setBacklight(LCDColor);
      }
      if (buttons & BUTTON_RIGHT)
      {
        LCDColor = LCDColor + 1;
        if (LCDColor > 7) LCDColor = 7;
        lcd.setBacklight(LCDColor);
      }
      if (buttons & BUTTON_SELECT)
      {
        if (LCDColor  > 0)LCDColor = 0;
        else LCDColor = (TEAL);
        lcd.setBacklight(LCDColor);
      }
    }
  }
}

Schematics

Temperature and humidity Sensor DHT11 connections
The DHT11 is mounted on the prototyping area of the data logger shield. The diagram is the one showed in this picture.
Dht11 conections 2hxjtsoh1d
Sensor Diagram
Fritzing Schematic
sensor_diagram_8g1IRngv7Q.fzz
Sensor Connection Diagram
jpg file, showing how to connect the sensors
Sensor diagram x4gcgbzb0p
Display connections
4 wires is all you need to connect this display
A 6lcskzoaxj

Comments

Similar projects you might like

Temperature and Humidity Data Logger

Project tutorial by Wimpie van den Berg

  • 23,414 views
  • 2 comments
  • 22 respects

DHT11 Humidity + Temperature Sensor with 16x2 LCD display

Project showcase by onatto22

  • 9,068 views
  • 1 comment
  • 17 respects

Date, Time, Temperature and Humidity Display

Project tutorial by Chamath Vithanawasam

  • 15,795 views
  • 9 comments
  • 38 respects

Beautifully Finished Humidity and Temperature Sensor

Project tutorial by Wicked Makers

  • 16,866 views
  • 21 comments
  • 135 respects

Temperature and Humidity Data logger - Breadboard

Project tutorial by Jed Hodson

  • 7,590 views
  • 2 comments
  • 9 respects

Arduino Temperature - Humidity - Rain Sensor

Project showcase by Rick_Findus

  • 7,412 views
  • 6 comments
  • 13 respects
Add projectSign up / Login