Keep accurate time using Real Time Clock (RTC)

The Arduino board can keep time using millis() which increment from boot up till shutdown, then it will start over again. But what if we needed to keep time indefinitely, independently whether the board is switched on or off? What if we don’t want millis() but we want the year, month, day and time? How do we compensate for leap years?
No worries. We are fortunate enough to have the DS1307 Real Time Clock and Adafruit has provided us with a really good library to access all its features. The module requires a CR1225 (or other) battery to keep running even when you pull the plug on the Arduino.


Remember to download and install the Adafruit library for the RTC which can be found here (https://github.com/adafruit/RTClib). If you have problems installing the library follow our tutorial here (http://runtimeprojects.com/2016/03/arduino-beginners-course-lesson-5-installing-and-using-libraries/).

The RTC requires only 4 pins to connect it on the Arduino Uno, as follows:

  • +5V –> VCC
  • GND –> GND
  • SCL –> A5
  • SDA –> A4

The SQW is a square-wave output and it’s optional. Most of us do not require this pin so we will leave it aside for now.

The Sketch

The following sketch is intended to demonstrate how can we use the RTC library. We will output the current date and time to serial, then do some calculations on the date and time, and output it again.

Let’s start by including libraries.

#include "RTClib.h"

The following lines creates the RTC object and creates a list of days of the week, in English.

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

Next up is the setup function. Here we’re initializing the Serial object and the RTC object.

void setup () {
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
  } else {
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));  

In order to set an accurate time we use the

rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

This will initialize the RTC with the time the sketch is compiled, obviously using the date and time of your PCs.

In the loop function we make use of the ‘now’ object of type DateTime to store the current time, then output the required date information to serial port.

void loop () {
    DateTime now = rtc.now();
    Serial.print(now.year(), DEC);
    Serial.print(now.month(), DEC);
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(now.minute(), DEC);
    Serial.print(now.second(), DEC);
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);

We can do more with this library. We can go backward and forward in time using the TimeSpan type.

Here we created another instance of DateTime called ‘future’, with the difference that we pass the ‘now’ parameter, which is the current date time object, and we add a time span of 7 days, 2 hours, 30 minutes and 6 seconds to the current time. We then output the future date and time to the serial port.

    DateTime future (now + TimeSpan(7,2,30,6));
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print(future.month(), DEC);
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(future.minute(), DEC);
    Serial.print(future.second(), DEC);

Thats how to use an RTC DS1307. Other chipsets may work but we had no experience with any other.



Leave a Reply

Your email address will not be published. Required fields are marked *