DEMO: Using SNTP to sync the Spinneret's on-board RTC
Beau Schwabe
Posts: 6,566
Here is a Demo that uses SNTP (Simple Network Time Protocol) to Sync and Set the time of the on-board Spinneret RTC (Real Time Clock). The W5100 is accessed in Indirect mode to open a socket in UDP mode to retrieve the SNTP data. The RTC is then set to the SNTP time and displayed using the PST (Parallax Serial Terminal)
Note1: Other SNTP time servers here to choose from: http://tf.nist.gov/tf-cgi/servers.cgi
Note2: A previous version used the W5100 in SPI mode, this version uses Indirect/Parallel mode. Not that it matters much for setting the RTC, I just thought it would be easier to transition into an HTML Web application already using the Indirect driver without loading another object.
Enjoy!
EDIT: Please see the latest BUG fix ... http://forums.parallax.com/showthread.php/145697-SNTP-Simple-Network-Time-Protocol-BUG-fix-Update
LATEST program UPDATE.... v1.0.1
Note1: Other SNTP time servers here to choose from: http://tf.nist.gov/tf-cgi/servers.cgi
Note2: A previous version used the W5100 in SPI mode, this version uses Indirect/Parallel mode. Not that it matters much for setting the RTC, I just thought it would be easier to transition into an HTML Web application already using the Indirect driver without loading another object.
Enjoy!
EDIT: Please see the latest BUG fix ... http://forums.parallax.com/showthread.php/145697-SNTP-Simple-Network-Time-Protocol-BUG-fix-Update
LATEST program UPDATE.... v1.0.1
Comments
'USA Standard Time Zone Abbreviations
#-10, HST,AtST,PST,MST,CST,EST,AlST
'USA Daylight Time Zone Abbreviations
#-9, HDT,AtDT,PDT,MDT,CDT,EDT,AlDT
Is the "-" a bug?
How can I get GMT +1 ?
Thanks
No, the "-" is not a bug. I'm not sure I understand your 'Fault at : 50 and 53'
The line... '#-10, HST,AtST,PST,MST,CST,EST,AlST' ... In the Propeller IDE evaluates to ...
HST = -10
AtST = -9
PST = -8
MST = -7
CST = -6 <-- I am in Central USA time zone which is GMT - 6
EST = -5
AlST = -4
...likewise for the Daylight time zones
If you want GMT + 1, then in the CON section, just make...
BST = 1 or CET = 1 or wherever you may be.
The line of code that this constant gets applied to reads ...
... Change 'CST' to your abbreviation or just hard code the number in its place like this...
LongHIGH contains the upper 32 Bits of the 64 Bit time stamp <--- Seconds
LongLOW contains the lower 32 Bits of the 64 Bit time stamp <--- Fractional seconds
At line Nr 50 and 53 i get "Error at 50,7 Expected Unique Name, Constant or "(" "
If I remove the minus the program compiled
I get to find the use of " #-10, HST,AtST,PST,MST,CST,EST,AlST "
The CET part work when I use " SNTP.GetTransmitTimestamp(1,@Buffer,@LongHIGH,@LongLOW) "
Not working when I use " SNTP.GetTransmitTimestamp(CET,@Buffer,@LongHIGH,@LongLOW) "
and before riped the minus or change in line 50 & 53 " #(-10), HST,AtST,PST,MST,CST,EST,AlST "
I hope to have more time to play with the Supper Spinneret
Thanks Beau !
So it is a bst bug on osx, for me the first one.
It's really hard to say without looking at your code, and even then... I have trouble sometimes looking at my own code :-)
If you want you can send it to me via E-mail, and I'll see what I can determine.
Hope this helps
This is a BST compile error in how it handles the viewed data on the screen.
In the Propeller IDE it compiles correctly.
I do have a question though about how the time value returned from the SNTP souce is formatted. In the CON section, you have "Zone = CST", however, in the notes of the DAT section, it says "Typically, the TIME server will report time in local time zone". If this is true, why do you need to specify the time zone you are in? Is it used to convert local time to GMT? If so, do most people set their RTC to GMT? Thank you for any help you might be able to provide.
Benj
"Typically, the TIME server will report time in local time zone" - It really depends on the time server you are calling. I'm sure during my research into SNTP I found that statement, but I can't find it at the moment.
Here is a list of time servers...
http://tf.nist.gov/tf-cgi/servers.cgi
Don't abuse the privledge ... "All users should ensure that their software NEVER queries a server more frequently than once every 4 seconds. Systems that exceed this rate will be refused service. In extreme cases, systems that exceed this limit may be considered as attempting a denial-of-service attack."
Here is also a Perl Script version that I wrote for testing before implementing it into the Spinneret
Note:
There is one small error in the SNTP Simple Network Time Protocol.spin file. The line that reads bytefill(BufferAddress+16,string("LOCL"),4) 'ref-id ; four-character ASCII string should read bytemove(BufferAddress+16,string("LOCL"),4) 'ref-id ; four-character ASCII string instead. This original still works for now, but I will make the correction and update the file this evening. - Error fixed
LATEST program UPDATE.... v1.0.1
Benj
First, while there are provisions for switching between "Standard" and "Daylight Saving" time, it is a manual process, which requires re-upping code to your Spinneret twice a year.
Second, it appears that the GetTime method doesn't function as I had anticipated when the SNTP host can't be reached. If you use Beau's stock code and unplug the ethernet cable, you will find that after the timeout, it still sets the RTC and displays a time in the year 2036. I'm not sure why a timeout returns a -1 instead of a 0. Switching it to 0 fixes this problem.
So, instead of just listing problems, I put together some fixes. They might be a little klugey, but they do work. I wrote a method IsDST that determines whether or not the time returned should be DST or not. If it is, the offset is adjusted and then the RTC is programmed. Since I have friends in the European Union, and their rules are different, I wrote IsDSTEU for them. I also "fixed" GetTime so that a timeout returns a 0 and added some serial terminal text to indicate that SNTP had timed out.
I also added Beau's above mentioned fix of changing bytefill to bytemove in SNTP Simple Network Time Protocol.
I was not really sure where the best place was to put my new methods, but it was easiest to integrate them into SNTP Simple Network Time Protocol, so that's where they went.
This is the first code I have ever posted, so I'm excited to have some people take a look, try it out, and give me some feedback. I also am not sure I noted the additional author (me) and revision notes properly, but I'm learning.
Benj
I don't know if this is the proper place to post this, but since I have only made minor enhancements/revisions, I don't know if it warrants a new thread.
My PST output:
Can anyone else confirm this? I want to make sure that I didn't mess up one of the settings of my RTC or something.
I'll have to set this up again and double check (might be next week), I'm pretty sure I worked that out though.
When I was testing I wasn't using a Spinneret at all, I was using Perl on a Linux computer. I might have missed something in the translation into "Human readable Numbers".
RTC.SetDateTime gets sent a 13 for hours
RTC.GetHour returns a 1 for hours
RTC.IsPM returns false (although it should be true)
I next selected a time zone that would set the clock to 11:xxAM and just let it run.
RTC.SetDateTime gets sent an 11 for hours
RTC.GetHour returns an 11 for hours
RTC.IsPM returns false (as it should)
at 12PM RTC.IsPM starts to return true (as it should)
So, it appears that the clock can rollover to PM, but occasionally fails when setting. This doesn't always happen, just for stints of time.
Is it just for testing when viewport is enabled?
its driving me nuts!, any ideas?
Thu Sep 09, 2011 11:42:08 AM
SNTP Server Sync time:
(GMT - 6:00) 09/09/2011 11:39:51
it should be:
Thu Sep 08, 2011
Hmm, that's a problem. I just tested the Perl script and it shows the same result...
...This means that there is an error in the way the Date is derived from the elapsed seconds since January 1st 1900.
I'll look into that and fix this
What Time Zone are you in?... that could make a difference ... I think that's where the problem is in the code.
Keep in mind that GMT does not observe daylight savings so, while I am in CST (GMT-6) right now to see the proper time the GMT value would be GMT-5.
That's not the problem with the wrong day, although there is some overlap around midnight with the current calculations. I'll see about addressing that.
Inside of 'SNTP Simple Network Time Protocol.spin' change ....
... so that it reads...
If you Start with January as 1 and December as 12 and look at the binary nibbles .. bits A and D
With the exception of February if A and D are different then there are 31 days that month, if they are the same, then there are 30 days. ... With July and Aug being where the 'Flip' is. ...and Yes, I could have just had a lookup table, but I wanted to be different.
0001 - Jan
0010 - Feb
0011 - Mar
0100 -Apr
0101 -May
0110 -Jun
0111 - Jul
1000 -Aug
1001 -Sept
1010 -Oct
1011 -Nov
1100 -Dec
Sorry I did not reply when you asked the question, I didn't see it and somehow missed it until now...
"Curiosity and learning - Why is _clkmode and _clkfreq set in the "s-35390A_GBSbuild_02_09_2011.spin" driver?
Is it just for testing when viewport is enabled?" ... I believe you are correct, and it is an artifact associated with ViewPort. This section of code is Roy's original code, all that I did was to add a routine FmtDateTime which formats the Date and Time into a human readable string
Give some time to RS232, and make a SNTP server ?
I know it wil not be realy sync, but ..... 1 second acuracy ?
So I have a ref time on RS422, and want to distribute it with a SNTP spinneret server on local network ?