Codingcolor Arduino RTC LCD clock with Chronodot

I recently started experimenting again with Arduino and must say I am having a lot of fun.

Chronodot Arduino and LCD RTC clock

Chronodot Arduino and LCD RTC clock

I had the idea to implement an RTC clock with arduino and excellent Macetech Chronodot and got myself the needed parts from Adafru.it. As it often turns out with Arduino project, someone already had the same idea (and 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 QY-1602A LCD to Arduino correctly” from fritzing.org and only had to rig the Chronodot using the codingcolor howto.
As I use Arduino 1.0, there are some issues to solve before using the sketch provided by codingcolor.com. As Lee Wiggins points out in a comment, the development environment changed in 1.0 and some changes affect the Twowire (Wire.h) lib included in the condingcolor.com  sketch. Some changes are required to run and upload it using Arduino1.0. If you want to know more about what has been changed in 1.0, please see here[blog.makezine], specifically at the “Migrating Wire (I2C) statements” paragraph.
I also discovered why the system was running correctly when powered by the USB cable and why the LCD was not powering up while rigged to an external (suitable, in my mind) 5v 2A power supply to external power jack of Arduino Uno. It turns out that’s it’s not suitable, as the external power supply must be at least 7V to account for the voltage loss of the voltage regulator.
After that, and after fixing the codingcolor.com sketch code to address the Arduino 1.0 updates, I had it up and running.
Credits for the original codingcolor.com code go to Manuel Gonzalez, www.codingcolor.com.

/*
 Code under (cc) by Manuel Gonzalez, www.codingcolor.com
 http://creativecommons.org/license/cc-gpl
 Pins 12, 11, 5, 4, 3, 2 to LCD
 Analog pins 4 (SDA),5(SCL) to Chronodot
 Pins 6 (hour), 7(min) buttons
Arduino 1.0 conversion from d. www.napalmpiri.info
*/

#include <Wire.h>
#include <LiquidCrystal.h>

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()
{

  pinMode(hourButtonPin,INPUT);
  pinMode(minButtonPin,INPUT);

  Wire.begin();
  lcd.begin(16, 2);

  hourButtonState = 0;
  minButtonState = 0;
  ////////////////////////////////
  seconds = 00;
  minutes = 56;
  hours = 10;
  day = 5;
  date = 16;
  month = 11;
  year = 12;
  //initChrono();//just set the time once on your RTC
  ///////////////////////////////
}

void loop()
{
  check_buttons();
  get_time();
  get_date();
  display_time();
  display_date();
  delay(1000);

}
void display_time()
{
  char buf[12];

  lcd.setCursor(0, 0);

  if(hours == 0)
  {
    lcd.clear();
  }

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

  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.write(3);
  Wire.write(decToBcd(day));
  Wire.write(decToBcd(date));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}
void get_date()
{
  Wire.beginTransmission(104);
  Wire.write(3);//set register to 3 (day)
  Wire.endTransmission();
  Wire.requestFrom(104, 4); //get 5 bytes(day,date,month,year,control);
  day   = bcdToDec(Wire.read());
  date  = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year  = bcdToDec(Wire.read());
}

void set_time()
{
   Wire.beginTransmission(104);
   Wire.write((uint8_t)0);
   Wire.write((uint8_t)decToBcd(seconds));
   Wire.write((uint8_t)decToBcd(minutes));
   Wire.write((uint8_t)decToBcd(hours));
   Wire.endTransmission();
}
void get_time()
{
  Wire.beginTransmission(104);
  Wire.write((uint8_t)0);//set register to 0
  Wire.endTransmission();
  Wire.requestFrom(104, 3);//get 3 bytes (seconds,minutes,hours);
  seconds = bcdToDec(Wire.read() & 0x7f);
  minutes = bcdToDec(Wire.read());
  hours = bcdToDec(Wire.read() & 0x3f);

}
void setHour()
{
  hours++;
  if(hours > 23)
  {
   hours = 0;
   seconds = 0;
   minutes = 0;
  }
  set_time();

}
void setMinutes()
{
  minutes++;
  if(minutes > 59)
  {
   minutes = 0;

  }
  seconds=0;

  set_time();

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

  if(hourButtonState == HIGH){
    setHour();
  }

  if(minButtonState == HIGH){
    setMinutes();
  }
}
///////////////////////////////////////////////////////////////////////

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

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

I still need to get to switches to change the time on the run but then it’s ok.
I hope it will be useful to someone: this project is great fun and the finished product is useful and works very well!
Unfortunately my Arduino has an old firmware so I will have to through the  firmware update…

Advertisements