Keeping time on Arduino projects isn't as easy as you might think: once the computer connection isn't there, your unpowered Arduino simply stops running, including its internal ticker.

In order to keep your Arduino in sync with the world around it, you're going to need what's called a "Real Time Clock module". Here's how use one.

What's the point of a Real Time Clock (RTC)?

Your computer most likely syncs its time with the internet, but it still has an internal clock that keeps going even without an Internet connection or the power is turned off. When you use an Arduino plugged into a computer, it has access to accurate time provided by your system clock. That's pretty useful, but most Arduino projects are designed to be used away from a computer - at which point, any time the power is unplugged, or the Arduino restarted, it'll have absolutely no idea of what time it is. The internal clock will be reset and start counting from zero again next time it's powered up.

If your project has anything to do with needing the time - such as my nightlight and sunrise alarm clock - this is clearly going to be an issue. In that project, we got around the issue by manually setting the time each night in a rather crude way - the user would press the reset button just before they went to bed, providing a manual time sync. Clearly that's not an ideal long-time solution.

An RTC module is an additional bit of circuitry, requiring a small coin cell battery, which continues to count the time even when your Arduino is turned off. After being set once - it will keep that time for the life of the battery, usually a good year or so.

TinyRTC

The most popular RTC for Arduino is called TinyRTC and can be bought for around $5-$10 on eBay. You'll most likely need to supply your own battery (it's illegal to ship these overseas to many places), and some headers (the pins that slot into the holes, which you'll need to solder in yourself).

This is the module I have:

rtc-module

It even has a built-in temperature sensor, though the battery will last longer if you're not using it.

The number of holes on that thing looks pretty scary, but you only need four of them; GND, VCC, SCL and SDA - you can use the relevant pins on either side of the RTC module. You talk to the clock using I2C protocol, which means only two pins are used - one for the "clock" (a serial communications data clock, nothing to do with time) and one for the data. In fact, you even chain up to 121 I2C devices on the same two pins - check out this Adafruit page for a selection of other I2C devices you could add, because there are a lot!

Getting Started

Hook up your TinyRTC module according to the diagram below - the pink DS line is not needed, as that's for the temperature sensor.

wiring

Next, download the Time and DS1307RTC libraries and place the resulting folders in your /libraries folder.

Exit and relaunch the Arduino environment to load in the libraries and examples.

ds1307rtc-example-menu

You'll find two examples in the DS1307RTC menu: upload and run the SetTime example first - this will set the RTC to the correct time. The actual code is not worth going into detail with, just know that you need to run it once to perform the initial time synchronisation.

Next, look at the example usage with ReadTest.

        
#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
  Serial.println("DS1307RTC Read Test");
  Serial.println("-------------------");
}

void loop() {
  tmElements_t tm;

  if (RTC.read(tm)) {
    Serial.print("Ok, Time = ");
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.write(':');
    print2digits(tm.Second);
    Serial.print(", Date (D/M/Y) = ");
    Serial.print(tm.Day);
    Serial.write('/');
    Serial.print(tm.Month);
    Serial.write('/');
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.println();
  } else {
    if (RTC.chipPresent()) {
      Serial.println("The DS1307 is stopped. Please run the SetTime");
      Serial.println("example to initialize the time and begin running.");
      Serial.println();
    } else {
      Serial.println("DS1307 read error! Please check the circuitry.");
      Serial.println();
    }
    delay(9000);
  }
  delay(1000);
}

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

Note that we've also included the core Wire.h library - this comes with Arduino and is used for communicating over I2C. Upload the code, open up the serial console at 9600 baud, and watch and your Arduino outputs the current time every second. Marvellous!

The most important code in the example is creating a tmElements_t tm - this a structure that we'll populate with the current time; and the RTC.read(tm) function, which gets the current time from the RTC module, puts it into our tm structure, and returns true if everything went well. Add your debug or logic code inside that "if" statement, such as printing out the time or reacting to it.

Now that you know how to get the right time with Arduino, you could try rewriting the sunrise alarm project or create an LED word clock - the possibilities are endless! What will you make?

Image Credits: Snootlab Via Flickr