Time precision between NTP and GPS source - time

I have NTP client implementation (on Linux) to send/receive packets to (Stratum 1 or 2) NTP server and get the server time on the board. Also, I have another application running on Linux which gives me the GPS time.
Before I get the time information from NTP and GPS source, I will be setting the time manually(using date) on the board close to current GPS time(this info is taken from http://leapsecond.com/java/gpsclock.htm).
Keeping the system time on the board as the reference, I will take the difference of this reference time with NTP(say X) and GPS(Y). The difference between X and Y is coming to be 500+ ms. I was curious to know the time precision between NTP and GPS.
Is 500 ms an expected value?
I tried enabling hardware time-stamping on the NTP client,however it has not made any difference.

Using a GPS as a reference clock boils down to one thing: PPS (Pulse-Per-Second). Everything else is pretty jittery (unstable/unpredictable).
The PPS output is extremely accurate (nanoseconds).
PPS does not contain any information except when a second starts. That means we have to feed our clock the date and time from another source. NMEA (the actual data from the GPS) is fine as long as it’s good enough to determine the time to one second accuracy.
My guess is that your “GPS time” is the time (and date) from the GPS “data outlet”. This time can be off by 500ms (or even worse) and that’s normal. That’s why we do not use that time as an accurate reference clock.

You might want to read about time references. I think the GPS time system is not strictly identical to the UTC time returned by those time-server. The time measured by the atomic clocks have a leap second added periodically to get UTC time within +/1 second of the astronomical time which is not stable.
Is your NTP implementation able to correct network latency ? Try using a NTP server with a low-latency to you...
These factors may explain the difference you see.

Related

Is there a way to read the current time stored in RTC using windows?

I am looking for a way to query the current RTC from the motherboard while running under windows. I am looking for a simple unaltered time as it is stored in the hardware clock (no drift compensation, no NTP time synchronization, not an old timestamp which is continued using a performance counter, ...).
I looked at the windows calls GetSystemTime, GetSystemTimeAdjustment, QueryInterruptTime, QueryPerformanceCounter, GetTickCount/GetTickCount64, GetLocalTime. I read about the Windows Time Service (and that I can shut it off), looked if there is a way to get to the BIOS using the old DOS ways (port 70/71, INT 21h, INT 1Ah), looked at the WMI classes, ... but I'm running out of ideas.
I understand that windows queries the hardware clock from time to time and adjusts the system time accordingly, when the deviations exceed 60sec. This is without NTP. The docs I found do not say what happens after that reading of the hardware clock. There must be another timer in use to do the micro-timing between hardware reads.
Since I want to draw conclusions about the drift of clock sources, this would defeat all reasoning when asking windows for the "local time" and comparing its progress against any high resolution timer (multimedia timer, time stamp counter, ...).
Does anybody know a way how to obtain the time currently stored in the hardware clock (RTC) as raw as possible while running under windows?

How to periodically synchronize NTP time with local timer-based time

I have an embedded system with WiFi (based on an 80MHz ESP8266, developed using Arduino IDE), and I would like it to keep reasonably accurate clock time (to one second), using the two tools at its disposal: the internet, and its own internal timers.
Challenges:
The processor clock will likely drift over time, ostensibly in a
predictable manner.
NTP uses UDP, so return packets with the time are not guaranteed to
return in order, or to return within any set interval, or to return
at all.
Latency of return NTP packets varies widely over time, from under
100ms to (potentially) several seconds.
Latency of DNS varies widely over time, from under 100ms up to
several seconds (I can't control the timeout). DNS is needed to look
up IP addresses for the NTP server pool(s).
The system takes various actions based on certain times and
intervals, so I don't want to over-control the time, setting it
forward and backward continually, causing actions to be needlessly
missed or duplicated (or, alternatively, to complicate the program
logic handling all of these conditions - an occasional miss or
duplicate is not mission critical).
Sometimes an NTP server will return the wrong time (e.g.,
pool.ntp.org occasionally returns 0 seconds since 1900, which is easy
to detect)
Sometimes a stray return packet with an old time will arrive just
ahead of the return packet from the current request.
Current Approach:
Keep a local device time incrementing using an ISR triggered every 0.1
second.
Periodically poll (currently every 6 minutes, but really doesn't have
to be this often) an NTP server (pool).
Try again if there's no response within a short interval (currently 1
second, which is shorter than typical but most requests return in
under 150ms).
Vary the NTP server (pool) on each try, to spread the load and to
average out response times and any service errors.
Extract the time to the nearest 0.1 second (and adjust for typical
receive latency).
If the NTP time is off from the local device time by more than a
second, update the local device time (in a critical section).
Timeout, retry, and re-initialize (where appropriate), for failed
network elements of the process. Abandon the request after most hope
is lost, and just try again next time.
Is there a better, or canonical, or best practices way to do this time synchronization? Are there other factors or approaches I'm missing?
For automatic updating time from the internet or GPS system will overkill a cheap arduino project, for you may require a Ethernet shield and write a TSR program that will regularly send updated time to the arduino. Instead you can purchase more accurate RTC clock ( some are getting more accurate these days) and manually update the clock from time to time using keyboard and LED display incorporated with the arduino. If at all your project is very time critical, it is better to you some cheap crystal based solution instead.

How does the clock work in Windows 7?

I have read this answer somewhere but I don't understand it exactly:
I understand Windows increments the clock every curTimeIncrement
(156001 100 nanoseconds) with the value of curTimeAdjustment (156001
+- N). But when the clock is read using GetSystemTime does the routine interpolate within the 156001 nanosecond*100 interval to
produce the precision indicated?
Can someone try to explain it to me?
What is curTimeIncrement, curTimeAdjustment and how can Windows do this?
What is the effect for this on getting the accurate time?
Is that true just for windows 7 or also other OS Win8, Linux, etcetera?
It refers to the values returned by GetSystemTimeAdjustment() on Windows. It tells you how the clock is being adjusted to catch up or slow down to match the real time. "Real" being the time kept by an institution like the NIST in the USA, they have an atomic clock whose accuracy is far, far higher than the clock built into your machine.
The Real Time Clock (RTC) in your machine has limited accuracy, a side-effect of keeping the hardware affordable, it tends to be off by a few seconds each month. So periodically the operating system contacts a time server through the Internet, time.windows.com is the common selection on Windows. Which tells it the current real time according to the atom clock oracle.
The inaccuracy of the RTC is not the only source for drift, sometimes the real time is changed intentionally. Adding a leap second to resynchronize the clocks with the true rotation of the Earth. The current day (24 x 60 x 60 seconds) is a bit too short, the Earth's rotation is slowing down by ~1.5 msec every century and is in general irregular due to large storms and earth-quakes. The inserted leap second makes up for that. The most recent one was added on June 30th of this year at 23:59:60 UTC. 60 is not a typo :)
The one previous to that was on June 30th, 2012. A bit notorious, the insertion of the leap second crashed a lot of Linux servers. Google "Linux leap second bug" to learn more about it.
Which is in general what the machinery underneath GetSystemTimeAdjustment() is trying to avoid, instantly changing the time with the value obtained from the time server is very dangerous. Software often has a hard assumption that time progresses steadily and misbehaves when it doesn't. Like observing the same time twice when the clock is set back. Or observing a fake time like 23:59:60 UTC due to the leap second insertion.
So it doesn't, the clock is updated 64 times per second, at the clock tick interrupt. Or in other words 1 / 64 = 0.015625 between ticks, 156250 in nanoseconds*100 units. If a clock adjustment needs to be made then it doesn't just add 156250 but slightly more or less. Thus slowly resynchronizing the clock to the true time and avoiding upsetting software.
This of course has an unpleasant side-effect on software that paints a clock. An obvious way to do it is to use a one second timer. But sometimes that is not a second, it won't be when a time adjustment is in progress. Then Nyquist's sampling theorem comes into play, sometimes a timer tick does not update the clock at all or it skips a second. Notable is that this is not the only reason why it is hard to keep a painted clock accurate, the timer notification itself is always delayed as well. A side-effect of software not being able to instantly execute. This is in fact the much more likely source of trouble, the clock adjustment is just icing on the cake that's easier to understand.
Awkward problem, Mr. Nyquist has taught us that you have to sample more frequently to eliminate undesirable aliasing effects. So a workaround is to just set the timer at a small interval, like 15 or 31 milliseconds, short enough for the user to no longer observe the missing update.

Can NTPD be stricter in correcting time?

NTP is doing it's best in syncing my local time with the various NTP servers. If my computer (which has no hardware clock) doesn't have Internet access for a long period of time, the time starts to drift. NTPD slowly corrects it when it's back online, but it can take a long time if the offset is big. I understand the point of this method, but I don't want it to be careful. I want it to be strict in changing the date and time, even if it means huge leaping in time.
Is it possible to make NTPD stricter and less careful?
Check out chrony. Chrony is designed to handle intermittent network connections, where as the ntp reference implementation is not.
http://chrony.tuxfamily.org/
NTPd actually can compensate for the drift by learning the error rate of your local oscillator. Quoting this:
The driftfile entry specifies which file is used to store the system clock's frequency offset. ntpd uses this to automatically compensate for the clock's natural drift, allowing it to maintain a reasonably correct setting even if it is cut off from all external time sources for a period of time.
If you would like to set the time almost immediately manually you can use the -g option to ignore the 1000s safety check (usually, ntpd will not sync if/once the delta is beyong this threshold):
ntpd -qg

Get notified of ntp adjustments

I am in a weird situation and I need some direction with NTP time adjustments.
I have a PC (Red Hat) that runs NTP daemon and this PC adjusts its time with a Stratum 2 time server on my LAN.
My PC is also connected to a DVR over serial port (RS-232). This device and my PC time needs to in synchronization.
However after some time the clocks of my PC and DVR begin to drift away, so I need a way of detecting time adjustment on my PC and apply same adjustment to DVR as well.
Is there any way of doing this ?
I am hoping to find a way of subscribing to some kind of event at OS level for system clock changes on Red Hat. (If this is possible at all for RedHat)
It seems it is possible on Windows with SystemEvents.TimeChanged event but I could not find a counterpart on RedHat using C++.
Any help is appreciated.
Most of the time the NTP server does not make discrete adjustments to the system clock, it only slows it down or speeds it up using adjtime, in an effort to keep the drift rate under control. The NTP server might be doing this fairly continuously, and it will not tell you every time it makes an adjustment.
Even if the NTP server told you whenever it made adjustments, that information is not useful for you. Your DVR's clock is driven by different hardware and therefore has a different drift rate and would require a different set of adjustments at different times. Ideally this would be done by an NTP daemon on the DVR!
The NTP daemon does under some circumstances cause a jump in the clock. It may happen at startup or if the clock gets way off, but this should be a very rare event. It probably emits a log message when it does this, so one possibility would be to watch the logs. Another possibility would be to compare the results from clock_gettime(CLOCK_REALTIME) and clock_gettime(CLOCK_MONOTONIC) from time to time. When you notice that the delta between these two clocks has changed, it must be because someone made the system time jump. But beware: the results will be jittery because an unpredictable and variable amount of time elapses from the moment you fetch one of the clocks until the moment you fetch the other one.
Depending on your needs, you might be able to achieve what you need by ignoring the system time and using only clock_gettime(CLOCK_MONOTONIC) for synchronizing with the DVR. That clock is guaranteed not to jump. But beware! (again?! haha!) I believe CLOCK_MONOTONIC may still slow down and speed up under the direction of the NTP daemon.
Since there doesn't seem to really be a solution to this problem short of an API change from Microsoft, I've added a feature request. Please upvote if you're having this same issue.

Resources