Arduino + DS1307 Real Time Clock

February 23, 2011 | Amateur Radio, Arduino, electronics | By: Mark VandeWettering

Okay, this is no big deal: lots of people have done it before. But while I was watching TV, I soldered some header pins to the DS1307 based real time clock board I got from sparkfun.com , and coded up this simple program to read the time from it. I’d never really used the Wire library, but it’s pretty straightforward. I plugged the board into a breadboard, jumpered it into the Arduino, and with a bit of tweaking, it works.

[sourcecode lang=”C”]

#include <Wire.h>
#define DS1307_I2C_ADDRESS (0x68)

byte h, htmp, m, s ;
byte dow, dom ;
byte mn, yr ;

byte
BCDToDEC(byte val)
{
return (val >> 4) * 10 + (val & 0xf) ;
}

void
doDate()
{
Wire.beginTransmission(DS1307_I2C_ADDRESS) ;
Wire.send(0x0) ;
Wire.endTransmission() ;

Wire.requestFrom(DS1307_I2C_ADDRESS, 7) ;

s = BCDToDEC(Wire.receive() & 0x7f) ;
m = BCDToDEC(Wire.receive()) ;
htmp = Wire.receive() ;
dow = BCDToDEC(Wire.receive()) ;
dom = BCDToDEC(Wire.receive()) ;
mn = BCDToDEC(Wire.receive()) ;
yr = BCDToDEC(Wire.receive()) ;

if (htmp & (1<<6)) {
/* 12 hour mode… */
h = BCDToDEC(htmp&0x1F) ;
} else {
/* 24 hour mode… */
h = BCDToDEC(htmp&0x3F) ;
}

if (h < 10) Serial.print("0") ;
Serial.print(h, DEC) ;

Serial.print(":") ;
if (m < 10)
Serial.print("0") ;
Serial.print(m, DEC) ;
Serial.print(":") ;
if (s < 10)
Serial.print("0") ;
Serial.print(s, DEC) ;

if (htmp & (1<<6)) {
if (htmp & (1<<5))
Serial.print("PM") ;
else
Serial.print("AM") ;
}
Serial.print(" ") ;

Serial.print(mn, DEC) ;
Serial.print("/") ;
Serial.print(dom, DEC) ;
Serial.print("/") ;
Serial.print(yr, DEC) ;
Serial.print("\n") ;
}

void
setup()
{
Wire.begin() ;
Serial.begin(9600) ;
}

void
loop()
{
doDate() ;
delay(1000) ;
}
[/sourcecode]

Nothing earth shattering here. Eventually, I want my beacon controller to have a real time clock, and this seemed like a good way to go. Having a reasonably accurate real time clock means that I can make my beacon send WSPR messages, which start at the beginning of even numbered minutes on the hour. Baby steps.

Comments

Comment from Kenneth Finnegan
Time 2/23/2011 at 10:44 pm

Also note that if you need better accuracy than the DS1307, the DS3232 is a software drop-in replacement for it (Same I2C address and register mapping), and will get you an order of magnitude (20ppm to 2ppm). You’d probably have to leave it running for a long time before you’d notice, but still; FYI.

Comment from Mark VandeWettering
Time 2/23/2011 at 10:58 pm

Thanks for the pointer Kenneth. I’ll keep that in mind.

Comment from Ben Pharr, WF5N
Time 2/24/2011 at 5:14 am

FYI, with 20ppm accuracy, your RTC could lose or gain as much as 1.7 seconds per day, which could get you out of sync with respect to WSPR pretty quickly. Maybe a WWVB receiver is in order?

Comment from Mark
Time 2/24/2011 at 8:13 am

Or GPS.