Pages: 1 [2]   Go Down
Author Topic: Time and RTC libs - question on date and time integrity  (Read 5065 times)
0 Members and 1 Guest are viewing this topic.
Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A couple of observations...

1) Use the 1Hz signal coming out of the RTC to drive one of the two interrupt pins on the 328P and hence increment the seconds. Thus, you do not have to query the clock at all via I2C to get great second-by-second performance. Sure, you have to keep track of seconds and minutes, and hours, but that's pretty simple.

2) If you want to be extra careful (guard against bad code or other mishaps resulting in a lost interrupt), have the code query the clock once a day in the middle of the night, etc. Then your seconds, minutes, and hours, will once again be in perfect harmony.

3) Never worry about flickering again - the code overhead for the clock is hence minimized and the Arduino can spend its time keeping the display happy.
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A couple of observations...

1) Use the 1Hz signal coming out of the RTC to drive one of the two interrupt pins on the 328P and hence increment the seconds. Thus, you do not have to query the clock at all via I2C to get great second-by-second performance. Sure, you have to keep track of seconds and minutes, and hours, but that's pretty simple.

2) If you want to be extra careful (guard against bad code or other mishaps resulting in a lost interrupt), have the code query the clock once a day in the middle of the night, etc. Then your seconds, minutes, and hours, will once again be in perfect harmony.

3) Never worry about flickering again - the code overhead for the clock is hence minimized and the Arduino can spend its time keeping the display happy.

I'm sorry if I didn't make myself clear. What I aim to do is to have the clock show civil time, with all its irregularities, and to be as independent from outside sources of time-related information as possible. I am using a Chronodot, but do not count this as an "outside source"; the outside sources to which I refer are mains frequency and NTP / radio / GPS signals. Ideally, I set the clock once in the entire duration of its existence, though in practice, I will almost certainly need to make occasional adjustments of a few seconds.

I would prefer to be able to tell the clock, "leap second coming at end of month XXX", and have it correctly insert that at the right time, as well.
« Last Edit: August 23, 2012, 05:36:47 am by odometer » Logged

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm sorry if I didn't make myself clear. What I aim to do is to have the clock show civil time, with all its irregularities, and to be as independent from outside sources of time-related information as possible. I am using a Chronodot, but do not count this as an "outside source"; the outside sources to which I refer are mains frequency and NTP / radio / GPS signals. Ideally, I set the clock once in the entire duration of its existence, though in practice, I will almost certainly need to make occasional adjustments of a few seconds.

I would prefer to be able to tell the clock, "leap second coming at end of month XXX", and have it correctly insert that at the right time, as well.

Pardon me for asking, but what part of my recommendation runs counter to your stated desires for this project? You wanted to avoid flickering displays, I addressed that issue by minimizing the CPU overhead associated with querying the Chronodot to once a day. That configuration also allows you maximum CPU capacity for other features, such as showing seconds in 1/2 increments.

If you are not familiar with the SQW output that the Chronodot features, now may be a good time to re-read the DS3231 datasheet and Atmel 328P interrupts. I have used the SQW output for my projects, it makes timekeeping much easier without a lot of overhead. The only downside as I see it are the (IIRC) 51-odd instruction cycles that it takes to drop into a interrupt routine. That said, 51 out 16 Million cycles per second is a pretty small percentage allowing your MCU to do other things 99.9997% of the time.

With careful monitoring and the adjustment of the aging trim (see datasheet) you may be able to minimize clock drift.

As far as the insertion of leap seconds go, here is a quote from Wikipedia (for what that's worth):
Quote
Because the Earth's rotation speed varies in response to climatic and geological events, UTC leap seconds are irregularly spaced and unpredictable. Insertion of each UTC leap second is usually decided about six months in advance by the International Earth Rotation and Reference Systems Service (IERS), when needed to ensure that the difference between the UTC and UT1 readings will never exceed 0.9 second. Between their adoption in 1972 and June 2012, 25 leap seconds have been scheduled, all positive.
(emphasis mine).

So in forty years, 25 seconds have been added at irregular intervals. My suggestion would be to worry about clock drift instead, the DS3231 is not nearly that accurate. Ideally, it'll be around 2PPM without accounting for aging, reflow soldering, etc. That's 63 seconds per year or ~5 seconds per month, assuming a non-random distribution of the error.

If I had too much time on my hands, it would make for an interesting experiment to see how accurate the DS3231 can be made through careful adjustment of the aging trim. For example, by connecting it to a radio time stamp circuit and comparing the 'should' vs. 'actual' seconds elapsed over a two month period and auto-adjusting the trim accordingly.
« Last Edit: August 23, 2012, 01:21:11 pm by Constantin » Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Let me spell it out for you, Constantin: Daylight Saving Time.

What I am thinking is, have the "external" RTC keep UTC, and convert for display.
Logged

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi odometer, thanks for the clarification. Daylight Savings Time is a bit more precise description than "civil" time. Implementing it should be easy.

Implementing auto-leap-second insertion as you stated earlier should be more difficult for the reasons I outlined above.

Looking over the schematic, I see that the Evil Mad Science alpha clock does not seem to have an connection from the SQW output from the Chronodot to one of the 644 hardware interrupts. Oh well, there goes that great idea.

IMO, no library is needed to access all the data in the Chronodot. Implementing the I2Ccode is pretty simple, gives you a great appreciation for bit shifting and other operations to assemble the various pieces of data.

Best of luck with your project.
« Last Edit: August 23, 2012, 09:28:20 pm by Constantin » Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi odometer, thanks for the clarification. Daylight Savings Time is a bit more precise description than "civil" time. Implementing it should be easy.

To do DST right, I need to be able to do date stuff right.
I find date stuff tricky to code and trickier to test.
Maybe it's because I'm really not used to working in this kind of environment (C++, microcontroller). I've done plenty of date / time related stuff on my own, and I believe that I am at least aware of the major "gotchas" by now. But I really am not perfect.

I think I might do this:
Handle the "messy stuff" only once every, say, 10 minutes. So the routine would go something like this.
Let's say I power the clock on. The RTC says that it is 12:34:56 (this is UTC) on such-and-such a date in the part of the year with DST. The program assumes it is the middle of the second (so as not to be more than 1/2 second out), and performs the conversion to local time for display: the result is 08:34:56.5. So I see "8:34:56" for half a second, then "8:34:57" for one full second, then "8:34:58" for one full second,... During this process, the RTC is ignored, and the half-seconds, seconds, and minutes are counted "stupidly". This continues until any XX:X9:59.5, at which time the program reads the RTC seconds once every 10 or 20 milliseconds. If it sees "59", it stands still. If it sees "00", it moves on. So, to continue our example, when our program reaches 08:39:59.5, it reads the RTC seconds, and one of three things happens:
a) The RTC seconds are "59" (or possibly "58"). Our program stays put at 08:39:59.5.
b) The RTC seconds are "00". Our program performs a full recalculation of the local time. It is now 08:40:00.0. (I am not sure whether this case involved reading more than just the seconds from the RTC, but it would probably be prudent.)
c) The RTC seconds are something other than "58", "59", or "00". Our program screams bloody murder.
The reason for the "full recalculation of the local time" in (b) is because sometimes there will be a discontinuity, such as when Daylight Saving Time begins or ends. Also, this recalculation will give us the local date, which is not always the same as the RTC date. Remember, I have my clock programmed (more like jury-rigged) to show the date as well as the time.
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

While I'm at it, I will post my (horrible) modification of the Alpha Clock Five firmware:

(Edit: There is a big bug in the code for the alarm. Depending on conditions too detailed to list, it might or might not work. Do not rely on the alarm!)

* firmware_17a_adj.pde (53.17 KB - downloaded 24 times.)
« Last Edit: September 06, 2012, 09:56:08 pm by odometer » Logged

Pages: 1 [2]   Go Up
Jump to: