I’ve attached a sketch for a simple GPS based NTP Time Server. I needed a reliable NTP Server on my LAN without having to connect via the internet.
The NTP Server uses a low cost ublox GPS as the time source and hopefully is a simple sketch to understand and modify for your needs. It should also be easy to modify to suit a wide variety of GPS chipsets as only the standard NMEA sentence GPRMC is used as the time source.
There are a couple of sketches on github for NTP Servers but these are either very abstract and complicated or do not work correctly. As far as I can see there are no NTP Server sketches on the Arduino forum?
This sketch assumes that a separate UART (UART 1) on a Mega2560 board is used for the GPS Tx/Rx connections. A W5100 based ethernet shield has been used for the LAN connection.
The Arduino code would easily fit on a 328 based board but you would need to modify the code to provide the Tx/Rx handling using Newsoftserial. I decided not to do that as I wanted some flexibility to add other features later and to avoid the interrupt processing timing overheads associated with Newsoftserial.
The basic accuracy of the NTP Server is determined by the GPS signal time source, the UDP NTP request processing time of the Mega sketch and the LAN latency. Of course the GPS signal is accurate to well defined limits. It is possible to tune for the processing time and LAN latency by adjusting the delay/dispersion values and timestamp to suit your requirements.
This NTP Server provides a NTP Response which works correctly with Windows etc. To keep things simple, the NTP Server just times out if there is no GPS GPRMC data available. The error handling is very basic.
There are plenty of ways this simple sketch could be improved and features added. Obviously the C coding could be tweaked, but I have tried to keep the code very easy to understand.
Hopefully someone will find this sketch useful and contribute any improvements they make.
NTP_Server_01.ino (7.36 KB)
The NTP Server uses a low cost ublox GPS as the time source and hopefully is a simple sketch to understand and modify for your needs. It should also be easy to modify to suit a wide variety of GPS chipsets as only the standard NMEA sentence GPRMC is used as the time source.
do you have a link to that device?
Search eBay for "Ublox NEO6MV2 GPS". Generally the device is under US$20.
packetBuffer[1] = 1 ; // stratum
think that should be at least 4 or so as you do not use fractional seconds 
for the rest looks quite good, Thanks for sharing!
robtillaart:
packetBuffer[1] = 1 ; // stratum
think that should be at least 4 or so as you do not use fractional seconds 
I have used fractional seconds in my own NTP Server as the GPS/GPRMC timing and Mega processing time is very stable. However I left this out of the basic sketch.
I think if you need time on a stand alone device (or no internet connection), another option is to just get an RTC for cheap, set the time and be done. This is useful though if you are already using the gps for other purpose, like navigation. And the gps needs to be outside for it to lock to the satellites.
doughboy:
And the gps needs to be outside for it to lock to the satellites.
GPS always gives accurate UTC time. RTCs will always drift.
The ublox and MT3329 chipset GPS receivers are very sensitive and work very well inside a house.
Ziggy2012:
doughboy:
And the gps needs to be outside for it to lock to the satellites.
GPS always gives accurate UTC time. RTCs will always drift.
The ublox and MT3329 chipset GPS receivers are very sensitive and work very well inside a house.
you can get more accurate RTC chips. It is still a way simpler (and faster) solution to using GPS if all you need is time. If you want accuracy, the time sync of 8 hours is not sufficient, that is why the default is 5 minutes. I would not count on the gps working on all indoor location. I know when I first setup my neo6 gps while indoors (for a quadcopter I am working on), it took several hours before it got a 3D lock (I actually was not expecting it to),. even outdoors it takes up to 10 minutes on a cold boot. so yes, it will work indoors, but...
doughboy:
you can get more accurate RTC chips.
Can you post a link please. I was not aware of RTC chips which are more accurate than the GPS network.
this
https://www.sparkfun.com/products/10160
or half price on ebay
http://www.ebay.com/itm/DeadOn-RTC-DS3234-Breakout-Real-Time-Clock-DS3234-/280892418658?pt=LH_DefaultDomain_0&hash=item41667e2a62
if accuracy is your concern, then syncing time every 8 hours is defeating the whole objective. A better solution perhaps is a combination gps + rtc. you can actually sync the rtc to gps once every 8 hours, and rtc to sync the arduino time every 5 minutes.
doughboy:
this
https://www.sparkfun.com/products/10160
or half price on ebay
http://www.ebay.com/itm/DeadOn-RTC-DS3234-Breakout-Real-Time-Clock-DS3234-/280892418658?pt=LH_DefaultDomain_0&hash=item41667e2a62
if accuracy is your concern, then syncing time every 8 hours is defeating the whole objective. A better solution perhaps is a combination gps + rtc. you can actually sync the rtc to gps once every 8 hours, and rtc to sync the arduino time every 5 minutes.
This is exactly what the NTP Server sketch is designed for. It provides an accurate (GPS UTC time sourced) Network Time Server (refer Network Time Protocol Version 4) which can be used to periodically resynch less accurate RTCs (including the ones you have linked to above).
Any device on the network can resynch its own internal clock (using the NTP Client protocol) to this NTP Server. Because this NTP Server is completely independent and does not rely on any external (NIST etc) NTP time servers, resynching can be done when and as often as you like.
well, there's that, and there is the practicality side of a solution.
time library does not sync itself, you must call the now() function for it to check if it is time to synchronize.
plus like I said, it does not matter if your time source is accurate to 1 billionth of a second if arduino is only accurate to 62 billionth. plus gps is not as accurate as you think, in theory it may be, but not from practical point of view. There is latency for the signal to get from satellite to the gps (ntp introduces network latency as well) , not to mention you are using a serial connection, which itself introduces timing error. Anyone who has ever used a gps for navigation knows how much error there is on location data. Gps signal can disappear or be blocked, hence it is not 100% reliable as well. Just understand its limitations so as not to fall into a false sense of security you are synchronized with atomic clock in fort collins.
the fastest sync is still via rtc. Connecting to ntp server on the internet adds a lag of several seconds (I've see it hang up to 10 seconds). That's why it is not practical to use it (and gps) as a main sync source. Hence you cannot sync to ntp or gps as often as you like. You will find all these out when you actually build your project.
doughboy:
well, there's that, and there is the practicality side of a solution.
time library does not sync itself, you must call the now() function for it to check if it is time to synchronize.
plus like I said, it does not matter if your time source is accurate to 1 billionth of a second if arduino is only accurate to 62 billionth. plus gps is not as accurate as you think, in theory it may be, but not from practical point of view. There is latency for the signal to get from satellite to the gps (ntp introduces network latency as well) , not to mention you are using a serial connection, which itself introduces timing error. Anyone who has ever used a gps for navigation knows how much error there is on location data. Gps signal can disappear or be blocked, hence it is not 100% reliable as well. Just understand its limitations so as not to fall into a false sense of security you are synchronized with atomic clock in fort collins.
the fastest sync is still via rtc. Connecting to ntp server on the internet adds a lag of several seconds (I've see it hang up to 10 seconds). That's why it is not practical to use it (and gps) as a main sync source. Hence you cannot sync to ntp or gps as often as you like. You will find all these out when you actually build your project.
I am not sure why you have such an issue with a NTP Server using GPS as a time source. The published Network Time Protocol Version 4 specifies GPS can be used as a Stratum 1 primary server time source. The latency issues are also dealt with extensively in the specification.
The following is an extract from the NTP 4 Spec:
An NTP implementation operates as a primary server, secondary server or client. A primary
server is synchronized directly to a reference clock, such as a GPS receiver
Anyway I would think that most people who have used an NTP Time Source to synch a local clock would be well aware of the latency, serial connection etc etc issues you mention. And yes, I have built and tested the project. And yes. I have used GPS extensively for other projects. But I certainly don't see any problem if you prefer not to use GPS.
I have read the sketch, but i still not understan in code below
packetBuffer[11] = 0; // root dispersion
packetBuffer[12] = 0;
packetBuffer[13] = 0xC;
packetBuffer[14] = 0;
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
timestamp = numberOfSecondsSince1900Epoch(year,month,day,hour,minute,second);
#if debug
Serial.println(timestamp);
print_date(gps);
#endif
tempval = timestamp;
packetBuffer[12] = 71; //"G";
packetBuffer[13] = 80; //"P";
packetBuffer[14] = 83; //"S";
packetBuffer[15] = 0; //"0";
===================================================================
#if debug
Serial.println(timestamp);
print_date(gps);
#endif
#if debug ...#endif, is that for error handling?
why packetBuffer[12],packetBuffer[13],packetBuffer[14] is used twice?
In this Sketch, Time Server MAC address used {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, but in another sketch from another source using MAC address { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED } for ethernet shield, why it is different?
There's a GPS-based NTP server project at the link below. It uses an Arduino Mega with Ethernet shield plus a couple of options for the GPS time source. The project design document (contained in the zip file) has lots of details including an accuracy analysis and test results. Sketch source code is also in the zip file.
Project Web Page
Project Zip File
artamesiaelectronics:
In this Sketch, Time Server MAC address used {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }, but in another sketch from another source using MAC address { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED } for ethernet shield, why it is different?
The ethernet shield does NOT come with an assigned MAC address. You assign what ever you want as you initialise the shield library.
Hi Ziggy2012
I used your code, it works well but date wrong when i synchronize to my PC. Can you help me? thanks!
GPS always gives accurate UTC time. RTCs will always drift.
yes, but: there is a thing you need to know.
w8bh clock2
page 2, just above and below the oscope screen capture:
Fortunately there is a better way. Most modules also provide a 1pps (1 pulse-per-second) output. The leading edge of this pulse typically falls at the top of the second. In other words, the start of the pulse corresponds to the start of the second. Serial RS-232 data immediately following this pulse will give the time corresponding to that pulse. The following digital oscilloscope image shows the relationship between the 1pps pulse in yellow and the serial data in blue.
The rising edge of the 1pps signal marks the beginning of the second.Each square in the horizontal direction equals 100mS, or one tenth of a second. In the example above, the1pps signal is 100mS wide. Serial data begins about 250 mS after the start of the second, and lasts for roughly 425mS. After watching this display for a minute or so, it was interesting to see that the start and duration of the serial data are both variable
so if you don't do what W8BH did and trigger a time correction from the leading edge, you will always be slightly behind the right time.
I adjusted the W8BH clock for Arduino UNO and added 3 I2C LEDs: UTC, Local Time adjusted for DST, and an optional status display for people who dig deep into the code. It takes up all the static RAM in an UNO, you need a MEGA if you want any more functionality
To Ziggy2012: I like how this forum marks you as "newbie" yet your write up is thoughtful, humble and well done, and the subject is very important. And all the other guys who slice & dice your post and some how try to convince us that an RTC is a better solution than actual satellite accuracy. How they complain they can't get a lock with the Ublox M6 inside their house, did they ever do further research of their own to learn why? It's because they are still streaming the GPS data via SoftwareSerial instead of bringing it in directly from UART port, I suggest they do this and will be blown away, mine syncs in 34 seconds more often than not, some rooms of the house take longer, longest is usually 3 minutes for me, module I'm speaking of: HiLetgo GY-NEO6MV2 NEO-6M GPS Flight Controller Module 3V-5V with Super Strong Ceramic Antenna for Arduino EEPROM APM 2.5.
This is easily done even with 328 based project by putting a jumper to RX pin (usually for USB program upload) and the GPS module, so when programming is needed, simply pull off the jumper, program, then put the jumper back on! Use if (Serial.available()) then Get.IT, and so on...
Keep up the good work, I acknowledge your skills and appreciate how you "tried to keep it simple" for the sake of the learner. If I could give you 100 Karmas I would. Cheers!