RTC and DST
AGCB
Posts: 327
in Propeller 1
Is there any way to automatically adjust a RTC (DS3231) for daylight savings time?
Even if not the exact day but within a week or so
Thanks
Aaron
Even if not the exact day but within a week or so
Thanks
Aaron
Comments
I guess I can figure out how to program the Prop to do the same. I was hoping there might be an easier way!
Aaron
The smart approach is to always run the RTC at e.g. UTC or whatever, and never change that. Instead you apply DST (and TZ if you run the RTC at UTC) at the application level, typically where you read or display the date. Just look at the date and apply DST if it's after that March Sunday or before the one in October or whenever it is these days. You can never go wrong because there's no risk of doing it twice.
Then we should all work at getting rid of the whole DST. There's nothing good about it.
In my example, I save a bit in EEPROM when the adjustment has been made so it isn't done again, and upon power up I know if DST is in effect. This isn't the only way to do it, but the OP wanted to know how to adjust the RTC.
Another technique is to save the DST bit in EEPROM and then make the adjustment each time the clock is read. This is a little trickier in that after 23:00 it means also adjusting the day, date and possibly the month, each time the clock is read. But it can be done.
The best solution I have found is to use a RTC with automatic DST adjustment, like the ISL12022MA which is a very nice chip.
If your application runs in a place that observes DST, then you're going to have to deal with it one way or another.
I still think it's infinitely more elegant to simply run the clock at a fixed time setting and apply any adjustments to where the time is used.
-Tor
-Phil
I'll make that work in my program
Aaron
Aaron
You would use two functions to get the time: One for getting UTC time (e.g. a function 'gmtime'), and another for getting your local time ('localtime') which would apply your timezone and DST as needed. If you have a filesystem or a datalogger you would timestamp with the UTC time, not the local time. A UTC time stamp can unambiguously be converted to local time, the opposite is not true (the end of DST sets the clock back one hour (typically), thus the same local time could be any of two different UTC time values).
If you have a program which needs to check how much time has passed you will always want to compare UTC time values, not local time, because during DST changes the latter will jump. You would have to be aware of the DST dates in any program which tries to measure time intervals (and you would have the ambiguous hour-of-change at end of DST to clash with too - and that can't be resolved).
With the RTC running on UTC you can even move your gadget to another time zone while it's running, apply a TZ (timezone) change, and any program checking for time intervals which you kept running while moving will work fine, because the clock just ticks linearly ahead.
Converting the UTC hour to local/DST time is quite simple but the inconvenience of using UTC comes in having to convert the date back one day during the first few hours of each day (i.e. the first four or five hours on the east coast of the US). The code gets a bit messy with each month having a different number of days (no slick metric system yet for days, months and leap years).
Since I am using my RTC for "human time" I run my RTC set to local time. Below is a routine I added to the S35390A_RTCEngine.spin code that adjusts the RTC's time into and out of daylight saving according to the latest DST rules.
At this point I run this routine as part of the clock's read time/date routine. The DST flag is stored in the "user register" so stays within the RTC itself. This isn't much of a burden for me since I'm not running my code for speed. If speed is a factor then one could think about using one of the Sieko's alarms to go off each day at 2 AM and seeing that event would trigger a once daily check on the DST rule.
I originally write this code for a DS1307 RTC where the days of the week ran from 0 to 6 and I arbitrarily assigned Sunday as 0. If I recall correctly this original Seiko code used 1-7 for the days of the week. So in order to utilize this DST code I needed to modify the days of the week to use 0-6 (I think the internals of the Seiko run days of the week from 0 to 6 and the conversion to 1-7 was only in the spin code). A bit of fiddling with this algorithm would get it to work with days of the week using 1-7.
Interesting part - it is not clear how the DST manages, ie does the part need to be running and 'cross-over' the set points (just like an alarm) ?
Given DST applies differently around the world, (even flips phase for southern hemisphere) I think it has to be only a threshold cross design ?
The chip needs to be running and cross over the set point for the DST adjustment to happen, but will do so on battery and not just Vdd. If you lose Vdd and you have no battery (or it's dead) then you lose the time, so DST really doesn't matter.
The ISL part is neat in that you specify when the change occurs, either by month-week-day-hour or month-date-hour. It is truly global. Just set the rules and the chip takes care of the rest. So any changes to the rules, or moving to a locale with different rules, can easily be configured.
Yes, plus the IRQ/Fout pin can be used for one-time or repeating alarms, and the chip has readable temperature sensor! Along with 128 bytes of battery backed SRAM.
For DST switch, I think I'd use the DST registers if I were doing something like a dedicated clock that would display local parking regulations like we have around here, street sweeping monthly starting at 9am on the second Tuesday.
Another plus for the ISL is that the Vbat can be 5v, where on the DS parts, some are limited to 3.3v. I use supercaps, and just charge them with Vdd through a diode+resistor and don't have to worry about exceeding the Vbat max input.