Temperature Logger with Arduino

In this post, we will build a temperature logger. This can than be deployed to monitor the temperature of a room or the environment. We will read the temperature every 15 minutes and store it in SD card.

This post builds upon three topics discussed earlier:

  1. Monitor Temperature with LM35 Temperature Sensor

  2. SD Card with Arduino

  3. RTC with Arduino – DS1307 and DS3231

Make sure to check out these posts. You will get a better understanding about the different modules used in this project.

Block Diagram and Approach:

Our approach to this project is very simple. Let me describe the steps:

  1. Read the time from the RTC. If the minutes is a multiple of 15, go to step 2. Else, do nothing
  2. Read the temperature from the temperature sensor
  3. Store the time and the temperature in the SD card

Essentially, what we are doing is that we will store the temperature once every 15 minutes, i.e., every time the minutes read 00, 15, 30 or 45.Temperature Logger with Arduino block diagramWe will use an RTC (Real Time Clock) to note the time. That way, we know the exact time stamp of any particular temperature record. Even if the power goes off, the time does not start from zero.

Temperature Logger Circuit Connections:

Temperature Logger with Arduino circuit

 

Temperature Logger Code:

#include <SPI.h>
#include <SD.h>
#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68

File dataFile;
byte stored=0;

void setup() 
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial); // wait for serial port to connect. Needed for native USB port only

  Serial.print("Initializing SD card...");
  if (!SD.begin(10)) 
  {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  Wire.begin();
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return( (val/16*10) + (val%16) );
}

void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}
void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}

void loop()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

  // Store temperature only once every 15 minutes
  if(minute%15==0 && stored==0)  
  {
    Serial.print("Writing to data.txt...");
    dataFile = SD.open("data.txt", FILE_WRITE);
    if (dataFile) 
    {
      dataFile.print(hour, DEC);
      // convert the byte variable to a decimal number when displayed
      dataFile.print(":");
      if (minute<10)
      {
        dataFile.print("0");
      }
      dataFile.print(minute, DEC);
      dataFile.print(":");
      if (second<10)
      {
        dataFile.print("0");
      }
      dataFile.print(second, DEC);
      dataFile.print(" ");
      dataFile.print(dayOfMonth, DEC);
      dataFile.print("/");
      dataFile.print(month, DEC);
      dataFile.print("/");
      dataFile.print(year, DEC);
      dataFile.print(" - ");
      dataFile.println(readTemperature());
      Serial.println(readTemperature());
      dataFile.close();
      Serial.println("done.");
      stored=1;
    } 
    else 
    {
      // if the file didn't open, print an error:
      Serial.println("error opening data.txt");
    }
  }
  else if(minute%15 != 0)
  {
    stored=0;
  }
  else{}
  delay(50000); // every 50 second
}

//Function to read the temperature
float readTemperature()
{
    float ADCValue;
    float tempVoltage = 0;
    float temp = 0;
    ADCValue = analogRead(A0);
    tempVoltage = (float)((5.0/1023)*ADCValue)*1000.0; //sensor output in milli volts
    temp = (float)tempVoltage/10.0; //temperature in Celcius
    return temp;
}

Output:

After letting the code run for a few hours, you will get a file in the SD card with data that looks like this.

Improvements:

One of the drawbacks we have in this system is that the code is always running. Even though we are not doing anything for almost 15 minutes. Once every 15 minutes we log the temperature and then go back to doing nothing.

A major improvement that can be done is to make the Arduino go to sleep after it has recorded the temperature. That way, the power consumption will be significantly reduced. Once every 15 minutes, read and store the temperature and go back to sleep.

Sharing is Caring!!

Leave a Reply

Your email address will not be published. Required fields are marked *