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.


#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) ;
}

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.

Write a comment