A Simple Data Logger with the DS3231 and an SD Card

A DIY data logger works by pairing two jobs that a microcontroller alone can't do well: keeping accurate wall-clock time, and storing more data than its own memory can hold. The DS3231 module handles the first job with a temperature-compensated crystal oscillator accurate to about ±2ppm (roughly a minute of drift a year) and a coin-cell backup that keeps the clock running through a power cycle or a dead battery on the main board — so a logger that's unplugged overnight still knows the correct date and time the moment it powers back up. An SD card handles the second job: an Arduino Uno has only 2KB of RAM and no persistent storage of its own, so every reading it takes has to go somewhere else the instant it's captured, and a microSD card gives it gigabytes of somewhere-else that survives a reset, a crash, or the Arduino being unplugged and carried to a computer to read the file off. Together, an RTC-stamped, SD-stored reading is something a plain millis() timestamp and the Uno's own memory can't produce on their own.

What parts does a DIY data logger need?

At minimum: a microcontroller (an Arduino Uno here), a DS3231 real-time clock module for timestamps, an SD card module to interface a microSD card over SPI, an actual microSD card to write to, whatever sensor you're logging (temperature, voltage, humidity — the logger itself is sensor-agnostic), and jumper wires. That's five active parts plus wiring. It's worth being precise about the SD card piece specifically: a bare microSD card and an "SD card module" are not the same product. The card is just flash storage with no way to talk to a 5V microcontroller; the module is a small breakout board with an SPI interface and on-board logic-level shifting that lets the Arduino actually read and write to the card without damaging it.

Why do you need a real-time clock instead of just millis()?

The Arduino's built-in millis() function returns milliseconds since the sketch started running — not since any fixed point in time. It resets to zero every time the board is reset or loses power, it overflows and wraps around after about 49 days of continuous uptime, and it has no idea what today's date is. That's fine for measuring short intervals inside a running sketch, but useless for a log file you want to open a week later and know that a given row was recorded at, say, 14:32 on a Tuesday. A DS3231 module solves this by keeping its own independent time reference — driven by a temperature-compensated crystal oscillator and backed by a CR2032 coin-cell battery (not included with the module) — so it keeps counting real calendar time even while the Arduino itself is unpowered. Every time the sketch wakes up, it can ask the DS3231 over I2C for the actual date and time and write that alongside the sensor value, instead of a meaningless millisecond counter that means nothing outside that specific power cycle.

How do you wire the DS3231 and an SD card module to an Arduino Uno?

These two modules use different buses, which is exactly why they coexist without conflict: the DS3231 talks I2C on the Uno's fixed A4/A5 pins, and the SD card module talks SPI on the Uno's fixed pins 10–13. Neither interface uses the other's pins, so both can be wired and active at the same time.

Arduino Uno DS3231 module Signal
5V VCC power
GND GND ground
A4 SDA I2C data
A5 SCL I2C clock
Arduino Uno SD card module Signal
5V VCC power
GND GND ground
D13 SCK SPI clock
D12 MISO SPI data, out of card
D11 MOSI SPI data, into card
D10 CS chip select

Compoden's own build assistant flagged the reason this needs a module rather than a direct wire from the card slot: a microSD card runs on 3.3V logic while the Arduino Uno's pins are 5V, and connecting the two directly "can damage the SD card or prevent it from working reliably." A proper SD card module carries its own onboard 3.3V regulator and level shifting specifically to sit between the two voltage domains, which is what makes it a separate part from the memory card itself. Whatever sensor you're logging (a DS18B20 temperature probe, a voltage divider, a humidity sensor) wires to whatever pins its own interface needs — typically a spare digital or analog pin, since I2C and SPI are already spoken for by the RTC and SD module.

What can you log with this setup?

Anything the Arduino can read and turn into a number on a schedule: temperature and humidity over days or weeks, a voltage or current reading from a power circuit, soil moisture on an irrigation timer, a door or motion event with a timestamp, or GPS coordinates on a moving object. The DS3231 and SD card module don't care what the data is — they just supply "when" and "where it's kept." Structuring rows as comma-separated values (a CSV file) is the common approach because it opens directly in a spreadsheet: one column for the DS3231's timestamp, one or more columns for whatever the sensor measured.

Watch it built live: a real Arduino Uno data logger project

Rather than describe a generic build, we typed one real sentence into Compoden's AI build assistant on the storefront and let it pick parts, price them, and explain the build — unscripted, screenshotted as it happened:

"I want to build a data logger that timestamps sensor readings and saves them to an SD card, using a DS3231 real-time clock module and an Arduino Uno"

Compoden AI build assistant screenshot: data logger build with Arduino Uno, DS3231 RTC module, and microSD card

It carded the Arduino Uno, the DS3231 RTC module, a MicroSD Card 8GB Class 10, and jumper wires, then explained the RTC's role directly: "The DS3231 RTC Module is a real-time clock. It keeps track of the current time and date, even when the main board is turned off, usually with a small battery (not included). It communicates with the Arduino using the I2C interface and runs on 3.3V to 5.5V. This module is essential for adding accurate timestamps to your sensor readings." On the storage side it was equally direct that a memory card alone isn't the whole story: "The MicroSD Card 8GB Class 10 is your storage... it uses either the SDIO or SPI interface to connect to the Arduino." Below the tray, the storefront itself flagged the missing piece under a "not in stock" notice rather than silently leaving it out: "a bare microSD card has no interface — the Arduino Uno R3 CH340G ATmega328P Board has no built-in SD slot, so it needs an SPI microSD card-reader module to read the card." That's an accurate, honest catch by the assistant, and it's worth repeating here rather than glossing over: at the time of this build, Compoden's dedicated MicroSD Card Reader SPI Module exists in the catalog and is priced at ₹110, but the AI build tray didn't carry it into the cart automatically. We've added it as its own line item in the parts table below so this build is actually complete.

The assistant's tray also included a Bluesky Mini 5V 3A UBEC voltage regulator, filling what it labeled a "servo power" slot — its own explanation acknowledged this was a stretch: "While listed as filling a 'servo power slot,' in this build, it could be used to provide a stable 5V power source for your Arduino... if your main power supply is higher than 12V." Nothing about a data logger needs servo power, so we've left that part out of the table below; skip it unless you're already running the Uno from something above 12V and want a regulated 5V tap.

Watch the firmware get generated

We then asked Compoden's build companion, Soldr, to write the actual Arduino sketch for this project — targeting the Uno specifically, timestamping a temperature reading with the DS3231 and writing it to a CSV file on the SD card:

Soldr firmware editor screenshot: generated Arduino sketch for the DS3231 and SD card data logger, using SPI and I2C libraries

The generated sketch included the SPI, SD, Wire, RTClib, OneWire and DallasTemperature libraries, used a DS18B20 sensor on digital pin 2 for the actual temperature reading, the DS3231 over I2C (A4/A5) for the timestamp, and the SD card over SPI with chip select on pin 10 — matching the wiring table above exactly. Soldr's own summary of the logic: "The sketch will log temperature from a DS18B20 sensor, timestamped by a DS3231 RTC, to a CSV file on an SD card... Data will be logged every 10 seconds," and it named the three libraries to install through the Arduino IDE's Library Manager before flashing: RTClib, DallasTemperature, and OneWire. One thing worth noting: Soldr's own parts-matching step separately flagged "Real-Time Clock: no match found" while building this firmware, even though the code it generated correctly used the DS3231 throughout — a mismatch between its internal catalog lookup and the actual code output that's worth knowing about if you see the same warning.

Get everything in this build

The parts this build actually needs to work, including the SD card reader module the AI assistant's tray identified as necessary but didn't add automatically — at today's live price and stock, each linking straight to checkout, or add the whole tray in one click.

Part Qty Price
Arduino Uno R3 CH340G ATmega328P Board 1 ₹230 Add to cart →
DS3231 RTC Module (I2C, battery-backed) 1 ₹180 Add to cart →
MicroSD Card Reader SPI Module for Arduino 1 ₹110 Add to cart →
MicroSD Card 8GB Class 10 1 ₹240 Add to cart →
Male-to-Male Breadboard Jumper Wires (20cm, 24 AWG) 1 ₹40 Add to cart →
Total ₹800 Add all 5 to cart →

Prices and stock verified live at the time this was written; Compoden's storefront always reflects the current price and availability at checkout. You'll also need a CR2032 coin-cell battery for the DS3231's backup clock (not included with the module) and whatever sensor you're logging — a DS18B20 temperature probe, a voltage sensor, or otherwise — since neither is part of the DS3231/SD-card timestamp-and-store combination itself.

Built and Backed by Compoden

Every part above ships from Compoden's own India stock, tested for compatibility before it's listed — not sourced individually and hoped to work. Delivery in 3–7 days across India, with COD and UPI available at checkout. If a part in this build doesn't perform as described, Compoden's support team will help you troubleshoot or replace it.

FAQ

Can I use the Arduino's millis() function instead of buying a DS3231?
Not for real timestamps. millis() counts milliseconds since the sketch last started, resets on every power cycle or reset, and has no concept of the actual date or time of day. It works for measuring short intervals inside a single run, but a log file needs to say when a reading happened in real calendar time, which only a battery-backed RTC like the DS3231 can provide across power cycles.

Do the DS3231 and the SD card module conflict with each other on the same Arduino Uno?
No. The DS3231 communicates over I2C on pins A4 (SDA) and A5 (SCL), while the SD card module communicates over SPI on pins 10–13. These are separate buses using separate pins, so both can be wired and active on the same Uno at the same time without interference.

Why can't I just wire a microSD card straight to the Arduino without a module?
A microSD card runs on 3.3V logic while the Arduino Uno's pins output 5V. Connecting the card's pins directly to the Uno risks damaging the card or getting unreliable communication. An SD card module sits between the two specifically to shift the logic levels safely, in addition to providing the physical card slot and SPI wiring the Uno needs to read and write files.

Does the DS3231 keep time if the Arduino is unplugged?
Yes, as long as its CR2032 coin-cell battery is installed. The battery is not included with the module and needs to be bought separately; without it, the DS3231 loses track of time the moment main power is removed, the same as any other chip.

Back to blog