A field data recorder that runs for weeks on a battery, logs readings every minute to a removable SD card, and requires no internet connection — that is what an arduino datalogger sd card project delivers. Whether you are monitoring soil temperature in a greenhouse, tracking humidity in a server room, or recording vibration in industrial machinery, an Arduino datalogger is a low-cost, reliable, and endlessly customisable solution. This complete guide walks you through selecting hardware, wiring the circuit, writing robust logging code, and deploying your datalogger in the field.
Components You Need
A typical Arduino datalogger requires these core components:
- Arduino board: Uno, Nano, or Mega depending on your I/O needs
- SD card module: SPI-based microSD breakout board (3.3 V logic with level shifters built in)
- RTC module: DS3231 or DS1307 for accurate timestamps
- Sensor(s): Temperature, humidity, pressure, light, or any analog/digital sensor
- MicroSD card: Class 4 or higher, formatted as FAT16 or FAT32, 2–32 GB
- Power supply: LiPo battery + TP4056 charger for field deployment
- Optional: Status LED, push button for manual log trigger
For this guide, we will build a temperature and humidity datalogger using a DHT20 sensor, a DS3231 RTC, and a standard microSD breakout module.
Understanding the SD Card Module
The SD card module communicates with Arduino via SPI (Serial Peripheral Interface). The module typically includes a 3.3 V regulator and level shifters to interface the 5 V Arduino with the 3.3 V SD card. The key pins are:
- MOSI (Master Out Slave In) — data from Arduino to SD card
- MISO (Master In Slave Out) — data from SD card to Arduino
- SCK (Serial Clock) — timing signal
- CS (Chip Select) — selects the SD card when pulled LOW
SD Card Preparation
Before use, format your SD card as FAT32 using the official SD Card Formatter tool from sdcard.org (not Windows’ built-in formatter for cards over 32 GB). Create a folder called LOGS/ on the card to keep your data files organised. The Arduino SD library uses the 8.3 filename format (8-character name, 3-character extension). File names like LOG001.CSV work perfectly.
SD Card Write Performance
SD card write speed varies significantly by card brand and class. Class 10 cards are faster than Class 4, but both are more than adequate for dataloggers sampling at rates below 100 Hz. The main bottleneck is the SPI bus speed, which the Arduino SD library defaults to 4 MHz. For dataloggers, slow write speed is rarely a concern since log intervals are typically 1–60 seconds.
Adding Real-Time Clock (RTC) for Timestamps
An RTC module adds battery-backed timekeeping that persists even when your Arduino is unpowered. The DS3231 is the gold standard for DIY dataloggers — it has a built-in temperature-compensated crystal (TCXO) that maintains ±2 ppm accuracy (about 1 minute drift per year), compared to ±20 ppm for the cheaper DS1307.
Why Not Use millis() for Timestamps?
millis() counts milliseconds since the last reset. If the Arduino loses power (battery dies, power interruption), the counter resets to zero and you lose all timestamp reference. The RTC’s coin cell battery (CR2032) maintains the time for 5–10 years regardless of main power.
Setting the DS3231
#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {
rtc.begin();
// Set time to compile time (only needed once!)
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
Upload this once to set the time. After that, remove the line — the RTC keeps time independently and you never need to reset it until the coin cell dies.
Complete Circuit Wiring
All connections for a DHT20 + DS3231 + SD card datalogger on Arduino Uno:
SD Card Module
- MOSI → Arduino pin 11
- MISO → Arduino pin 12
- SCK → Arduino pin 13
- CS → Arduino pin 10
- VCC → Arduino 5V
- GND → Arduino GND
DS3231 RTC (I2C)
- SDA → Arduino pin A4
- SCL → Arduino pin A5
- VCC → Arduino 5V (or 3.3V — module has its own regulator)
- GND → Arduino GND
DHT20 Sensor (I2C)
- SDA → Arduino pin A4 (shared I2C bus with DS3231)
- SCL → Arduino pin A5
- VCC → Arduino 5V
- GND → Arduino GND
Both the DS3231 (address 0x68) and DHT20 (address 0x38) have different I2C addresses, so they share the same two-wire bus without any additional configuration.
Full Datalogger Code
Here is a complete, production-ready datalogger sketch with error handling, SD card presence detection, and graceful failure modes:
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
#include <Aosong_DHT20.h>
#define SD_CS_PIN 10
#define LOG_INTERVAL 60000UL // Log every 60 seconds
#define LED_PIN 7 // Status LED
#define FILENAME "DATA.CSV"
RTC_DS3231 rtc;
DHT20 dht20;
bool sdReady = false;
unsigned long lastLog = 0;
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
// Init RTC
if (!rtc.begin()) {
Serial.println("RTC not found!");
while (1) blink(3); // 3 blinks = RTC error
}
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Init DHT20
dht20.begin();
// Init SD card
if (!SD.begin(SD_CS_PIN)) {
Serial.println("SD card init failed!");
while (1) blink(5); // 5 blinks = SD error
}
sdReady = true;
// Write CSV header if file does not exist
if (!SD.exists(FILENAME)) {
File f = SD.open(FILENAME, FILE_WRITE);
if (f) {
f.println("Timestamp,Temperature_C,Humidity_pct,Status");
f.close();
}
}
Serial.println("Datalogger ready!");
blink(1);
}
void loop() {
if (millis() - lastLog >= LOG_INTERVAL) {
lastLog = millis();
logData();
}
}
void logData() {
DateTime now = rtc.now();
// Read DHT20
int status = dht20.read();
float tempC = dht20.getTemperature();
float humPct = dht20.getHumidity();
// Build timestamp string: YYYY-MM-DD HH:MM:SS
char timestamp[20];
snprintf(timestamp, sizeof(timestamp), "%04d-%02d-%02d %02d:%02d:%02d",
now.year(), now.month(), now.day(),
now.hour(), now.minute(), now.second());
// Print to Serial for debugging
Serial.print(timestamp);
Serial.print(","); Serial.print(tempC, 2);
Serial.print(","); Serial.println(humPct, 2);
// Write to SD card
if (sdReady) {
File f = SD.open(FILENAME, FILE_WRITE);
if (f) {
f.print(timestamp); f.print(",");
f.print(tempC, 2); f.print(",");
f.print(humPct, 2); f.print(",");
f.println((status == DHT20_OK) ? "OK" : "ERR");
f.close();
blink(1); // Confirm write
} else {
Serial.println("File open failed!");
}
}
}
void blink(int times) {
for (int i = 0; i < times; i++) {
digitalWrite(LED_PIN, HIGH); delay(150);
digitalWrite(LED_PIN, LOW); delay(150);
}
}
This sketch uses a status field in the CSV to flag any sensor read errors, making it easy to identify bad readings in post-processing. The LED provides visual confirmation of each successful log write — essential when deployed in the field without a laptop connected.
CSV File Format and Data Analysis
The output CSV file can be opened directly in Microsoft Excel, Google Sheets, or LibreOffice Calc. A typical file looks like this:
Timestamp,Temperature_C,Humidity_pct,Status 2025-06-15 08:00:00,28.40,65.20,OK 2025-06-15 08:01:00,28.45,65.10,OK 2025-06-15 08:02:00,28.50,64.90,OK
Python Analysis
For automated analysis, use pandas:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('DATA.CSV', parse_dates=['Timestamp'])
df = df[df['Status'] == 'OK'] # Exclude error rows
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
df.plot(x='Timestamp', y='Temperature_C', ax=ax1, title='Temperature Log')
df.plot(x='Timestamp', y='Humidity_pct', ax=ax2, title='Humidity Log', color='blue')
plt.tight_layout()
plt.savefig('report.png', dpi=150)
plt.show()
Avoiding Data Corruption
Always use f.close() after writing. The SD library buffers writes in RAM and only commits them to the physical card on close. If power is lost before close, the last write is lost. For logging intervals of 60 seconds, this is generally acceptable. For critical applications, use f.flush() after every write (slower but safer).
Battery Power and Low-Power Operation
A standard Arduino Uno running continuously draws about 45–50 mA. A 3000 mAh LiPo would last only 60 hours. For week-long deployments, power management is essential.
Sleep Mode
Use the AVR sleep modes to reduce current consumption between log events:
#include <avr/sleep.h>
#include <avr/wdt.h>
void sleepSeconds(int seconds) {
for (int i = 0; i < seconds / 8; i++) {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
wdt_enable(WDTO_8S); // Wake every 8 seconds
sleep_cpu();
sleep_disable();
}
}
In SLEEP_MODE_PWR_DOWN, the ATmega328P draws only 0.1–0.36 µA (with the brown-out detector disabled). Combined with the DS3231’s 3 µA sleep current and the SD card’s 0.1 mA standby current, a well-designed datalogger can achieve <1 mA average current — meaning a 3000 mAh battery lasts over 125 days.
Hardware Modifications for Ultra-Low Power
- Remove the power LED from the Arduino board (desolder or cut the LED)
- Replace the AMS1117 5V regulator with a more efficient MIC5219 or similar
- Use an Arduino Pro Mini 3.3V/8MHz — draws only 0.1 mA in active mode
- Power the SD card directly from a GPIO pin (only activate during writes)
Field Deployment Tips
Weatherproofing
For outdoor deployment, house your electronics in an IP65-rated enclosure. Use cable glands for sensor wires. Apply conformal coating to the PCB to resist moisture. The DS3231 module should be inside the enclosure; temperature/humidity sensors can be external with weatherproof versions (e.g., DS18B20 in stainless steel probe housing).
SD Card Reliability
- Use industrial-grade SD cards (e.g., SanDisk Industrial, Kingston Industrial) for extended temperature range and write-cycle endurance
- Implement a log rotation scheme: new file per day (
YYYYMMDD.CSV) to keep file sizes manageable - Log a checksum or record count at the end of each session to detect incomplete writes
Daily File Naming
char filename[13];
DateTime now = rtc.now();
snprintf(filename, sizeof(filename), "%04d%02d%02d.CSV",
now.year(), now.month(), now.day());
// Creates files like: 20250615.CSV
Remote Monitoring Upgrade
Combine your SD card datalogger with an ESP8266 or ESP32 for Wi-Fi upload. The Arduino handles sensor reading and SD logging (offline backup). Periodically, the ESP reads the latest CSV row and posts it to a dashboard like ThingSpeak, Grafana, or your own web server. This hybrid approach gives you both reliable local storage and remote monitoring.
Frequently Asked Questions
What SD card size should I use for an Arduino datalogger?
For most applications, 2–8 GB is more than sufficient. Logging temperature and humidity once per minute produces about 50 bytes per row including the timestamp. Over one year, that is 26 MB — easily fitting on even a 512 MB card. Use Class 10 or higher for better write reliability, and always format with FAT32 (not exFAT, which the Arduino SD library does not support).
My Arduino freezes when writing to the SD card — what is wrong?
The most common causes are: (1) insufficient power — SD cards draw up to 100 mA during writes, which can cause voltage drops on 3.3 V rails; (2) CS pin conflict — if another SPI device (like an Ethernet shield) is not properly deselected, it can corrupt the SPI bus; (3) fragmented SD card — reformat the card if it has many files. Always power the SD module from 5 V through its built-in regulator rather than directly from the 3.3 V pin.
Can I log data faster than once per second?
Yes, but SD card writes take 10–50 ms each (due to FAT table updates). For fast logging (>10 Hz), buffer readings in RAM and write in blocks. Accumulate 100–500 samples in a byte array, then write the entire block in one SD operation. The Arduino’s 2 KB RAM limits buffer size, so the Mega (8 KB) or Nano Every (6 KB) are better choices for high-speed logging.
Does the DS3231 need any additional components?
Most DS3231 breakout modules (including the popular ZS-042 variant) come with the CR2032 battery holder, pull-up resistors for I2C, and decoupling capacitors already installed. Plug it in and it works. Check that the CR2032 battery is installed before your first deployment — without it, the time resets every power cycle.
How do I retrieve data from the SD card?
Simply remove the microSD card and insert it into your computer using a card reader. The CSV files appear as standard files in Windows Explorer, macOS Finder, or any Linux file manager. Open them directly in Excel, or copy them to your computer for analysis. Alternatively, add an SD card reading sketch that outputs CSV data over Serial so you can retrieve data without removing the card from the field installation.
Build your first field datalogger today. Explore our full range of Arduino boards, sensors, and electronic components at Zbotic — everything you need to build reliable data acquisition systems, delivered fast across India.
Add comment