GPS receivers can be used not only to determine the location, but also to receive accurate time signals. In this article, I will show how to set up an exact time server using GPS as the source of information and working with an accuracy of a few microseconds. As an example, I use the Garmin receiver and the FreeBSD OS, but the article will also be useful to those with Linux and Windows.
UPD: server is available at stratum1.net Web-muzzle:
www.stratum1.net .
')
I already
ran through a similar topic in Habré, but I believe that the topic should be opened up in much more detail: the author omitted many important details.
1. A bit of theory
According to the GPS World magazine, more than a billion GPS receivers are currently in use in the world, and more than 90% of them are used only to receive accurate time signals. [nineteen]
To determine your own three-dimensional coordinates, the GPS receiver calculates the distance to 4 satellites. This distance is calculated by measuring the time of the radio signal from the satellite. Because the speed of light is 3 Ă— 10
8 m / s, the signal travel time is very small, and the calculation requires very accurate synchronization of the clock on the satellite and the receiver. Therefore, each GPS satellite is equipped with an atomic clock with an accuracy of 1 ns / day, and the receiver provides time accuracy of about 50 ns [17]. To determine the time it is enough for the receiver to receive a signal from one satellite (
tanenn ).
Thus, you can get the exact time from the GPS-receiver. After all, computer clocks are not particularly accurate, not to mention switches, IP cameras, etc. But why do you need GPS if you can synchronize using the NTP protocol, for example, with pool.ntp.org?
- if the system does not have Internet access;
- if you need high accuracy of time - units of microseconds (ms);
- if you need to synchronize a distributed system from a reliable time source;
- just for fun :)
2. GPS receiver
You can use practically any GPS receiver - the main thing is that it supports the standard NMEA 0183 protocol. The
NMEA protocol is used to transmit GPS information using simple ASCII strings over a serial interface, such as RS-232. Together with the geographical coordinates, NMEA also transmits the exact time, usually once a second.
The accuracy of the time received from a conventional GPS receiver can be up to several milliseconds (ms), but it strongly depends on the receiver model: usually sending NMEA messages is not a priority for the receiver, so the accuracy may not be very good.
If you want to provide even greater accuracy - up to a few microseconds, you need to use a GPS receiver that can produce a
PPS signal (
Pulse per second ). The PPS pulse is repeated once per second with very high accuracy and can be read by ntpd.
Below I will consider both options: first, normal NMEA and in more detail PPS.
3. Getting time from GPS (without PPS)
3.1 Configuring GPS and ntpd
Windows administrators can install the ntpd port for Windows and follow the directions in
this article .
For Linux and FreeBSD, the instructions are the same:
- Connect the GPS receiver to the server's COM port (the USB adapter should also work).
- Create a symbolic link / dev / gpsX to the device (for example, I have / dev / cuau0 -> / dev / gps0).
- Add a line to ntp.conf
server 127.127.20.0 mode 0 prefer iburst minpoll 4 maxpoll 6
Line 127.127.20. 0 means that we use a local time source, driver 20 (NMEA Generic), device / dev / gps 0 .
If your device operates at a speed other than 4800 bps, you must set the speed using the mode command: 0 - 4800 bps (by default, you can leave it blank), 16 - 9600, 32 - 19200, etc.
iburst - speeds up initialization;
minpoll n - the minimum polling interval of 2 n seconds, at least 4, i.e. 16 s;
maxpoll n - maximum polling interval of 2 n seconds, maximum 17, about one and a half days;
prefer is the preferred server.
More information can be found in the excellent ntpd documentation. .
- Restart the server. Run ntpq -p. The list should contain the line GPS_NMEA (0) ... If this does not happen, refer to paragraph 5 “Possible problems”.
3.2 Check and Correction
The problem is that the receiver may send time data late. Also do not forget about the delay in the transfer of NMEA-messages. In order to correct this delay, add to the ntp.conf a reliable NTP-server stratum-1 with the parameter prefer, and restart ntpd.
For verification, we will need to use the ntpq -p command. Issue format:
Each line contains information about the time source, whether it is an NTP server or a local time source.
The first character in the line is the selection status:
* - selected source,
+ - as far as I understood, candidate for selection - the system will switch to it in case of primary source failure,
o - PPS source, space - not working source,
- x , etc. - "rejected" (unreliable) sources.
Next come:
remote is the hostname or IP address;
refid - source ID (driver name or server address with which the source is synchronized);
stratum: 0 for the primary time source (GPS), 1 for the server connected to it, 2 for the server that is synchronized with the server stratum 1, etc .;
t - type: l - local clock, u - network node, etc .;
when - time since the last transmission;
poll - a log interval of
2 seconds, i.e. if poll = 4, the server polls the source every 2
4 = 16 seconds;
reach is an octal number indicating the success of the last 8 transmission attempts. For example, 0 - not a single successful attempt, 377
8 = 11111111
2 - all attempts are successful. After running ntpd, if everything is OK, the source passes the values ​​reach 0, 1, 3, 7, 17, 37, 77, 177, 377;
delay - the time of the packet;
offset - the difference between the source and local time;
jitter - jitter or in other words the variance (spread) of the packet transit time.
Most of all we will be interested in the status symbol of the choice, reach, offset and jitter. Reach should be 377, and offset and jitter should be as small as possible.
Run the ntpq -p command. Wait until the offset of the NTP server is low enough.
remote refid stit when poll reach delay offset jitter
================================================= ============================
* mail.mobatime.r .DTS. 1 u 5 377 1 14.894 -3.198 0.490
xGPS_NMEA (0) .GPS. 0 l 2 377 7 0.000 -955.90 31.554
The selected ntpd server is marked
* , while our GPS receiver is marked bad (x). Offset GPS receiver is about -956 ms. Apparently, the information is transmitted about the previous second. To correct this lag it is necessary under the line server 127.127.20.0 ... add a line:
fudge 127.127.20.0 time2 0.956
Now you can make GPS your preferred server again. After restarting the server, the GPS_NMEA (0) should appear
* .
4. Getting time from GPS with PPS signals
4.1 Connecting a Garmin 18x LVC receiver
For myself, I chose a
Garmin 18x LVC receiver with a PPS pulse accuracy of ± 1 µs. This is an OEM receiver, it does not have a beautiful small screen, but it is convenient to use it in your own applications.

This receiver transmits data to the COM port and requires 5V, 90 mA power, so it will be convenient to power it from USB. We will need a female DB9 connector or a COM cable cut in half, as well as a cut USB cable for power. The native receiver connector also needs to be cut off - this will not affect the warranty. Connection diagram:
yellow wire - with pin 1 (PPS)
white wire - with pin 2 (transmission)
green wire - with pin 3 (reception)
both black wires - with black usb wire and pin 5 (ground)
Red wire - with red USB wire (+ 5V).

It is advisable to
solder the contacts. A simple twist can not earn (however, I did not check).
Inspired by the articles [2] and [3], I went even further and added a fuse, a “power” LED, a “PPS” LED and resistors for LEDs to the wiring diagram. Skilled electronics engineers can easily fit everything into a COM-cable plug, but I got a whole box.
I bought a ready-made development board, DB-9 and USB type B sockets, screw terminals (I did not find a BM06B-SRSS-TBT or SM06B-SRSS-TB native connector), a 1A fuse and a holder. As I could, I soldered all this, and Epoxy stuck the connectors :)


Basically, so bothering is optional. You can simply connect the wires from GPS, COM and USB, as done
here .
4.2 Configuring Garmin 18x LVC
To improve performance and reliability, it is desirable to configure the receiver. This can be done by sending commands via the terminal (see the
manual ) or by using the
SNSRCFG Windows utility. I chose the second path.
Connect to the receiver:
Comm → Setup: set the COM port, Baud rate: manual, 4800.
Comm → Connect
The program should load the current configuration.
Customize:
Config → Sensor Configuration
You must ensure that PPS is on and increase the pulse length to 200 ms.
You can also try to disable DGPS - we will not use it, and set Fix Mode = 2D - in theory, this will allow the receiver to work with three visible satellites instead of four. However, I can not vouch that these two options affect something.

Select NMEA messages:
Config → NMEA Sentence Selection
NTPd understands GPRMC and GPGGA messages. To reduce data transfer time, I left only GPGGA.

4.3 Configuring FreeBSD and ntpd
PPS support in FreeBSD has been around for quite some time, so PPS is easier to set up here and works more accurately. Linux users can read the article
Using a Garmin GPS 18 LVC as NTP stratum-0 on Linux 2.6 . The settings written below apply to FreeBSD.
To enable PPS support, you need
to rebuild the system
kernel with the option:
options PPS_SYNC
The NTP server is already present in the system, but it will not be superfluous to update. For FreeBSD, do this from the ports:
cd / usr / ports / net / ntp
make install clean
Now you need to add lines to rc.conf:
ntpd_enable = "YES"
ntpd_program = "/ usr / local / bin / ntpd"
ntpd_program points to the installation path of ntpd from ports.
Create symbolic links to / dev / gpsX and to / dev / ppsX device (for example, I have / dev / cuau0 -> / dev / gps0). You can use the ln command or add the appropriate lines to /etc/devfs.conf:
link cuau0 gps0
link cuau0 pps0
In the NTP documentation, it is recommended to receive only GPS PPS pulses for the exact clock, and time itself from another stratum 1 server. To do this, add (4-5)
stratum 1 servers and our PPS to /etc/ntp.conf eg:
server ntp.mobatime.ru prefer iburst maxpoll 9
server ntp1.vniiftri.ru iburst maxpoll 9
server ntp2.vniiftri.ru iburst maxpoll 9
server 127.127.22.0 minpoll 4
fudge 127.127.22.0 flag3 1
Driver 22 is responsible for PPS. flag3 turns on kernel timeline correction mode. The ntpd documentation
says that it is not necessary to include kernel discipline: ntpd will work more precisely if you just set minpoll 4. However, I can do just the opposite: with flag3, the clock is more accurate - so I suggest you experiment with this parameter yourself.
You can go the other way: receive and time with GPS and PPS signals:
server 127.127.20.0 prefer minpoll 4
fudge 127.127.20.0 flag1 1 flag3 1
flag1 includes PPS, flag3 is a kernel discipline.
This will allow getting time without using the Internet, but in this case a correction will most likely be needed (similar to paragraph 3.2).
After making changes, you must restart ntpd:
/etc/rc.d/ntpd restart
Run the ntpq -p command (for more information, see section 3.2). If you receive only a PPS signal, then the output should be approximately as follows:
remote refid stit when poll reach delay offset jitter
================================================= ============================
xnut.rsuitb.ru 5.89.176.137 3 u 21 64 377 2.074 41.522 5.869
+ mx.kr-pro.ru 62.117.76.138 2 u 34 64 377 4.167 0.336 0.423
+ wooster.rojer.p 195.54.192.55 3 u 25 64 377 70.609 9.523 0.262
x193.124.4.177 7.123.225.33 3 u 21 64 377 2.133 56.525 9.041
ntp1.vniiftri.r .init. 16 u - 512 0 0.000 0.000 0.000
xntp2.vniiftri.r .PPS. 1 u 39 64 377 73.585 -14.117 0.189
* mail.mobatime.r .DTS. 1 u 17 64 377 15.223 0.147 0.843
oPPS (0) .PPS. 0 l 5 16 377 0.000 -0.001 0.002
Before the PPS (0) should be “o”, reach within a couple of minutes to reach 377. The remaining servers are used to get the time.
If you also receive NMEA information with GPS, then
remote refid stit when poll reach delay offset jitter
================================================= ============================
* GPS_NMEA (0) .GPS. 0 l 11 16 17 0.000 -9.795 14.537
Before GPS_NMEA (0) should stand
* .
It will not be superfluous to check PPS status This can be done using the ntpdc -c kerninfo or ntptime commands. ntptime gives a little more detailed information:
ntptime
ntp_gettime () returns code 0 (OK)
time d24065e8.9067dfac Wed, Oct 12 2011 23: 15: 52.564, (.564085545),
maximum error 4739 us, estimated error 1 us, TAI offset 0
ntp_adjtime () returns code 0 (OK)
modes 0x0 ()
offset 2.004 us, frequency -28.979 ppm, interval 256 s,
maximum error 4739 us, estimated error 1 us,
status 0x2107 (PLL, PPSFREQ, PPSTIME, PPSSIGNAL, NANO),
time constant 4, precision 0.001 us, tolerance 496 ppm,
pps frequency -28.979 ppm, stability 0.019 ppm, jitter 1.434 us,
intervals 313, jitter exceeded 195, stability exceeded 0, errors 1.
What to look for:
ntp_gettime () and ntp_adjtime () should return "OK".
status must have PPSFREQ, PPSTIME, PPSSIGNAL flags, and there must not be PPSWANDER, PPSJITTER, PPSERROR.
jitter exceeded shows the number of pulses that came not quite on time. It's worth worrying if the jitter exceeded value becomes too large, and the PPSJITTER flag appears in the status.
intervals - the number of calibration intervals, should increase by one time per
interval seconds (256 s in the example)
stability exceeded - the number of too large time corrections, 0 - everything is in order.
errors - the number of PPS pulses that did not come at all or came at the wrong time, should not increase during operation.
stability - the smaller, the more stable the PPS source and server clock. Must be less than 0.1.
jitter - PPS pulse
jitter . Must be a few microseconds (us), no more.
5. Possible problems and debugging
5.1 Don't panic!
Always consider that the GPS receiver takes some time to establish its location after switching on: up to half an hour for older models, 45 seconds for the Garmin 18x. This time depends on how long the receiver has been turned off (
tanenn ). ntpd also requires a certain time to correct the clock. According to my observations: 10-20 seconds to "see" the receiver, 20-30 minutes so that the offset is reduced to the optimal value. If your reach after a few minutes of work is set to 377, and the offset is reduced (by module), then everything is fine.
5.2 ntpd does not see the receiver
If ntpd does not see the receiver: reach in ntpq -p is frozen at zero, you must carefully check the connection of the receiver to the server. Stop ntpd and open the COM port in the terminal. On FreeBSD:
cu -l / dev / gps0 -s 4800
Connected
$ GPGGA, 160042,5545.7890, N, 03722.6113, E, 1,08,0.9,188.3, ​​M, 13.3, M ,, * 47
$ GPGGA, 160043,5545.7890, N, 03722.6114, E, 1,08,0.9,188.3, ​​M, 13.3, M ,, * 41
| hhmmss | --- latitude - | - long-term --- | | ^^
| number of satellites
...
where / dev / gps0 is the device file, 4800 is the data transfer rate.
If the receiver is connected correctly, the NMEA messages should be sprinkled. Make sure the receiver "sees" the satellites. In a GPGGA message, the number of satellites must be 4 or more, and there must be one before this number. If you have enabled GPRMC messages, then after the time, there should be an “A” symbol.
To exit cu, press "Enter", then "~", then ".".
If NMEA messages indicate that the receiver does not see the satellites, it is necessary to move it to the coverage area. Best of all, the receiver can view the entire sky. My Garmin can also be installed on the roof, but through experiments I glued it to a place on the window where he sees satellites around the clock.
Examine the ntpd logs. Perhaps you should install the latest version of the server.
If NMEA messages do not arrive at all, make sure that the data transfer rate from the receiver corresponds to the expected ntpd. Check the operation of the COM port and the connection of the receiver to it.
Make sure that the total cable length from the port to the receiver does not exceed 5 m. Otherwise, you will have to bother and make a differential line to transmit the signal to protect against interference. It is recommended that the shielding of the GPS cable be connected to the shielded USB cable.
5.3 ntpd does not see the PPS signal
Again check the connection, for example with a voltmeter or oscilloscope. I use a cheap DSO Nano pocket oscilloscope. This is what the PPS signal looks like:

It is also convenient to use
RealTerm : it shows both NMEA messages and a PPS signal once a second on the DCD line.
Do not use USB-COM adapters: PPS signal may not go through or be delayed through them. As a rule, the COM port is always present on the motherboard, it just may not be displayed on the wall of the case.
5.4 Large offset / jitter
Make sure that you adjust the time taken as described in 3.2. If the receiver's settings allow you to disable all NMEA messages except one of: $ GPRMC, $ GPGLL, $ GPGGA, $ GPZDA, or $ GPZDG. If you use only PPS, you can disable all messages.
Try turning off COM port buffering. Install in /boot/device.hints:
hint.sio.0.flags = "0x2"
See if there are newer firmware versions for your GPS receiver. (
Garmin 18x LVC Firmware download )
The obvious idea is to increase the speed of data transmission. But according to the
documentation of ntpd, this will not help us. The speed is better to leave 4800.
Perhaps it is worth trying to change the OS system timer. On FreeBSD, you can put it in /etc/sysctl.conf:
kern.timecounter.hardware = i8254
My offset began to “jump” when the air conditioner in the server room started turning on and off.
Graph of PPS offset and temperature, when the temperature is stable:

When the air conditioner doesn’t mind:

From the graph it can be seen that the offset depends on the air temperature in the room. This is due, apparently, to the imperfection of the timer on the server. Ways to fix this problem are described
here and
here .
The “hardwired” method is to replace the generator on the motherboard with a temperature-compensated (TXCO). But this is an option for a guru of microelectronics and a soldering iron.
6. Preparing the NTP server for use
Before publishing the server to the network, read the sections of the documentation on
setting access rights and
limiting the number of requests .
If you want to create an NTP server for the local network, you can add the server address in the DHCP settings. However, I have suspicions that on Windows clients this option does not work, and on * nix dchpclient you need to configure it on each machine.
Often, they simply substitute the local NTP server in the DNS time.windows.com :) Now all Windows computers will go to our server.
The client list can be viewed with the ntpdc -c monlist command.
I also wrote a small
script for
Zabbix that tracks the reach / offset / jitter PPS parameters and the selected time server. Running the script must be added to zabbix_agentd.conf:
UserParameter = ntp.pps_jitter, / usr / local / bin / php /usr/local/share/zabbix/ntp_zabbix.php pps jitter
UserParameter = ntp.pps_offset, / usr / local / bin / php /usr/local/share/zabbix/ntp_zabbix.php pps offset
UserParameter = ntp.pps_reach, / usr / local / bin / php /usr/local/share/zabbix/ntp_zabbix.php pps reach
UserParameter = ntp.source_jitter, / usr / local / bin / php /usr/local/share/zabbix/ntp_zabbix.php source jitter
UserParameter = ntp.source_offset, / usr / local / bin / php /usr/local/share/zabbix/ntp_zabbix.php source offset
UserParameter = ntp.source_reach, / usr / local / bin / php /usr/local/share/zabbix/ntp_zabbix.php source reach
Restart the agent. On the server, respectively, you need to add these items for the NTP server. Now you can customize triggers and graphics.
7. Other ways to synchronize time
In addition to NMEA, ntpd supports even more exotic devices (see the
full list ).
It is worth noting, first of all, the ability to synchronize the clock over the radio signal. For example, in Russia there is a
RWM service, from Frankfurt in Germany the station DCF77 is broadcasting. DCF77 is well caught in the European part of Russia (I have a confident reception in Moscow). Making friends DCF77 and ntpd is easy, see the
article . The accuracy of this solution will be lower, but it is several times cheaper than the option with GPS: you only need to buy an antenna, no knowledge of radio engineering is required here.
Craftsmen can set up a beacon synchronization at the end of each hour. The length of the last sixth pulse depends on the current hour. But this method will be clearly worse in accuracy than the usual time synchronization over the Internet.
The exact time can be obtained from the cellular operator (
hellt ). This "feature" is called NITZ. However, not all operators and not all GSM devices support it. I checked my GSM-modems Siemens MC55 and Arduino GPRS-shield on SIM900 chip - there are no such AT-commands in these devices.
There are also ready-made NTP servers with GPS or GLONASS sensors, but, of course, they are much more expensive.
List of working Russian public statum servers 1
ntp1.vniiftri.ru
ntp2.vniiftri.ru
ntp4.vniiftri.ru
ntp.mobatime.ru
ntp0.ntp-servers.net
ntp1.ntp-servers.net
ntp2.ntp-servers.net
ntp0.zenon.net
gps-time.prao.psn.ru
ntp.ix.ru
I will try to make my server open as soon as I deal with the access rights. stratum1.net .
Literature
Sorted by “utility”:
- Ntpd documentation
- Adding a FreeBSD NTP server based on an GPS 18 LVC device
- Using a Garmin GPS 18 LVC as NTP stratum-0 on Linux 2.6
- NTP Reference Clocks Using FreeBSD 7.0
- Stratum 1 NTP, Garmin GPS 18 LVC on FreeBSD 8.0 ( mirror )
- Time synchronization with a Garmin GPS
- PPS Synchronization (NTP FAQ)
- Stratum One Time Servers
- Prof. David R. Andersen: NTP Temperature Compensation
- NTP temperature compensation
- Network Time Protocol server using PC gnu / linux and freebsd
- LinuxPPS NTPD support
- The Kernel Discipline
- Why not incorrect time? (FreeBSD FAQ)
- NTP Precise Time System
- Network Time Protocol (NTP) at the end are links to RFCs and mailing lists.
- Five ideas behind GPS
- DFC77 receiver
- What are dangerous cheap GPS jammers