Go back

I2C RTC Clock with DS1307 on Velxio

Introduction

Ever wanted to add a real-time clock to your Arduino project but didn’t have the hardware handy? With Velxio, you can simulate an I2C RTC (DS1307) right in your browser. In this tutorial, we’ll build a simple I2C reader that fetches the current time and date from a virtual DS1307 and prints it to the Serial Monitor. No external libraries needed—just the built-in Wire library.

Circuit diagram of i2c-rtc-read on the Velxio simulator canvas

Circuit Walkthrough

This example is remarkably simple because the DS1307 is already integrated into the virtual Arduino Uno board. There are no external components or wires to add. The I2C bus (SDA on A4, SCL on A5) is internally connected to the DS1307 at address 0x68. The only component is the Arduino Uno itself.

Velxio component picker modal browsing parts by category

To start, open the Velxio editor and select an Arduino Uno from the component picker. The DS1307 is built into the simulation environment, so you don’t need to add it separately. The circuit is ready to go.

Code Walkthrough

Let’s break down the code step by step.

Include and Define

#include <Wire.h>

#define DS1307_ADDR 0x68

We include the Wire library for I2C communication and define the DS1307’s I2C address as 0x68.

BCD to Decimal Conversion

byte bcdToDec(byte val) {
  return ((val >> 4) * 10) + (val & 0x0F);
}

The DS1307 stores time values in Binary-Coded Decimal (BCD) format. This helper converts a BCD byte to a regular decimal number.

Setup

void setup() {
  Wire.begin();
  Serial.begin(9600);

  Serial.println("===========================");
  Serial.println("  DS1307 RTC Reader (I2C)");
  Serial.println("===========================");
  Serial.println();
}

We initialize the I2C bus and Serial communication at 9600 baud. Then we print a header.

Loop

void loop() {
  // Set register pointer to 0 (seconds)
  Wire.beginTransmission(DS1307_ADDR);
  Wire.write(0x00);
  Wire.endTransmission();

  // Request 7 bytes: sec, min, hr, dow, date, month, year
  Wire.requestFrom(DS1307_ADDR, 7);

  if (Wire.available() >= 7) {
    byte sec   = bcdToDec(Wire.read() & 0x7F);
    byte min   = bcdToDec(Wire.read());
    byte hr    = bcdToDec(Wire.read() & 0x3F);
    byte dow   = bcdToDec(Wire.read());
    byte date  = bcdToDec(Wire.read());
    byte month = bcdToDec(Wire.read());
    byte year  = bcdToDec(Wire.read());

    // Print formatted time
    Serial.print("Time: ");
    if (hr < 10) Serial.print("0");
    Serial.print(hr);
    Serial.print(":");
    if (min < 10) Serial.print("0");
    Serial.print(min);
    Serial.print(":");
    if (sec < 10) Serial.print("0");
    Serial.print(sec);

    Serial.print("  Date: ");
    if (date < 10) Serial.print("0");
    Serial.print(date);
    Serial.print("/");
    if (month < 10) Serial.print("0");
    Serial.print(month);
    Serial.print("/20");
    if (year < 10) Serial.print("0");
    Serial.println(year);
  } else {
    Serial.println("Error: Could not read RTC");
  }

  delay(1000);
}

In the loop, we first set the DS1307’s register pointer to 0 (seconds register) by sending a single byte 0x00. Then we request 7 bytes from the RTC. The DS1307 returns seconds, minutes, hours, day-of-week, date, month, and year in BCD. We mask the top bit of seconds (bit 7 is the clock halt flag) and the top two bits of hours (bits 6-7 are mode/AM-PM). After conversion, we print the time and date with leading zeros. If fewer than 7 bytes are available, we print an error. Finally, we wait 1 second.

Key Concepts

Common Pitfalls and Debugging Tips

Velxio editor toolbar with compile and run controls

Suggested Extensions

Try It Yourself

Ready to see it in action? Open the live example on Velxio and hit the Run button. You’ll see the time updating every second in the Serial Monitor.

Launch the I2C RTC Reader on Velxio

Velxio canvas toolbar above the simulation viewport

Happy simulating!


Share this post on:
David Montero

Written by

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

Related posts


Previous Post
I2C EEPROM Read/Write with Arduino: A Complete Guide
Next Post
I2C Scanner with Arduino: Find Every Device on the Bus