Table of Contents
KEY TAKEAWAYS
- A temperature logger combines a temperature sensor, RTC module, and SD card with Arduino
- The RTC provides accurate timestamps while the sensor provides temperature readings
- Data is written to a CSV file on the SD card at regular intervals for later analysis
- This project demonstrates practical integration of multiple components in an embedded data acquisition system
Block Diagram and Approach:
Our approach to this project is very simple. Let me describe the steps:- Read the time from the RTC. If the minutes is a multiple of 15, go to step 2. Else, do nothing
- Read the temperature from the temperature sensor
- Store the time and the temperature in the SD card

Temperature Logger Circuit Connections:

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.
Vivek Bhageria — Lead Firmware R&D Engineer, 12+ years. Ex-Bosch (automotive powertrain), MusicTribe (real-time audio), medical devices. M.Tech BITS Pilani. I write at NerdyElectronics — practical, register-level embedded systems for engineers who want to understand what’s actually happening under the hood.







