Hello folks, please tell me about usable libraries for DS3231 RTC to deal with DST.
I've got several projects on the go, all of which have the above RTC and I've successfully used RTClib.h. to get the correct date and time . I'm in time zone 0 (i.e. UTC). I now want to be able to deal with the spring and autumn adjuectment to the clock.
I can easily calculate when to make DST active by something like:
........ Check if date is between 26/3 and 31/3
.........If so, check if dayOfWeek is 1 (i.e. Sunday)
.........If it's Sunday, set a variable called DSTactive to = 1, else do nothing
.........If DSTactive=1 , then do something to make sure RTC is incremented by 1 hour.
-and obviously, the reverse of this in November.
I appreciate that this logic would trigger a change at midnight not the UK official 2am, but can live with that.
How do I get the DS3231 to increment or decrement its hour value just the once? I'm happy to use a different library if necessary?
I've looked at time.h and timeZone.h but neither seem to float my boat. Ideally I just want a functiont that tells the RTC to sort itself out.
For the AVR processors, I use the Jeelabs/Adafruit library, because it's so easy to set the RTC to UTC and produce local time:
const int DST = 1; // 0 for EST and 1 for EDT
...
DateTime getLocalTime() {
DateTime now = rtc.now();
DateTime localNow = now + TimeSpan(0, -5 + DST, 0, 0);
return localNow;
}
Additionally, hidden in AVR-GCC, are two simple time functions that tell you if daylight savings time is in effect. In the code above, I don't use it, but it's included in the calculations and I can set or clear it manually.
Sometimes I post and realize how lazy I was, so I updated it:
const int DST = 1; // 0 for EST and 1 for EDT
const int ZONE = -5; // EST/EDT - New York etc.
...
DateTime getLocalTime() {
DateTime now = rtc.now();
DateTime localNow = now + TimeSpan(0, ZONE + DST, 0, 0);
return localNow;
}
For reasons of synchronization as well as avoiding certain local time setting stumbling blocks, it is almost always better to set the RTC to UTC time and calculate the offset for local use.
I think I've seen the thread referred to by alto777 and also several other similar ones. They all seem to concentrate on one of the following:
Code to calculate when to change
Using a look up table to decide when to change
Using NPT, GPS or some other source over WiFi or network
I've got that covered, as noted above. But nothing I can find tells me now to increment or decrement once only, at some time around just after midnight on the correct day.
It's a pity that the DS3231 doesn't have a parameter to set, saying if TRUE, add on one hour, but if it does, I can't find it.
I guess we understand the English language differently and hope my later posts clarify. Bottom line - I don't need to care about in or becomes in range. I just need to figure how to increment or decrement once.
Your approach is misguided. What if the device is turned off when the DST time change passes? When you turn it on, how will it know whether DST is in effect (EDIT has been adjusted) or not? It's not possible to pull this off without one or many kludges.
Okay, I now see why so many times this subject seems to result in a thread that bounces around before hitting a dead end or petering out without a solution. My apologes for opening the can of worms again.
I'll start again and see if I can be really clear with the requirement and what I know how to do:
DST comes around last Sunday in March and reverts last Sunday in October every year.
I need a usable time, don't care if it comes direct from RTC or is somehow adjusted in code.
I'm not committed to the idea of changing RTC, it just seemed the simplest idea. Obviously not.
I have zero problem in deciding when to make the change(s). That bit is easy.
I have no problem in how to change the RTC (if necessary). That bit is easy.
I do have a problem is just adding on one hour in code, worried that there is a rollover issue with a 25th hour. If that's not the case, someone please tell me. Hence why I assumed changing the RTC (once) was simplest.
As previously mentioned, I've looked at the timeZone library and found nothing useful. I'm in Zone 0, UTC so don't need the complexity.
I was not aware of the TimeSpan option, thanks for that. Is it in native Arduino, or does it need another library?
At the moment I have solution in mind but it's very, very clunky. I would decide when to increment or decrement the RTC, move it by one hour and set a flag to indicate I've done it once. It just seems a shame to have this running in the loop, over and over, multiple times a second all year long. Hey ho.
Well, I can see how this is going so it will be my last comment. MCU do not charge by the hour for their time. It's free. But for the sake of argument, I use something like this in all my clocks:
so that time checks are not performed every millisecond, unless I really need it.
At the moment I have solution in mind but it's very, very clunky.
I'll be straightforward. That is absolutely true, and you should consider why the standard approach is the one that is almost universally uses. But it's not the implementation that is clunky, it's the concept.
You really need to store in eeprom the current state of the clock, whether it is in DST or not, otherwise there is no way to know at startup what state the clock is in. Easier to leave the clock alone and adjust for DST offset in the code.
Problem is, as already pointed out, the RTC doesn't know which time zone it is set for, so your code needs to store that somewhere that's non-volatile. Unfortunately, unlike the older DS1302, the otherwise superior DS3231 doesn't have any spare NVRAM you can use to store something like timezone in. Many Arduino have EEPROM, or can simulate it with an area of Flash memory, so that's another possibility.
Or, as also pointed out, keep your RTC permanently on UTC+0 and add one hour during BST.