Pages: [1]   Go Down
Author Topic: Real Time Clock module to display time and date on LCD  (Read 3309 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi guys,

I have a RTC module similar to the one here: https://www.sparkfun.com/products/99

I just need to program the arduino to display the time and date on a LCD display.
Have seen and tried out a few examples on the forum for the RTC module but I don't know why I am not able to get them working properly.

Pls assist. Thanks
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 498
Posts: 19064
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Read this before posting a programming question

Quote
... I don't know why I am not able to get them working properly.

I don't know either. You haven't posted your code. You haven't said what happens, except that it doesn't "work properly".
Logged


Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1284
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Often these modules need to be enabled to start keeping time. There is a bit that needs to be set to do this.  If you go to the link in my signature below I have a library with example code that allows you to look at what is happening in the ds1307.

Are you sure your connections are correct?
If you want others to help, though, you really need to be more clear about what errors you are getting.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, this is the code below.

And the error is that neither the time nor date gets displayed..

Is there any simple code available to test that my RTC module is actually working?


Code:




#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
#include <LiquidCrystal.h> // we need this library for the LCD commands
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.write(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave
Wire.endTransmission();
}
// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
void setup()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
Serial.begin(9600);
// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
second = 0;
minute = 46;
hour = 2;
dayOfWeek = 4;
dayOfMonth = 7;
month = 2;
year = 13;
// setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
lcd.begin(20, 4); // tells Arduino the LCD dimensions
lcd.setCursor(0,0);
lcd.print("test"); // print text and move cursor to start of next line
lcd.setCursor(0,1);
lcd.print(" test ");
delay(5000);
lcd.clear(); // clear LCD screen
}
void loop()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
lcd.clear(); // clear LCD screen
lcd.setCursor(0,0);
lcd.print(" ");
lcd.print(hour, DEC);
lcd.print(":");
if (minute<10)
{
lcd.print("0");
}
lcd.print(minute, DEC);
lcd.print(":");
if (second<10)
{
lcd.print("0");
}
lcd.print(second, DEC);
lcd.setCursor(0,1);
lcd.print(" ");
switch(dayOfWeek){
case 1:
lcd.print("Sun");
break;
case 2:
lcd.print("Mon");
break;
case 3:
lcd.print("Tue");
break;
case 4:
lcd.print("Wed");
break;
case 5:
lcd.print("Thu");
break;
case 6:
lcd.print("Fri");
break;
case 7:
lcd.print("Sat");
break;
}
lcd.print(" ");
lcd.print(dayOfMonth, DEC);
lcd.print("/");
lcd.print(month, DEC);
lcd.print("/20");
lcd.print(year, DEC);
delay(1000);
}
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1284
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Have you looked at my library as suggested above for sample code and a working example?
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yup I have tried it out but when I upload it, the whole LCD display shows random running characters

The only change I made to your code is to change the LCD pins and and the no. of rows and columns:

Code:
#include <LiquidCrystal.h>
#include <MD_DS1307.h>
#include <Wire.h>

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

void setup()
{
  lcd.begin(20,4);
  lcd.clear();
  lcd.noCursor();
}

void p2dig(uint8_t v)
// print 2 digits leading zero
{
  if (v < 10) lcd.print("0");
  lcd.print(v);
}

char *dow2String(uint8_t code)
{
  char *str[] = {" Sun", " Mon", " Tue", " Wed", " Thu", " Fri", " Sat"};
  return(str[code-1]);
}

void printTime()
{
  lcd.setCursor(0,0);
  lcd.print(RTC.yyyy);
  lcd.print("-");
  p2dig(RTC.mm);
  lcd.print("-");
  p2dig(RTC.dd);
 
  lcd.setCursor(0,1);
  p2dig(RTC.h);
  lcd.print(":");
  p2dig(RTC.m);
  lcd.print(":");
  p2dig(RTC.s);
  if (RTC.Status(DS1307_12H) == DS1307_ON)
    lcd.print(RTC.pm ? " pm" : " am");
  lcd.print(dow2String(RTC.dow));
}

void loop()
{
  RTC.ReadTime();
  printTime();
  delay(100);
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
char *dow2String(uint8_t code)
{
  char *str[] = {" Sun", " Mon", " Tue", " Wed", " Thu", " Fri", " Sat"};
  return(str[code-1]);
}
What is the pointer pointing to when the array goes out of scope. It points to some place on the heap where some other data now lives. In other words, garbage. So, you get garbage on the LCD. No real surprise there.

The day name string should be global. Then, there is no need for this function.
Logged

DELHI
Offline Offline
God Member
*****
Karma: 8
Posts: 955
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


can some tell me how did we assigned this address:#define DS1307_I2C_ADDRESS 0x68  . how we get this I2c address





Well, this is the code below.

And the error is that neither the time nor date gets displayed..

Is there any simple code available to test that my RTC module is actually working?


Code:




#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
#include <LiquidCrystal.h> // we need this library for the LCD commands
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.write(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave
Wire.endTransmission();
}
// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
void setup()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
Serial.begin(9600);
// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
second = 0;
minute = 46;
hour = 2;
dayOfWeek = 4;
dayOfMonth = 7;
month = 2;
year = 13;
// setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
lcd.begin(20, 4); // tells Arduino the LCD dimensions
lcd.setCursor(0,0);
lcd.print("test"); // print text and move cursor to start of next line
lcd.setCursor(0,1);
lcd.print(" test ");
delay(5000);
lcd.clear(); // clear LCD screen
}
void loop()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
lcd.clear(); // clear LCD screen
lcd.setCursor(0,0);
lcd.print(" ");
lcd.print(hour, DEC);
lcd.print(":");
if (minute<10)
{
lcd.print("0");
}
lcd.print(minute, DEC);
lcd.print(":");
if (second<10)
{
lcd.print("0");
}
lcd.print(second, DEC);
lcd.setCursor(0,1);
lcd.print(" ");
switch(dayOfWeek){
case 1:
lcd.print("Sun");
break;
case 2:
lcd.print("Mon");
break;
case 3:
lcd.print("Tue");
break;
case 4:
lcd.print("Wed");
break;
case 5:
lcd.print("Thu");
break;
case 6:
lcd.print("Fri");
break;
case 7:
lcd.print("Sat");
break;
}
lcd.print(" ");
lcd.print(dayOfMonth, DEC);
lcd.print("/");
lcd.print(month, DEC);
lcd.print("/20");
lcd.print(year, DEC);
delay(1000);
}
Logged

AMPS

Offline Offline
Faraday Member
**
Karma: 68
Posts: 2803
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
can some tell me how did we assigned this address:#define DS1307_I2C_ADDRESS 0x68  . how we get this I2c address
This is the address the manufacturer of the 1307 has been given for the chip.

Edit:  Examples here  http://www.ladyada.net/library/i2caddr.html
« Last Edit: February 27, 2013, 01:35:34 am by LarryD » Logged

The way you have it in your schematic isn't the same as how you have it wired up! That goes for me too.

SJ, Costa Rica
Offline Offline
Newbie
*
Karma: 2
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I did something similar.

In this post you can read my full sketch.

http://arduino.cc/forum/index.php/topic,126867.msg953852.html#msg953852

Hope it helps
Logged

Pages: [1]   Go Up
Jump to: