Clock and memory on an Arduino Uno
A DS1307 and a 24LC256 on one I2C bus: the time written to EEPROM once a second, acknowledge polling through every write cycle, and the log read back. The whole build, an Arduino Uno and 2 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
IntermediateRuns in your browser. Free, and no account needed.
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// A DS1307 clock and a 24LC256 EEPROM on one bus: a time-stamped log.
//
// Both chips are on A4 and A5. The clock is at 0x68 and the memory at 0x50,
// which is the whole reason two devices can share two wires.
//
// Once a second the sketch reads the time and writes a four-byte record to
// the EEPROM: hours, minutes, seconds and a count. A write to the 24LC256 is
// only a request; the chip then goes away for up to 5 ms to do it, and does
// not answer its own address until it is done. So after each write the sketch
// polls the address until it is acknowledged again, and prints how many polls
// that took. Every eight records it reads the whole log back.
//
// A new DS1307 is stopped, at 2000-01-01, until something starts it. The
// clock here has been running on its coin cell; tick the part's `halted`
// property to see the sketch find it stopped and start it.
#include <Wire.h>
#include "RTClib.h"
const uint8_t EEPROM_ADDRESS = 0x50;
RTC_DS1307 rtc;
uint8_t count = 0;
void writeRecord(unsigned int at, const uint8_t *record) {
Wire.beginTransmission(EEPROM_ADDRESS);
Wire.write((uint8_t)(at >> 8));
Wire.write((uint8_t)at);
Wire.write(record, 4);
Wire.endTransmission();
// Acknowledge polling: an empty write, until the chip answers again.
int polls = 0;
do {
Wire.beginTransmission(EEPROM_ADDRESS);
polls++;
} while (Wire.endTransmission() != 0);
Serial.print(" (busy for ");
Serial.print(polls);
Serial.println(" polls)");
}
void print2(uint8_t value) {
if (value < 10) Serial.print('0');
Serial.print(value);
}
void setup() {
Serial.begin(9600);
Wire.begin();
if (!rtc.begin()) {
Serial.println("no clock at 0x68");
while (1) delay(10);
}
if (!rtc.isrunning()) {
Serial.println("the clock is halted: starting it");
rtc.adjust(DateTime(2026, 9, 23, 12, 0, 0));
}
}
void loop() {
DateTime now = rtc.now();
uint8_t record[4] = {now.hour(), now.minute(), now.second(), count};
print2(record[0]);
Serial.print(':');
print2(record[1]);
Serial.print(':');
print2(record[2]);
Serial.print(" record ");
Serial.print(count);
writeRecord((unsigned int)(count % 8) * 4, record);
count++;
if (count % 8 == 0) {
Serial.println("the log, read back:");
Wire.beginTransmission(EEPROM_ADDRESS);
Wire.write(0);
Wire.write(0);
Wire.endTransmission(false);
Wire.requestFrom(EEPROM_ADDRESS, 32);
for (int i = 0; i < 8; i++) {
uint8_t r[4];
for (int j = 0; j < 4; j++) r[j] = Wire.read();
Serial.print(" ");
print2(r[0]);
Serial.print(':');
print2(r[1]);
Serial.print(':');
print2(r[2]);
Serial.print(" #");
Serial.println(r[3]);
}
}
delay(1000);
}
Parts list
4 parts, plus the jumper wires. Every one is in the editor's parts bin.
How it is wired
4 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.
- Arduino Uno R3 pin 5V; I2C EEPROM, 24LC256 pin VCC; Real-time clock, DS1307 pin VCC
- Ground: Arduino Uno R3 pin GND; I2C EEPROM, 24LC256 pin VSS; Real-time clock, DS1307 pin GND
- Arduino Uno R3 pin A4; I2C EEPROM, 24LC256 pin SDA; Real-time clock, DS1307 pin SDA
- Arduino Uno R3 pin A5; I2C EEPROM, 24LC256 pin SCL; Real-time clock, DS1307 pin SCL
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.