Shop OBEX P1 Docs P2 Docs Learn Events
P2 NTP Client — Parallax Forums

P2 NTP Client

I wrote an NTP client that gets the current date time from an NTP server (time.windows.com). Since the P2 has a boot time counter (in seconds) and a very accurate oscillator, it was very easy to make a clock without additional hardware. Code is attached. It is not good, but a POC. If anyone wants to clean it up, please feel free to.

It will return a unix timestamp. I grabbed a function from AlexGyver's UnixTime.h to parse the timestamp into something humans can read. @Rayman has a nice P1 object called PropTime, but it was more complex than what I needed to parse the timestamp. It looks like it would be the best thing to actually use for a time library. I stole some of his ideas to display the day of week and name of the month.

PS: Can't wait to be able to create a data structure for time when structures become available.

Comments

  • Hi @ke4pjw.
    Thank you for uploading your NPP client code, I have been considering using NTP in a project so this would be a good place for me to start with that.
    I also like the video as a way of showing the code in operation, good work there.

  • ke4pjwke4pjw Posts: 1,146

    @lab_ges said:
    Hi @ke4pjw.
    Thank you for uploading your NPP client code, I have been considering using NTP in a project so this would be a good place for me to start with that.
    I also like the video as a way of showing the code in operation, good work there.

    Thanks @lab_ges! Yeah, getsec() and the system counter makes it possible and doesn't even use a cog. We just need to know the timestamp when the system counter started. I have not put in the work to make it accurate to less than a second or take into account Internet propagation delays. If I have some free time this weekend, I may work on either or both.

    That getDateTime function I converted from AlexGyver's C probably needs to be exhaustibly tested. I don't know what range of dates are valid. I suppose I need to build something that will return human readable strings for dayofweek and months.

    pub getDateTime(t,tz) : strtime | z,era,doe,yoe,y,doy,mp,a,b,c,d,e,f,h,j,k
    
    '        // http://howardhinnant.github.io/date_algorithms.html#civil_from_days
            t += tz * 3600
            second := t // 60
            t /= 60
            minute := t // 60
            t /= 60
            hour := t // 24
            t /= 24
            dayOfWeek := (t + 4) // 7
            z := t + 719468
            era := z / 146097
            doe := z - era * 146097
            yoe := (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365
            y := yoe + era * 400
            doy := doe - (yoe * 365 + yoe / 4 - yoe / 100)
            mp := (doy * 5 + 2) / 153
            day := doy - (mp * 153 + 2) / 5 + 1
            month := mp + (mp < 10 ? 3 : -9)
            y += (month <= 2)
            year := y
    
            debug(zstr_(@daysofweek+((dayofweek-1)*4)), " ", zstr_(@months+((month-1)*4))," ", udec_(day), " ",udec_(hour),":",udec_(minute),":",udec_(second) )
    
  • Hi Terry @ke4pjw
    I have been thinking of possibly using your code with a standalone NTP server (like those sold on Aliexpress), that derive their timing from a GPS, since I have an idea in mind where the Network is purely local with no connection to the internet so I would have to re-write your

    pub ntpsettime()
    

    since I would have no DNS server but think I could just manually fill in the SERVERIP[x] and use a fixed IP instead, assuming I can manually set an IP on the NTP setver box, I won't know until I am ready to buy one.

    I was wondering if you have made any progress with the NTP code, specifically the items you mentioned that you may be going to work on.

    I have not put in the work to make it accurate to less than a second or take into account Internet propagation delays. If I have some free time this weekend, I may work on either or both.

    Just curious as my application is probably a few months off and I am interested in what you are doing with your NTP client code.

  • ke4pjwke4pjw Posts: 1,146

    Yes, you can just put an IP in there of an NTP server and it will work.

    I haven't done anything with it. Here is why: In order to derive a sub-second accuracy, it would require computing the time that included the fractional part of the second. NTP is a 32bit fractional counter. The P2 fractional counter is 64bit. The P2 counter is in milliseconds and rolls over once every 49.7 days, while the NTP fractional second is about .2ns and rolls over every second or 1/(2^32). I don't know that I am smart enough to figure out how to derive what that converts to in milliseconds.

  • ke4pjwke4pjw Posts: 1,146

    @lab_ges Well, Stack Overflow to the rescue. Here is how to convert the NTP fractional seconds to milliseconds. I might take a look at this later this week.

    uint32_t frac  = (uint32_t) packetBuffer[44] << 24
                   | (uint32_t) packetBuffer[45] << 16
                   | (uint32_t) packetBuffer[46] <<  8
                   | (uint32_t) packetBuffer[47] <<  0;
    uint16_t mssec = ((frac >> 7) * 125) >> 22;
    
  • Hi Terry, Thanks for the comments, very helpful.

    Sorry for the delay in replying. I often don't get the time for correspondence till Friday Afternoon (UK time) when other things are starting to wind down a bit, so I often send a message then.
    The problem is made worse because the time difference means the messages are read in US time zones on Friday Morning so the delay then seems longer, as I don't see the replies till the following Monday Morning.
    My apologies, you haven't been talking to yourself.

    Here is how to convert the NTP fractional seconds to milliseconds. I might take a look at this later this week.

    This looks very promising; I need to look at the bytes [44] to [47] to make sense of it but it looks like they are combining those bytes into a long.
    So far, I haven't managed to locate a full list of the BYTES in the "NTP packet".
    What I have found make it look rather complex, so well done of understanding it to write your existing code, perhaps https://rfc-editor.org/rfc/rfc5905 isn't the best place to start with that?

    NTP has been in my sights for a while but a discussion with a colleague the other day means it might be useful faster than I expected.
    So, I have started looking at hardware NTP units that use a GPS to act as the master clock but I guess it is possible for another P2 with networking to act as a server too?
    Probably beyond my abilities but worth thinking about.

  • ke4pjwke4pjw Posts: 1,146

    @lab_ges I am curious, how accurate does your clock need to be?

  • Hi Terry ( @ke4pjw ),
    I would like to get to 1ms, I think NTP is supposed to get better than that:-
    From https://timetoolsltd.com/ntp/ntp-timing-accuracy/

    "A GPS NTP server on local area network with low network congestion provides best results. In such circumstances, client synchronization to better than 1ms is achievable."
    

    but only time will tell, as close to this as possible would be ideal!

Sign In or Register to comment.