Go Down

Topic: Time and RTC libs - question on date and time integrity (Read 5746 times) previous topic - next topic

Constantin

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.

odometer

#16
Aug 23, 2012, 12:15 pm Last Edit: Aug 23, 2012, 12:36 pm by odometer Reason: 1

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.

Constantin

#17
Aug 23, 2012, 08:09 pm Last Edit: Aug 23, 2012, 08:21 pm by Constantin Reason: 1

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.

odometer

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.

Constantin

#19
Aug 24, 2012, 04:26 am Last Edit: Aug 24, 2012, 04:28 am by Constantin Reason: 1
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.

odometer


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.

odometer

#21
Aug 24, 2012, 07:12 am Last Edit: Sep 07, 2012, 04:56 am by odometer Reason: 1
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!)

Go Up