Good morning all,
I'm trying to set my RTC using a return from an NTP time server. The NTP server will return time in seconds since 1/1/1900, which I can easily convert to a UNIX epoch, or time since 1/1/2000, etc.
My question is - Can I update my RTC chip with this serial number instead of worrying about individual hours, minutes, seconds, etc.? I have both DS1307 and DS3231 available to me.
Here's some sample code:
long currenttime = NTPgettime(); //returns a serial number version of time in seconds since a specified date
setTime(currenttime); //updates my RTC chip using this serial number.
All of the documentation I can find tells me to set the RTC using setTime(hr,min,sec,day,month,yr), which would require some type of conversion from serial epoch time to individual components of hr, min, sec, etc.
Thanks in advance for any thoughts...
Carl
The hrs, mins, secs, etc. are all stored in individual registers that must be written to, so the time must be converted.
https://datasheets.maximintegrated.com/en/ds/DS1307.pdf
https://datasheets.maximintegrated.com/en/ds/DS3231.pdf
This is the code snippet I've been using to convert ntp time to epoch time on your local timezone
if ( Udp.parsePacket() ) {
// We've received a packet, read the data from it
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long seventy_years = 2208988800UL - (STDTZOFFSET * 60 * 60);
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Udp.stop();
return secsSince1900 - seventy_years;
}
STDTZOFFSET is your local standard timezone offset, e.g. -8 for pacific standard time.
you can use the result to set RTC directly, as it is already converted.
you can just subtract seventy_years from the value returned by your NTPgettime() function.
Crossroads and Doughboy -
Thank you. That unfortunately confirms what I had thought. I have the same (or very similar at least) return value from the code that doughboy posted. Do you have any sample code on the most efficient conversion from the serial value (in seconds) to the required month/day/year/hour/minute/seconds input for the RTC modules?
I'd like to hide the conversion inside a sub function so that it doesn't run in the main loop - I'll only be updating the RTC occasionally.
Thanks again..
if you incorporate the conversion inside your ntp function, then you don't need to change anything in your main code. This will work as is
long currenttime = NTPgettime(); //returns a serial number version of time in seconds since a specified date
setTime(currenttime); //updates my RTC chip using this serial number.
you don't need to break it down into hours, mins, secs
if you are using the Time library, the current time is always available using functions
hour()
minute()
second()
day()
month()
etc
My question is - Can I update my RTC chip with this serial number instead of worrying about individual hours, minutes, seconds, etc.?
Yes, but it depends on the library you are using. setTime(uint32_t timestamp) may or may not be a valid entry to write the time into the RTC registers.
Using the standard Margolis DS1307 library the command will be rtc.set(timestamp)
With RTClib the command will be rtc.adjust(timestamp)
I believe that setTime is a time library command, and will not set the registers of the RTC.
Thanks for the responses all! Sounds like I need to take care to use the appropriate libraries - and then of course call them properly.