Page 1 of 1

NTP library for WiPy

Posted: Sun Oct 25, 2015 9:02 am
by andrew
I've hacked a first version of an NTP client library for the WiPy, adapted from this project: https://pypi.python.org/pypi/ntplib/0.3.3

Usage is as follows (don't use this code literally as is; it has a sneaky bug - see http://forum.micropython.org/viewtopic. ... 1068#p6460):

Code: Select all

import untplib

c=untplib.NTPClient()
resp=c.request('0.uk.pool.ntp.org', version=3, port=123)
print("Offset is ", resp.offset)

from machine import RTC
import time

rtc = RTC()
print("Adjusting clock by ", resp.offset, "seconds")
rtc.init(time.localtime(time.time() + resp.offset))
It doesn't deal with timezones or daylight saving time but I don't think NTP is supposed to cater for those, and anyway I'm in the UK so I don't have to worry about that until March 2016...

I've put the library and sample code here: https://github.com/andrewmk/untplib

Andrew

[[Edit: changed name of repository to untplib to avoid confusion]]

Re: NTP library for WiPy

Posted: Sun Oct 25, 2015 9:53 am
by patmolloy
Lovely :) Thanks!

Re: NTP library for WiPy

Posted: Mon Oct 26, 2015 1:45 am
by alanb
Very nice, thanks!

Re: NTP library for WiPy

Posted: Tue Oct 27, 2015 10:37 pm
by PCA
Hi Andrew,
Thanks for this job.
Unfortunately it does not work for me. In fact, it does not work the same each time it runs (I get different time.localtime() after each try). Sometimes, the time is quite near of the real time. Sometimes quite far ex:
(2015, 10, 27, 22, 9, 44, 1, 300)
(2015, 1, 1, 0, 23, 54, 3, 1)
...
No error raised. I tested different ntp servers with same result.
Have you an idea how I could debug it ?

Pascal

Re: NTP library for WiPy

Posted: Wed Oct 28, 2015 9:55 pm
by andrew
PCA wrote:Hi Andrew,
Thanks for this job.
Unfortunately it does not work for me. In fact, it does not work the same each time it runs (I get different time.localtime() after each try). Sometimes, the time is quite near of the real time. Sometimes quite far ex:
(2015, 10, 27, 22, 9, 44, 1, 300)
(2015, 1, 1, 0, 23, 54, 3, 1)
...
No error raised. I tested different ntp servers with same result.
Have you an idea how I could debug it ?

Pascal
I debugged it with the time honoured technique of inserting print statements in the code to see what is happening at different points. First of all I'd add a "print(packed)" after line 193 in untplib.py (https://github.com/andrewmk/untplib/blo ... ib.py#L193) to see what the binary data is that's going to be sent to the server. Then I'd add a "print(response_packet)" at line 320 (https://github.com/andrewmk/untplib/blo ... ib.py#L320) to see what comes back from the server. Then take it from there.

Edited to add:
Actually it would probably be more useful to

Code: Select all

import ubinascii
and then

Code: Select all

print(ubinascii.hexlify(packed))
and

Code: Select all

print(ubinascii.hexlify(response_packet))
Andrew

Re: NTP library for WiPy

Posted: Sat Oct 31, 2015 6:33 pm
by PCA
Hi Andrew,
I think I found my problem.
The call to RTC with empty parameters reinits the clock with a specific date and time. (line rtc = RTC())
The problem comes from the fact that the offset value has been calculated before with a possibly different value of RTC (that is the case by example if you soft reset (Ctrl D) the Wypi board - no problem in case of hard reset).
A solution is to put the RTC() before calling the NTPClient library.
For me the following lines at the end of boot.py work fine :

Code: Select all

import untplib
import time
from machine import RTC
rtc = RTC()
c=untplib.NTPClient()
resp=c.request('1.fr.pool.ntp.org', version=3, port=123)
rtc.init(time.localtime(time.time() + resp.offset))
print("After_adjust", time.localtime())
Hope this help !
Pascal

Re: NTP library for WiPy

Posted: Sat Oct 31, 2015 6:42 pm
by dhylands
You could also check the reset cause and not bother reinitializing the rtc at all if the reason was SOFT_RESET. Something like:

Code: Select all

import time

if machine.reset_cause() != machine.SOFT_RESET:
    import untplib
    from machine import RTC
    rtc = RTC()
    c=untplib.NTPClient()
    resp=c.request('1.fr.pool.ntp.org', version=3, port=123)
    rtc.init(time.localtime(time.time() + resp.offset))
print("Current time", time.localtime())

Re: NTP library for WiPy

Posted: Sat Oct 31, 2015 7:21 pm
by andrew
Ah, good point. Sorry about that, I cobbled that code example together from two different places and didn't try it out myself. Sorry you wasted time on it, but I bet you understand the code better now :D

Andrew

Re: NTP library for WiPy

Posted: Sat Oct 31, 2015 9:05 pm
by PCA
Hi Andrew,
Absolutely right ! I never took the time to dive into NTP. Now I can say I did ;-) !

Hi Dave,
Yes it is a good fix, but the quality of the clock is rather poor on the Wipy and calling the NTP server one more time is probably a good idea ;-)

Thanks for the help

Pascal

Re: NTP library for WiPy

Posted: Sun Nov 01, 2015 8:56 am
by pythoncoder
the quality of the clock is rather poor on the Wipy
All RTC's drift - expensive ones drift less than cheap ones ;) An option to correct for RTC drift is to reset it from NTP periodically - perhaps once a day. But when this occurs the local time is likely to suddenly jump forwards or backwards by several seconds. Depending on your code, this can be more troublesome than a gradual drift.