I have released a small library that keeps the Particle Time sync’ed to an ntp server. You can use any server you’d like but it defaults to “time.nist.gov”.
It is simple and light. Just create the NtpTIme object and call the start() member function. Then forget it. It uses one of the software timers to keep the Particle Time well sync’ed.
Buyer bewares: It is not subtle about adjusting the time. If there has been a big offset, it could yank the time by quite a bit and mess up something depending on it. It tries to adjust the time to the tick of the second, but that might vary depending on your ntp round trip latency and the accuracy of the software timer.
Available on github at https://github.com/ClassTech/NtpTime/ , it is under the MIT copyright, so feel free to use it. Let me know if you have problems or questions.
Just for completeness, my older SparkTime library still works great and is available in the webIDE.
It features European and US Daylight Savings Time rules that you can use or not and is separate from the on-chip RTC. It does implement the NTP standard back-off and kiss-of-death parts of the protocol to be a good net citizen.
what is the difference between this library and the firmware’s Time function ?
I need to stay sync with UTC time and the time is critical in my proyect since i am using it for seism detection.
If you need time accuracy within a second or so, the built in library is fine. Hardware restrictions prohibit more accuracy than that. The NtpTime library will give subsecond accuracy if you have a consistent connection to an NTP time server. – Dougf
Do I need to do anything to disable the built in Cloud Time functions? Aren’t the two libraries going to fight each other if I simply add in the NTPTime library? Cheers
oooo, also, is there anything I can add to my loop to check it’s actually working? Like a Particle Publish on success?
Can I ask if SparkTime should work with a Core? I’m getting lots of Compile errors, but then I’m not sure if they’re not just conflicts with the TimeAlarms library. Thanks
In file included from project.ino:4:0:
TimeAlarms/TimeAlarms.h: In member function 'AlarmID_t TimeAlarmsClass::alarmOnce(time_t, OnTick_t)':
TimeAlarms/TimeAlarms.h:135:29: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (value <= 0 || value > SECS_PER_DAY) return dtINVALID_ALARM_ID;
^
TimeAlarms/TimeAlarms.h: In member function 'AlarmID_t TimeAlarmsClass::alarmRepeat(time_t, OnTick_t)':
TimeAlarms/TimeAlarms.h:151:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (value > SECS_PER_DAY) return dtINVALID_ALARM_ID;
^
In file included from project.ino:4:0:
SparkTime/SparkTime.h: At global scope:
TimeAlarms/TimeAlarms.h:18:20: error: expected ')' before '.' token
#define now() (Time.now() + time_zone_cache)
^
SparkTime/SparkTime.h:48:12: note: in expansion of macro 'now'
uint32_t now();
^
SparkTime/SparkTime.h:56:30: error: expected ')' before 'tnow'
uint8_t dayOfWeek(uint32_t tnow);
^
TimeAlarms/TimeAlarms.h:34:30: note: in definition of macro 'dayOfWeek'
#define dayOfWeek(_time_) (((_time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK) + 1) // 1 = Sunday
^
SparkTime/SparkTime.h:56:30: error: expected ')' before 'tnow'
uint8_t dayOfWeek(uint32_t tnow);
^
TimeAlarms/TimeAlarms.h:34:30: note: in definition of macro 'dayOfWeek'
#define dayOfWeek(_time_) (((_time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK) + 1) // 1 = Sunday
^
SparkTime/SparkTime.h:56:30: error: expected ')' before 'tnow'
uint8_t dayOfWeek(uint32_t tnow);
^
TimeAlarms/TimeAlarms.h:34:30: note: in definition of macro 'dayOfWeek'
#define dayOfWeek(_time_) (((_time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK) + 1) // 1 = Sunday
^ ^
In file included from project.ino:4:0:
project.ino: In function 'void loop()':
TimeAlarms/TimeAlarms.h:18:15: error: expected unqualified-id before '(' token
#define now() (Time.now() + time_zone_cache)
^
project.ino:210:23: note: in expansion of macro 'now'
currentTime = rtc.now();
^
Thanks - that did the trick - plus I had to change unsigned long lastTime = 0 UL;
to unsigned long lastTime = 0UL;
I flashed it to my Core and all went well, I got a couple of publishes from the Core, but it’s now gone offline and has stayed offline. I wonder if I was just asking too much of it to also do this NTP stuff.
The one Core I stil have running is using SparkTime NTP to run a time-and-temperature clock on my desk. It does freak out occasionally and I pull the plug to reset it and off it goes again.
I had to connect with USB to do a serial flash back to the old firmware. Not sure what was going wrong but I suspect the Core was just being asked to do too much.