Go Down

Topic: Library for DS1307 Real Time Clock (Read 40 times) previous topic - next topic

mungbean

For the record there's also some example DS1307 code for the Basic Stamp BS2 at
http://www.hellspark.com/dm/ebench/sx/PDB/StampWorksCode-v2.1/SW21-EX33-DS1307-AmPm.BS2
which could be of interest.

It's pretty well-commented, although the code does go the long way round to do I2C comms,
since it's written for the stamps that don't have any built-in.



xSmurf

#16
Oct 15, 2007, 07:56 pm Last Edit: Oct 15, 2007, 07:56 pm by xSmurf Reason: 1

Here's the obligatory action picture :D


[size=9](Click for full flickr experience)[/size]


"Pilots believe in a clean living... they never drink wisky from a dirty glass."

mattt

Very interesting, thank you for sharing.
I'm rather new to this, it's great to see how others code.

Where you have...

Code: [Select]
#define bcdToBin(val)                               (((val)&15) + ((val)>>4)*10)

Is using a macro in this way, better than defining a function, it looks easier (quicker).
What impact does it have on the resulting compiled code size ?

xSmurf

Code size is obviously bigger than using a function. On the other hand it's not only obviously faster (no call) it also reduces the function stack and parameter passing. So you really have to see what you need. I actually ended up switch that back to a function cause it was called many times and saved up something like 20~30 bytes (for both bintobcd and bcdtobin). Hope this helps :)
"Pilots believe in a clean living... they never drink wisky from a dirty glass."

xSmurf

You can now checkout the code through Subversion the code @
http://svn.mlalonde.net/cral/ds1337

You will also need to checkout
http://svn.mlalonde.net/cral/configs/rtcConfig.h

I now added both alarms support as well as their interrupts and external square wave output. The alarms can also trigger a user selected callback function. Let me know what you think!
"Pilots believe in a clean living... they never drink wisky from a dirty glass."

mattt


Totally impressed.
It took me ages to cobble together my offering and you've transformed it in no time at all.
I'll prolly take your work and prune it back to use on a DS1307.

second link 404 for me. :(

xSmurf

#21
Oct 18, 2007, 07:23 pm Last Edit: Oct 18, 2007, 07:30 pm by xSmurf Reason: 1
Hehehe, don't get me wrong Mattt, I did spend a lot of time on this thing in the past few days (I should really say nights). - Oh man that Unix Time Stamp function grrrrrrrrr - And I still should split out the RTC stuff from the DS1337 and make the thing a little more generic so it can easily be adapted to other RTC's without changing anything in the business logic. Sorry for the 404, here's the file: http://svn.mlalonde.net/cral/configs/RTC/rtcConfig.h. There's also a Trac site at http://trac.mlalonde.net/cral/. There's not much there yet but I'll try and really document all my libraries and add them to the site so they are easily available :) And of course they are free for anyone to use (MIT license if you want to know)

EDIT: Oh yeah there is now full support for alarms, alarm interrupts, alarm user defined callback functions, and the square wave output. I've also put back the clockStart/Stop routines when changing the time, this resets the  status register and helps reduce possible errors of either the two alarm flags or the fault flag.

"Pilots believe in a clean living... they never drink wisky from a dirty glass."

xSmurf

Here is a little usage example for alarms and some other stuff:

Code: [Select]

void setup()
{
     // Set the clock using a unix time stamp (date -u +'%s')
     RTC.clockSet(1192390068); //Sun Oct 14 15:27:48 EDT 2007
     
     // Setup a callback function for the integrity check
     // See below for the callback functions
     RTC.clockIntegrityCallback(integrityCallback);
     
     // Enable the Square Wave @ 1Hz on INTB
     RTC.sqwSetRate(DS1337_SQW_1HZ);
     RTC.sqwEnable();
     
     // Setup the first alarm
     RTC.alarmSelect(0); // Switch to alarm 2
     RTC.alarmSet(RTC_SEC,      30);
     RTC.alarmSet(RTC_MIN,      18);
     RTC.alarmSet(RTC_HR,      0);
     RTC.alarmSet(RTC_DOW,      0);
     
     // Match mode: every minutes and seconds
     RTC.alarmSet(DS1337_ALARM_MODE, DS1337_ALARM_MCH_MINSEC);
     
     // Setup callback function for alarm 1
     RTC.alarmSetCallback(alarmCallback1);
     
     // Setuo the external interrupt on INTA for alarm1
     RTC.alarmSetInterrupt();
     
     RTC.alarmSelect(1); // Switch to alarm 2
     
     // Match mode: once per minute at 00s
     RTC.alarmSet(DS1337_ALARM_MODE, DS1337_ALARM_PER_MIN);
     
     // Setup callback function for alarm 2
     RTC.alarmSetCallback(alarmCallback2);
     
     // Setup the interrupt for alarm 2
     // If the square wave is enabled, it will output on INTA
     // if the SQW is disabled the interrupt will happen on INTB
     RTC.alarmSetInterrupt();
}

void loop()
{
     RTC.clockChecks(); // Performs alarm and integrity checks for call back functions
}

// Note that the alarm registers will stay high
// until these function are finished executing.
void alarmCallback1(void)
{
     Serial.print("alarm 1 triggerd");
     return;
}
void alarmCallback2(void)
{
     Serial.print("alarm 2 triggerd");
     return;
}

void integrityCallback(void)
{
     Serial.print("Oscillator integrity fault!");
     
     // If the fault flag is high the clock is stopped
     // so in this function we can fix the time and start the clock again
     RTC.clockStart();
     return;
}


There are other stuff too obvious, such as manually checking for alarms, setting the time in binary, etc. Most of the options can be turned on/off to save some space if you don't need the functionality. You should try and go through the two configuration files (ds1337.h, configs/ds1337/ds1337.h and configs/RTC/rtcConfig.h) there are a lot of helpful comments in there.
"Pilots believe in a clean living... they never drink wisky from a dirty glass."

lucasvickers

I'm using Matt's code for the DS1307.
I bought the breakout package from SparkFun, so it has the oscillator and battery connected.
Anyhow, I am successfully able to read and write the time, but the time does not advance.

I decided to double check my sanity so I read the entire second byte, not just the section that contains the 0-60 seconds.
The value is 0 (as matt's library sets it all to 0 when you do RTC.start(), so the oscillator should be enabled.

Any idea what else I can check for?

thanks

ih8gates

hey, lucasvickers - did you get the issue sorted?

i was having a similar issue. it looked like my time was resetting every time I started the serial port monitor in the Arduino environment. The problem is that I'd forgotten that the setup{} code on an Arduino runs every time that the serial connection is established. I had removed the comments from Matt's library so that I could set the clock to the correct time and that code was re-running every time I connected the serial monitor.

ih8gates

...and Matt - Just wanted to say "thanks". I'm new to Arduino and know very little about C, but I was able to get my 1307 working quickly using your library. Thanks for sharing it.

mattt


You're welcome,
It's very gratifying to read your thanks.

w3eta

#27
Mar 18, 2008, 06:13 pm Last Edit: Mar 18, 2008, 06:25 pm by w3eta Reason: 1
Quote
I'd really appreciate some feedback, especially around how I've a approached the BCD manipulations.

Thanks


Thanks for the library - it took me no time at all to get the RTC updated and running. I especially like the fact that I don't have to think about BCD.

I'm getting the time from the WWVB signal broadcast from Fort Collins, CO. Once I set the RTC from that, I'll just check the RTC against WWVB once in a while and reset it if it drifts.

I really wanted the RTC to interrupt the arduino and didn't realize the DS1307 doesn't support that, so eventually I'll have to replace it, but your library saved me from having to figure it out myself. :)

xSmurf

The ds1337 does support up to two external interrupts and has two alarms (registers or interrupts). Both are supported in the ds1337 library, so the move should be pretty painless :)

Matt, have a look at http://trac.mlalonde.net/cral/, if you'd like I could host your library there (nice file browser, documentation pages, changes and what not :)
"Pilots believe in a clean living... they never drink wisky from a dirty glass."

w3eta

Quote
The ds1337 does support up to two external interrupts and has two alarms (registers or interrupts). Both are supported in the ds1337 library, so the move should be pretty painless :)


Actually, I'm thinking now that I might just stick with what I have. I got a DS1307 mini-board from futurlec, and don't HAVE to have an alarm to interrupt.

Go Up