An Arduino LCD clock using the ChronoDot RTC

Well, here I go again, another adventure into the land of Arduino. I am in the midst of building an art project which requires the ability to keep accurate time. My first inclination was to create a software solution only using the Arduino. But after a few minutes of research I was aware of the disadvantage of a software solution, mainly, that the time would be incorrect if the Arduino was ever reset. I continued my research and found some cool Arduino clock kits and some great threads on RTC (REAL TIME CLOCK) chips, mainly the more popular DS1337 and DS1307.

Unfortunately both DS1337 and DS1307 chips seem to drift minutes per month, especially in extreme temperature ranges. So, I continued scouring the internet, until I found a thread that mentioned the ChronoDot RTC by MaceTech. The ChronoDot RTC is an extremely accurate real time clock module, based on the DS3231 temperature compensated RTC (TCXO). The ChronoDot claims to drift less than a minute per year, which makes the ChronoDot acceptable for my project. MaceTech provides a basic Arduino example using the Arduino Wire library which reads and prints the hours, minutes, and seconds from the ChronoDot. I basically borrowed the code and expanded upon it. I utilize a basic 16×2 LCD to output the time and date from the ChronoDot and I added the ability to change the hour and minutes via 2 push buttons.

The Arduino communicates with the ChronoDot, using the I2C standard interface. I2C is a serial data bus protocol that allows multiple devices to connect to each other with fairly slow data transfer rates. Thanks to the Arduino Wire library we don’t have to worry about the details. Moving forward you will need the following items to recreate my example:

Arduino Duemilanove,

a character LCD display with 0.1 header 16 pins long and a 10K potentiometer to adjust the contrast on the display,

a 6″ breadboard,

breadboarding wire,

a ChronoDot module,

2 10Kohm 1/2W 5% Carbon Film Resistors

and 2 push buttons.

The first thing you are going to do is connect your LCD to the Arduino. If you are not familiar with the steps, please read my post on connecting a character LCD to an Arduino. I placed my LCD as far left as I could on my 6″ breadboard to allow space for the other components.

The next step is to add the push buttons. The push buttons will enable the ability to set the hour and minutes, if needed.

Grab a push button, and place it on the breadboard. Grab a 10K resistor and connect one end of the resistor to the ground on the breadboard and then connect the other end of the resistor to one leg of the button, remember to leave space between the leg of the button and the resistor. Now, grab breadboarding wire and connect one end of the wire to the power supply on the breadboard, then connect the other end of the wire to the other leg of the button. You have completed a simple button circuit, grab the other push button and repeat the steps, your breadboard should resemble this:

Lets connect a button to the Arduino. Grab a breadboarding wire and connect one end of the wire to digital pin 6 of the Arduino. Connect the other end of the wire to the breadboard between the resistor and the one (grounded) leg of the push button. You have now created a button connection for the hour. Do the same for the minutes button but instead connect one end of a breadboarding wire to digital pin 7 of the Arduino. Connect the other end of the wire to the breadboard between the resistor and the one (grounded) leg of the push button. Your breadboard should look like this:

Now for the final piece, the good ole RTC Module. If you purchased the ChronoDot from Macetech, you should have received the lithium CR2032 battery. The battery allows timekeeping in the absence of external power, you will need to attach the battery to the module. The two solder pads on the PCB are marked + and -. The battery provided with the ChronoDot has a metal tab that runs from the top (positive, +) of the battery and down to the same level as the bottom (negative, -) side of the battery. You will need to solder the tab leading from the top of the battery to the + pad on the ChronoDot. The result should look like this:

Now, place the RTC module on the breadboard. Run breadboarding wire from the ground of the breadboard to the ground of the RTC. Run another strand of wire from the power supply of the breadboard to the VCC line of the RTC:

Grab two more wires to make the final connections to the RTC. Connect one end of a wire to the Arduino Analog pin 5. Now, connect the other end of the wire to the SCL pin of the ChronoDot RTC module on the breadboard. Grab the other wire and connect one end of the wire to the Arduino’s Analog pin 4. Connect the other end of the wire to the SDA pin of the RTC module on the breadboard. You have now connected the wires which communicate between the Arduino and the ChronoDot. Your completed breadboard should resemble this:

All there is left to do, is upload the example sketch below.
[cci lang=”c”]

Code under (cc) by Manuel Gonzalez,
Pins 12, 11, 5, 4, 3, 2 to LCD
Analog pins 4 (SDA),5(SCL) to Chronodot
Pins 6 (hour), 7(min) buttons


const int hourButtonPin = 6;
const int minButtonPin = 7;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int hourButtonState;
int minButtonState;

int seconds; //00-59;
int minutes; //00-59;
int hours;//1-12 – 00-23;
int day;//1-7
int date;//01-31
int month;//01-12
int year;//0-99;

void setup()


lcd.begin(16, 2);

hourButtonState = 0;
minButtonState = 0;
seconds = 00;
minutes = 26;
hours = 17;
day = 7;
date = 31;
month = 5;
year = 10;
//initChrono();//just set the time once on your RTC

void loop()

void display_time()
char buf[12];

lcd.setCursor(0, 0);

if(hours == 0)

lcd.print(“Time “);
lcd.print(itoa(hours, buf, 10));

if(minutes < 10) { lcd.print("0"); } lcd.print(itoa(minutes, buf, 10)); lcd.print(":"); if(seconds < 10){ lcd.print("0"); } lcd.print(itoa(seconds, buf, 10)); } void display_date() { char buf[12]; lcd.setCursor(0, 1); lcd.print("Date "); if(month < 10){ lcd.print("0"); } lcd.print(itoa(month, buf, 10)); lcd.print("/"); lcd.print(itoa(date, buf, 10)); lcd.print("/"); if(year < 10){ lcd.print("0"); } lcd.print(itoa(year, buf, 10)); } void initChrono() { set_time(); set_date(); } void set_date() { Wire.beginTransmission(104); Wire.send(3); Wire.send(decToBcd(day)); Wire.send(decToBcd(date)); Wire.send(decToBcd(month)); Wire.send(decToBcd(year)); Wire.endTransmission(); } void get_date() { Wire.beginTransmission(104); Wire.send(3);//set register to 3 (day) Wire.endTransmission(); Wire.requestFrom(104, 4); //get 5 bytes(day,date,month,year,control); day = bcdToDec(Wire.receive()); date = bcdToDec(Wire.receive()); month = bcdToDec(Wire.receive()); year = bcdToDec(Wire.receive()); } void set_time() { Wire.beginTransmission(104); Wire.send(0); Wire.send(decToBcd(seconds)); Wire.send(decToBcd(minutes)); Wire.send(decToBcd(hours)); Wire.endTransmission(); } void get_time() { Wire.beginTransmission(104); Wire.send(0);//set register to 0 Wire.endTransmission(); Wire.requestFrom(104, 3);//get 3 bytes (seconds,minutes,hours); seconds = bcdToDec(Wire.receive() & 0x7f); minutes = bcdToDec(Wire.receive()); hours = bcdToDec(Wire.receive() & 0x3f); } void setHour() { hours++; if(hours > 23)
hours = 0;
seconds = 0;
minutes = 0;

void setMinutes()
if(minutes > 59)
minutes = 0;



void check_buttons()
hourButtonState = digitalRead(hourButtonPin);
minButtonState = digitalRead(minButtonPin);

if(hourButtonState == HIGH){

if(minButtonState == HIGH){

byte decToBcd(byte val)
return ( (val/10*16) + (val%10) );

byte bcdToDec(byte val)
return ( (val/16*10) + (val%16) );

Take a look at the setup method in particular
seconds = 00;
minutes = 26;
hours = 17;
day = 7;
date = 31;
month = 5;
year = 10;
//initChrono();//just set the time once on your RTC

When you upload your sketch for the first time you will want to update the variables to the correct time then, un-comment out the initChrono() to set the clock, upload your sketch and now should have a running clock.

23 Responses to “An Arduino LCD clock using the ChronoDot RTC”

  1. Zonker says:

    Thanks for posting this project. I just got a ChronoDot, but the sample code didn’t show writing to the Dot, just reading the time. (I’m also looking forward to adding an LCD display to my project, so I’m sure that this sketch and we page will be even more useful to me in the future.

  2. Lauro says:

    Nice project.

    How to do your project below using only analog multimeter displays ?

  3. Lauro says:

    A suggestion: The return for the zero of each hand could be a little slower (.25 second or less) to prevent damages the counter.

  4. Per Jensen says:

    Great site! – Just assembled some ‘Dots today, and it worked first try with your code (found it with google) – you even show how to write to the chip – Thanks!!

  5. Lee Wiggins says:

    Hey Mate,

    Awesome “How to” very detailed and explained very well.

    May I suggest a couple of additions. Since the release of Arduino 1.0, the Wire library has been updated, Wire.send() is now Wire.write() and Wire.receive() is now when using Arduino 1.0

    Also I noticed now using Arduino 1.0 that the Wire.write(0); gives an error as “0” is ambiguous, my suggestion is to replace this with Wire.write((byte)0);

    Thanks mate and thanks again for providing such a great “How To”.


  6. d. says:

    Thanks for your useful post, I avoided reinventing the wheel.
    I detailed the change required to use Arduino 1.0 here:
    and I provided also the modified code (with credits, of course).
    I followed Lee Wiggins suggestion but used (uint8_t) instead of Byte.
    Thanks for the great work.

  7. […] luckily they used the Chronodot too): before reinventing the wheel a fast google search revealed “An Arduino LCD clock using the ChronoDot RTC”. I already indipendently rigged my 1602A LCD to my Arduino reading the post “How to connect a […]

  8. chris says:

    works fine except that the buttons dont actually do anything, checked and double checked the connections and its exactly as shown. Also cant change the date either!

  9. chris says:

    Fixed the buttons issue but still cant set the date not even in the code depsite following the instruction above

  10. admin says:

    Hi Chris, sorry for the late reply. Ive been extremely busy working on other projects. If I have some time this week I will try to rebuild the project. Things to look into is the Wire library. It may have changed and the methods may have been updated. Debug your work and make sure that the methods are being hit by running a trace.
    Good Luck.

  11. Bekka says:

    what does this line mean?
    ” lcd.print(itoa(year, buf, 10)); ”

    I do not get the itoa part.

  12. admin says:

    itoa() converts a number into a string.

  13. Ferg says:

    Hi, I am attempting to build a smart breaker box with a 4×3 keypad, lcd, and arduino uno. I have already setup my menus that can be scrolled thru if certain buttons are pressed. I have a chronodot and I was trying to figure out how to use my keypad to change the time and date. If you have any ideas please share. Here is what I have so far without the chronodot. file://localhost/Users/spencerferguson/Documents/menus.htm

  14. admin says:

    Hi Ferg,
    Unfortunately I can not access your source code. Essentially all you would have to do is get your button press from your key pad to call the set time or set date methods. Good Luck.


  15. Ferg says:

    Hi Manuel, I tried change the push buttons to my keypad buttons and it worked slightly. I say slightly because I would only assign one key to set a certain thing, but several keys would do the same function. Also, I couldn’t get the time to start back running. My source code is on that web page I posted at the bottom of my last post. All you have to do is copy and paste it in an address bar.

  16. Ian says:

    I’ve directly copied and pasted this to my own sketch, set up the wiring exactly as you have it, and made the two corrections to your code regarding Wire.send and Wire.receive. For some reason, when I load it onto the Arduino, everything works fine except for the time. With that, the hours and minutes just increment up to 23 and then reset to double zero. The seconds never change from double zero. Do you know why it’s doing this? I just did a straight copy/paste and wired it exactly as you have it.

  17. admin says:

    This project is a bit old and I have not replicated it in a long time. Unfortunately at the moment I do not have time to help debug your app. Good luck.

  18. MURUGAN says:


  19. alex says:

    hey how do you fix the problems with the months with 28 and 30 days like February

  20. admin says:

    Woah, it’s been a long time since I released the code. If I where to resolve the issue, I would simply add code to the getDate() method which would handle the month by doing something like:
    switch (month) {
    case 4:
    case 6:
    case 9:
    case 11:
    do something;
    Hope that helps.

  21. Wire.send should be Wire.write and Wire.receive() should be This worked for me very well. Thanks very much for your post.

  22. Brandon says:

    Did you know you can eliminate the 10k resistors by enabling the built in pull up resistors? Put these 2 lines below the pinmode lines.

    digitalWrite(hourButtonPin, HIGH); // set internall pullups
    digitalWrite(minButtonPin, HIGH);

  23. flyusa1 says:

    Works well so far. Thanks. 2 newbie questions, first how do I change the time format from 24 to 12 hours and second, when I unplugged then re-plug the power the time/date defaulted back to original time in the sketch from upload; the battery on the RTC did not retain the time up till power unplug. How do I fix that? Thanks!

Leave a Reply

Coding Color | 2009 All Rights Reserved.