Data logging is one of the most practical skills you can develop with Arduino. Whether you are monitoring temperature in a greenhouse, tracking voltage in a battery bank, or recording environmental conditions over days or weeks, a reliable data logger can transform your Arduino project from a simple demo into a real-world tool. This guide walks you through building a complete Arduino SD card data logger with accurate timestamps using a Real-Time Clock (RTC) module.
Table of Contents
- What You Need
- Understanding the Real-Time Clock (RTC)
- SD Card Module Wiring
- RTC Module Wiring
- Required Libraries and Setup
- Complete Data Logger Code
- CSV File Format and Reading Data
- Troubleshooting Common Issues
- FAQ
What You Need
Before you begin, gather all the hardware and software components. A well-planned parts list saves time and prevents mid-project frustration.
Hardware required:
- Arduino Uno R3 or compatible board
- DS3231 or DS1307 RTC module
- Micro SD card module (SPI interface)
- Micro SD card (FAT32 formatted, up to 32 GB)
- DHT11 or DHT22 temperature and humidity sensor (or your preferred sensor)
- Jumper wires and breadboard
- CR2032 coin cell battery for the RTC module
Understanding the Real-Time Clock (RTC)
The Real-Time Clock is the heart of any timestamped data logger. Without an RTC, you would only know how many milliseconds have passed since the Arduino was powered on, not the actual date and time. This makes your data nearly useless for long-term analysis.
Two RTC modules are commonly used with Arduino:
DS1307: A basic, affordable RTC that communicates over I2C. It runs from 5V and keeps time accurately when powered. However, it can drift by a few minutes per month and lacks temperature compensation.
DS3231: The superior choice for most projects. It includes an integrated temperature-compensated crystal oscillator (TCXO), which keeps it accurate to within ±2 minutes per year. It also operates from 3.3V to 5.5V and includes a built-in temperature sensor you can use as an additional data point.
Both modules use the I2C interface (SDA and SCL pins) and require a CR2032 coin cell battery to maintain time when the main power is disconnected. Always install the battery before setting the time.
The DS3231 uses 7-bit address 0x68 on the I2C bus. You can connect multiple I2C devices (sensors, displays, etc.) to the same SDA/SCL lines as long as each has a unique address.
SD Card Module Wiring
The SD card module communicates with Arduino over SPI (Serial Peripheral Interface). On the Arduino Uno, the SPI pins are fixed:
- MOSI → Pin 11
- MISO → Pin 12
- SCK (Clock) → Pin 13
- CS (Chip Select) → Pin 4 (configurable)
- VCC → 5V
- GND → GND
The CS pin can be any digital pin, but pin 4 is the standard choice and matches most library examples. If you are using the Arduino Mega 2560, the SPI pins change to 51 (MOSI), 50 (MISO), and 52 (SCK).
SD card modules typically include a 3.3V voltage regulator and level shifter on board, so you can safely connect them to a 5V Arduino. Check your specific module’s datasheet — some cheaper modules omit the level shifter, which can damage the SD card over time.
Always format your SD card as FAT32. The Arduino SD library does not support exFAT or NTFS. For cards larger than 32 GB, use a tool like SD Card Formatter (official tool from the SD Association) to force FAT32 formatting.
RTC Module Wiring
The DS3231 RTC connects over I2C. On the Arduino Uno:
- SDA → A4 (Analog pin 4)
- SCL → A5 (Analog pin 5)
- VCC → 3.3V or 5V (check your module)
- GND → GND
On the Arduino Mega 2560, I2C uses pins 20 (SDA) and 21 (SCL) instead of A4/A5.
Note that the I2C bus is shared — your sensor modules, RTC, and any OLED display all connect to the same SDA and SCL lines. Each device simply needs a unique I2C address. The SD card module uses SPI, which is a separate bus entirely, so there is no conflict.
Pull-up resistors (4.7 kΩ) on SDA and SCL are required for I2C to work reliably. Most RTC breakout boards include these on board. If you are using bare IC chips, you must add external pull-ups.
Required Libraries and Setup
You need three libraries for this project. Open the Arduino IDE, go to Sketch → Include Library → Manage Libraries, and search for each:
- SD (built-in) — handles SD card read/write operations
- RTClib by Adafruit — clean interface for DS1307 and DS3231 modules
- DHT sensor library by Adafruit (if using DHT11/DHT22)
After installing RTClib, you also need the Adafruit BusIO library as a dependency. The library manager usually handles this automatically.
Before deploying your logger, run the ds3231_set_time example from the RTClib library examples to synchronize your RTC with the current time. Once set, the coin cell battery keeps the time even when you disconnect the Arduino.
Complete Data Logger Code
Here is a complete, well-commented sketch that reads temperature and humidity from a DHT11 sensor, fetches a timestamp from the DS3231 RTC, and writes a CSV line to the SD card every 10 seconds:
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
#include <DHT.h>
#define SD_CS_PIN 4
#define DHT_PIN 7
#define DHT_TYPE DHT11
#define LOG_INTERVAL 10000 // Log every 10 seconds
RTC_DS3231 rtc;
DHT dht(DHT_PIN, DHT_TYPE);
File logFile;
void setup() {
Serial.begin(9600);
// Initialize RTC
if (!rtc.begin()) {
Serial.println("RTC not found! Check wiring.");
while (1); // Halt
}
// Uncomment once to set time, then comment out again
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Initialize SD card
if (!SD.begin(SD_CS_PIN)) {
Serial.println("SD card init failed! Check module.");
while (1);
}
dht.begin();
// Write CSV header if file is new
if (!SD.exists("datalog.csv")) {
logFile = SD.open("datalog.csv", FILE_WRITE);
if (logFile) {
logFile.println("Date,Time,Temperature_C,Humidity_%,HeatIndex_C");
logFile.close();
}
}
Serial.println("Data logger ready.");
}
void loop() {
static unsigned long lastLog = 0;
if (millis() - lastLog >= LOG_INTERVAL) {
lastLog = millis();
DateTime now = rtc.now();
float temp = dht.readTemperature();
float hum = dht.readHumidity();
if (isnan(temp) || isnan(hum)) {
Serial.println("DHT read failed, skipping.");
return;
}
float hi = dht.computeHeatIndex(temp, hum, false);
// Format: 2024-06-15,14:32:07,28.50,65.00,30.20
String dateStr = String(now.year()) + "-"
+ pad2(now.month()) + "-"
+ pad2(now.day());
String timeStr = pad2(now.hour()) + ":"
+ pad2(now.minute()) + ":"
+ pad2(now.second());
String row = dateStr + "," + timeStr + ","
+ String(temp, 2) + ","
+ String(hum, 2) + ","
+ String(hi, 2);
// Write to SD
logFile = SD.open("datalog.csv", FILE_WRITE);
if (logFile) {
logFile.println(row);
logFile.close();
Serial.println("Logged: " + row);
} else {
Serial.println("Error opening datalog.csv");
}
}
}
String pad2(int n) {
return (n < 10 ? "0" : "") + String(n);
}
Key design decisions in this code:
- Non-blocking timing: Uses
millis()instead ofdelay(), so the Arduino can still respond to other events between log intervals. - CSV header check: Only writes the header row if the file does not yet exist, preventing duplicate headers after a power cycle.
- File open/close on every write: Opening and closing the file each time is slower, but it ensures data is actually written to the card even if power is lost unexpectedly. If you use
FILE_WRITEwithout closing, data may remain in a buffer and be lost. - Pad2 function: Ensures two-digit formatting for months, days, hours, minutes, and seconds — critical for correct date/time sorting in spreadsheet software.
CSV File Format and Reading Data
Your logger produces a standard CSV file that opens directly in Microsoft Excel, Google Sheets, or LibreOffice Calc. The file looks like this:
Date,Time,Temperature_C,Humidity_%,HeatIndex_C
2024-06-15,14:32:07,28.50,65.00,30.20
2024-06-15,14:32:17,28.60,64.80,30.25
2024-06-15,14:32:27,28.55,65.10,30.22
In Excel, use the Date and Time columns together to create a combined datetime axis for charts. Select both columns, use Data → Text to Columns if needed, then create a line chart with time on the X axis.
Analysing your data in Python:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('datalog.csv')
df['datetime'] = pd.to_datetime(df['Date'] + ' ' + df['Time'])
df.set_index('datetime', inplace=True)
df['Temperature_C'].plot(title='Temperature Over Time')
plt.ylabel('°C')
plt.show()
This simple script loads your CSV, parses the datetime, and plots temperature over time — a useful starting point for any data analysis workflow.
Troubleshooting Common Issues
SD card init failed:
- Check that the CS pin number in your code matches the physical wiring
- Ensure the card is FAT32 formatted
- Try a different SD card — some cards are not compatible with the SD library
- Check power supply — SD card modules can draw more current than the Arduino 3.3V pin can supply. Use the 5V pin if your module has a regulator
- On the Arduino Mega, pin 53 (SS) must be set as OUTPUT even if you use a different CS pin
RTC shows wrong time or year 2000:
- Install a fresh CR2032 battery in the RTC module
- Uncomment the
rtc.adjust()line, upload, wait 10 seconds, then comment it out and re-upload - Check I2C wiring — SDA to A4, SCL to A5 on Uno
DHT reading fails (NaN values):
- Add a 10 kΩ pull-up resistor between the data pin and VCC
- Use
delay(2000)afterdht.begin()— the DHT sensor needs 1-2 seconds to stabilise - Try a lower log frequency (30 seconds instead of 10) — the DHT11 supports only one reading every 2 seconds
Data file is missing or corrupt:
- Never remove the SD card while the logger is running without pressing reset first
- Use the
logFile.close()call after every write — this flushes the buffer and updates the file allocation table - Avoid power cycling the Arduino mid-write
Frequently Asked Questions
How long can an Arduino SD card data logger run on battery power?
This depends heavily on the power management strategy. A standard Arduino Uno drawing 50 mA continuously from a 2500 mAh LiPo will last about 50 hours. Using the AVR sleep modes (power-down between readings) can extend this to weeks. The DS3231 draws only 2 µA in standby, and the SD card draws about 200 µA in idle mode. For long-term deployments, use an Arduino Pro Mini at 3.3V/8 MHz with sleep modes enabled — current consumption can drop below 1 mA between readings.
How much data can I store on an SD card?
Each CSV line in the example above is roughly 40 bytes. Logging every 10 seconds produces about 12 MB of data per month. A 1 GB SD card holds over 80 months of data at that rate. Logging every second would fill about 3.5 GB per month — still manageable with modern SD cards up to 32 GB.
Can I log multiple sensors at once?
Yes. Simply read each sensor in the loop, add the values to your CSV row string, and write everything in one line per interval. For many sensors, keep the log interval at 30 seconds or more to prevent file write operations from stacking up. If you need many sensors, the Arduino Mega gives you more I/O pins and SRAM.
What is the difference between DS1307 and DS3231?
The DS3231 is more accurate (±2 min/year vs ±2 min/month for DS1307), includes a built-in temperature sensor, and has a temperature-compensated oscillator. For most data logging projects where accuracy matters, the DS3231 is worth the small price difference. The DS1307 is fine for casual use where time drift of a few minutes per month is acceptable.
Why does my RTC lose time when Arduino is powered off?
The RTC module needs a CR2032 backup battery to maintain time when the main power is removed. Check that the battery is installed correctly (positive side up), has charge (measure with a multimeter — should read 3V), and that the battery holder contacts are clean. Some cheap modules arrive with dead batteries or bad contacts.
Building an Arduino SD card data logger with RTC timestamps opens the door to a huge range of real-world monitoring projects — from home weather stations and greenhouse monitors to UPS battery tracking and industrial sensor logging. With the foundation in this guide, you can swap in any sensor and start collecting meaningful, time-stamped data immediately.
Ready to start your data logging project? Browse our full range of Arduino boards, sensors, and accessories at Zbotic.in — everything you need for your next maker project, shipped fast across India.
Add comment