{"id":210,"date":"2022-09-05T21:06:40","date_gmt":"2022-09-05T21:06:40","guid":{"rendered":"https:\/\/blog.lns.com\/?p=210"},"modified":"2022-09-05T21:23:33","modified_gmt":"2022-09-05T21:23:33","slug":"a-gps-stratum-1-ntp-server","status":"publish","type":"post","link":"https:\/\/blog.lns.com\/?p=210","title":{"rendered":"A GPS Stratum 1 NTP Server"},"content":{"rendered":"<div>\n<div class=\"sc-caSCKo dGDNtD\" data-test-id=\"page-content-only\">\n<div id=\"content\" class=\"page view\">\n<div id=\"main-content\" class=\"wiki-content sc-exkUMo cdTKqg\" data-inline-comments-target=\"true\" data-test-appearance=\"full-width\">\n<div class=\"ak-renderer-wrapper sc-ipZHIp hRAmvh\">\n<div class=\"sc-hzNEM ewiCWL\">\n<div class=\"ak-renderer-document\">\n<p data-renderer-start-pos=\"118\"><em data-renderer-mark=\"true\"><span data-renderer-mark=\"true\">&#8220;A man with a\u00a0<\/span>watch<span data-renderer-mark=\"true\">\u00a0knows what\u00a0<\/span>time<span data-renderer-mark=\"true\">\u00a0it is. A man with two watches is never sure.&#8221; &#8211; Segal&#8217;s Law<\/span><\/em><\/p>\n<h1 id=\"Introduction\" data-renderer-start-pos=\"118\"><span data-renderer-mark=\"true\">Introduction<\/span><\/h1>\n<p data-renderer-start-pos=\"132\"><span data-renderer-mark=\"true\">Keeping accurate time is critical for a number of things at an ISP. Accurate time is needed for debugging to see what devices were affected at what time.\u00a0 \u00a0If you had one reference clock that everything synced to, it really wouldn&#8217;t matter if it was 5mS off or 5 minutes off.\u00a0 So long as everything was based on that clock.\u00a0 Where it matters if you are trying to match your logs and data with devices that are not synced to your clock but to some other clock.\u00a0 So long as the other set of devices have synced to the same coordinated set of clocks you are, then you may have a good chance of lining up your logs to these other devices.<\/span><\/p>\n<p data-renderer-start-pos=\"132\"><span data-renderer-mark=\"true\">In tracking an event you are looking for timestamps that are &#8220;newer&#8221; or &#8220;older&#8221;. The need for accurate\u00a0time may be in the milli or microseconds to see fast-moving events. In order to have a device to determine what time it is, it will normally use a protocol like the <\/span><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/en.wikipedia.org\/wiki\/Network_Time_Protocol\" href=\"https:\/\/en.wikipedia.org\/wiki\/Network_Time_Protocol\" data-renderer-mark=\"true\"><span data-renderer-mark=\"true\">Network Time Protocol (NTP).<\/span><\/a><span data-renderer-mark=\"true\">\u00a0 NTP will send a packet out to another and trusted the NTP server to see what time it is. As there is latency on the Internet and in the protocol, NTP will also try to calculate the latency and adjust for it.\u00a0 <\/span><\/p>\n<p data-renderer-start-pos=\"835\"><span data-renderer-mark=\"true\">Trusted NTP servers will be classified on how they get their\u00a0time such as based on an internal, highly accurate clock (<\/span><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/en.wikipedia.org\/wiki\/Network_Time_Protocol#Clock_strata\" href=\"https:\/\/en.wikipedia.org\/wiki\/Network_Time_Protocol#Clock_strata\" data-renderer-mark=\"true\"><span data-renderer-mark=\"true\">stratum 0<\/span><\/a><span data-renderer-mark=\"true\">) or based on another NTP server (stratum 1, 2, etc.). For instance, a stratum 1 server will get its time from a stratum 0 server. A stratum 2 server will get its time from a stratum 1 server and so on.<\/span><\/p>\n<p data-renderer-start-pos=\"1158\"><span data-renderer-mark=\"true\">One does everything they can to minimize the workload on these servers so that when a server is queried, it can respond as quickly and reliably\u00a0as possible.\u00a0 So you may not have all of your devices connect to your only reference clock.\u00a0 You would distribute a second tier of NTP servers that would sync to your reference clock that your devices get their time from.\u00a0 As we are building a stratum 1 clock, you would deploy a set of NTP servers that would be stratum 2 servers for the rest of your devices.\u00a0 The stratum 2 servers would also sync with other NTP servers on the net to confirm that the reference clock is accurate.<\/span><\/p>\n<div class=\"heading-anchor-wrapper-old\">\n<div class=\"sc-jtggT ejYsQE\">\n<h1><span style=\"font-size: 23px; font-weight: 900;\">The NTP Server<\/span><\/h1>\n<\/div>\n<\/div>\n<p data-renderer-start-pos=\"1972\"><span data-renderer-mark=\"true\">This server uses the <\/span><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/learn.adafruit.com\/adafruit-ultimate-gps-hat-for-raspberry-pi\/overview\" href=\"https:\/\/learn.adafruit.com\/adafruit-ultimate-gps-hat-for-raspberry-pi\/overview\" data-renderer-mark=\"true\"><span data-renderer-mark=\"true\">Adafruit Global Positioning System (GPS) receiver<\/span><\/a><span data-renderer-mark=\"true\"> hat sitting on a Raspberry Pi 3 to get its time from GPS. GPS has to have a highly accurate time to have accurate\u00a0positioning reporting.\u00a0<\/span><\/p>\n<div class=\"heading-anchor-wrapper-old\">\n<div class=\"sc-jtggT ejYsQE\">\n<h2><span style=\"font-size: 19px; font-weight: 900; letter-spacing: 0.13333em; text-transform: uppercase;\">Setup<\/span><\/h2>\n<\/div>\n<\/div>\n<p data-renderer-start-pos=\"2428\">As mentioned above, our server will get its time from a stratum 0 server. In this case, a GPS clock is considered a stratum 0 server as it is a highly stable &#8220;coordinated clock&#8221;. Coordinated means that the time it calculates is coordinated with other clocks, such as the rest of the GPS satellite clocks as well as established clocks on the ground. Drift between these clocks is noted and adjusted as needed in order to keep all coordinated clocks in sync.<\/p>\n<p data-renderer-start-pos=\"2880\">GPS receivers indicated time a couple of ways. Every second, this string is sent to the Pi. The actual timestamp of what time it is is sent to the Raspberry Pi via a 9600 baud serial port. As the string can vary in length as well as various other delays such as the computer servicing serial port interrupts, this is not an accurate method of finding out what time it is. It can actually vary several hundred mS. An additional method needs to be conveyed to the Raspberry Pi indicating the actual moment when the second occurs. This is typically a General Purpose I\/O (GPIO) pin going high for a 100 mS and then going low. This GPIO pin is exposed to the computer as the Packet Per Second (PPS) interface such as \/dev\/pps0. The moment the GPIO pin goes high is the exact moment the second occurs. This is called the rising edge. So, timing software on the computer will get the time from the serial port and know the exact moment from the GPIO pin going high.<\/p>\n<p data-renderer-start-pos=\"3809\">On a computer, you will have one process looking at the data from the GPS and one process handing the NTP protocol. The second process will get the timestamp and could be configured to assume that the first process is looking at the \/dev\/pps0 interface or it could use the \/dev\/pps0 interface. In the current configuration, the NTP server (CHRONYd) is getting the GPS timestamp from the GPSd process via shared memory and the NTP server is looking at the \/dev\/pps0 interface for the exact moment that the second occurs.<\/p>\n<p data-renderer-start-pos=\"4330\">The GPSd daemon simply listens to the serial port and reports this via shared memory to the NTP server. We are using a compiled (source) GPSd as the packaged version was several revisions old for the Raspberry Pi distro. We are using an NTP server that is also a recent release and locally compiled called Chrony. In this case, Chrony is listening to the PPS interface to understand when the actual second starts.<\/p>\n<div class=\"heading-anchor-wrapper-old\">\n<div class=\"sc-jtggT ejYsQE\">\n<h2><span style=\"font-size: 19px; font-weight: 900; letter-spacing: 0.13333em; text-transform: uppercase;\">Debugging<\/span><\/h2>\n<\/div>\n<\/div>\n<p data-renderer-start-pos=\"4733\">You can check the status of the NTP server by running the Chrony command-line interface called &#8220;chronyc&#8221;.\u00a0 \u00a0A couple of commands are worth note are &#8220;sources&#8221; and &#8220;tracking&#8221;.\u00a0 The &#8220;sources&#8221; command will list the sources it is using for time.\u00a0 In the line below it shows PPS0 which is the Pulse Per Second GPIO pin.\u00a0 It is within the error rate tolerable of +\/- 8mS and is around 200nS. GPS0 is the GPS NEMA strings via shared memory from GPSd to CHRONYd. Normally this would be off around 500mS or so we compensate for that by putting an offset in the chrony config of 0.500 seconds. PSM0 and PST0 are GPS NEMA strings and PPS signals via shared memory. Since the GPS is not handling PPS, these entries will be zero. The rest of the various NTP servers that chrony can sync against and have some confidence that the GPS data is sane.<\/p>\n<pre class=\"code-block \">chronyc&gt; sources\r\n210 Number of sources = 8\r\nMS Name\/IP address \u00a0 \u00a0 \u00a0 \u00a0 Stratum Poll Reach LastRx Last sample\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\r\n===============================================================================\r\n#* PPS0\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 0 \u00a0 4 \u00a0 377\u00a0 \u00a0 10 \u00a0 +227ns[ +516ns] +\/- 8186ns\r\n#? GPS0\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 0 \u00a0 3 \u00a0 377 \u00a0 \u00a0 5\u00a0 \u00a0 -12ms[\u00a0 -12ms] +\/-\u00a0 100ms\r\n#? PSM0\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 0 \u00a0 3 \u00a0 \u00a0 0 \u00a0 \u00a0 - \u00a0 \u00a0 +0ns[ \u00a0 +0ns] +\/-\u00a0 \u00a0 0ns\r\n#? PST0\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 0 \u00a0 3 \u00a0 \u00a0 0 \u00a0 \u00a0 - \u00a0 \u00a0 +0ns[ \u00a0 +0ns] +\/-\u00a0 \u00a0 0ns\r\n^- jane.qotw.net \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 2 \u00a0 4 \u00a0 377\u00a0 \u00a0 10\u00a0 \u00a0 +20us[\u00a0 +20us] +\/- \u00a0 88ms\r\n^- ntp18.kashra-server.com \u00a0 \u00a0 \u00a0 2 \u00a0 4 \u00a0 177\u00a0 \u00a0 10\u00a0 +1485us[+1485us] +\/- \u00a0 95ms\r\n^- time.iqnet.com\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 2 \u00a0 4 \u00a0 377 \u00a0 \u00a0 4\u00a0 -1098us[-1097us] +\/-\u00a0 141ms\r\n^- www.almaprovence.fr \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 3 \u00a0 4 \u00a0 377 \u00a0 \u00a0 5\u00a0 -1196us[-1196us] +\/-\u00a0 115ms\r\nchronyc&gt;<\/pre>\n<p data-renderer-start-pos=\"6426\">The Chrony tracking command gives you an update of stratum Chrony thinks it is. In this case Stratum 1, it has some confidence about slaving from the GPS receiver.<\/p>\n<pre class=\"code-block \">chronyc&gt; tracking\r\nReference ID\u00a0 \u00a0 : 50505330 (PPS0)\r\nStratum \u00a0 \u00a0 \u00a0 \u00a0 : 1\r\nRef time (UTC)\u00a0 : Fri Aug 21 22:01:59 2020\r\nSystem time \u00a0 \u00a0 : 0.000000248 seconds fast of NTP time\r\nLast offset \u00a0 \u00a0 : +0.000000319 seconds\r\nRMS offset\u00a0 \u00a0 \u00a0 : 0.000000776 seconds\r\nFrequency \u00a0 \u00a0 \u00a0 : 0.923 ppm slow\r\nResidual freq \u00a0 : +0.000 ppm\r\nSkew\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : 0.034 ppm\r\nRoot delay\u00a0 \u00a0 \u00a0 : 0.000000001 seconds\r\nRoot dispersion : 0.000025404 seconds\r\nUpdate interval : 16.0 seconds\r\nLeap status \u00a0 \u00a0 : Normal\r\nchronyc&gt;<\/pre>\n<h2 id=\"Configuration-files\" data-renderer-start-pos=\"7066\">Configuration files<\/h2>\n<h3 id=\"GPSd:\" data-renderer-start-pos=\"7087\">GPSd:<\/h3>\n<h5>\/etc\/default\/gpsd<\/h5>\n<pre class=\"code-block \"># \/etc\/default\/gpsd\r\n## mod_install_stratum_one\r\n# Default settings for the gpsd init script and the hotplug wrapper.\r\n# Start the gpsd daemon automatically at boot time\r\nSTART_DAEMON=\"true\"\r\n# Use USB hotplugging to add new USB devices automatically to the daemon\r\nUSBAUTO=\"true\"\r\n# Devices gpsd should collect to at boot time.\r\n# They need to be read\/writeable, either by user gpsd or the group dialout.\r\n# DEVICES=\"\/dev\/ttyAMA0 \/dev\/pps0\"\r\n# in case you have two pps devices connected\r\n# DEVICES=\"\/dev\/ttyAMA0 \/dev\/pps0 \/dev\/pps1\"\r\n# We tell GPSD to use the console serial port.  Alas, it will try to open \/etc\/pps0.  \r\n# Run Chrony first to grab the port so GPSd doesn't get it.\r\nDEVICES=\"\/dev\/ttyAMA0\"\r\n# Other options you want to pass to gpsd\r\nGPSD_OPTIONS=\"-n -r -b\"\r\nGPSD_SOCKET=\"\/var\/run\/gpsd.sock\"\r\nBAUDRATE=\"9600\"\r\n# Serial setup\r\n# For serial interfaces, options such as low_latency are recommended\r\n# Also, http:\/\/catb.org\/gpsd\/upstream-bugs.html#tiocmwait recommends\r\n# \u00a0 setting the baudrate with stty\r\n# Uncomment the following lines if using a serial device:\r\n\/bin\/stty -F ${DEVICE} raw ${BAUDRATE} cs8 clocal -cstopb\r\n# \/bin\/setserial ${DEVICE} low_latency<\/pre>\n<h3 id=\"Chrony:\" data-renderer-start-pos=\"8245\">Chrony:<\/h3>\n<h5 data-renderer-start-pos=\"8254\">\/etc\/chrony\/stratum1\/10-refclocks-pps0.conf:<\/h5>\n<pre data-renderer-start-pos=\"8254\">######################################################################\r\n# PPS0\r\n# PPS: \/dev\/pps0: Kernel-mode PPS ref-clock for the precise seconds\r\n# refclock\u00a0 PPS \/dev\/pps0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 refid PPS0\u00a0 precision 1e-7\u00a0 poll 3\u00a0 trust\u00a0 noselect\u00a0 lock PSM0\r\nrefclock PPS \/dev\/pps0 refid PPS0 trust\r\n# SHM(0), gpsd: NMEA data from shared memory provided by gpsd\r\n# refclock\u00a0 SHM 0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 refid GPS0\u00a0 precision 1e-1\u00a0 poll 3\u00a0 trust\u00a0 noselect\u00a0 offset 0.0\r\nrefclock\u00a0 SHM 0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 refid GPS0\u00a0 precision 1e-1\u00a0 poll 3\u00a0 trust\u00a0 noselect\u00a0 offset 0.500\r\n# SHM(1), gpsd: PPS0 data from shared memory provided by gpsd\r\nrefclock\u00a0 SHM 1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 refid PSM0\u00a0 precision 1e-7\u00a0 poll 3\u00a0 trust\u00a0 prefer\r\n# SOCK, gpsd: PPS0 data from socket provided by gpsd\r\nrefclock\u00a0 SOCK \/var\/run\/chrony.pps0.sock\u00a0 refid PST0\u00a0 precision 1e-7\u00a0 poll 3\u00a0 trust\u00a0 noselect<\/pre>\n<h5 data-renderer-start-pos=\"9173\">\/etc\/chrony\/stratum1\/20-ntp-servers.conf:<\/h5>\n<pre class=\"code-block \"># NTP Servers\r\npool  2.debian.pool.ntp.org  iburst  minpoll 4  maxpoll 4<\/pre>\n<div class=\"heading-anchor-wrapper-old\">\n<div class=\"sc-jtggT ejYsQE\"><span style=\"font-size: 19px; font-weight: 900;\">rc.local:<\/span><\/div>\n<\/div>\n<pre class=\"code-block \"># for the GPS...\r\n# Start Chrony first to grab \/etc\/pps0 before GPSd does...\r\n\/usr\/local\/sbin\/chronyd\r\nsleep 2\r\nstty -F \/dev\/serial0 raw 9600 cs8 clocal -cstopb\r\n\/usr\/local\/sbin\/gpsd -n -b \/dev\/ttyAMA0 -F \/var\/run\/gpsd.sock<\/pre>\n<h2 id=\"References\" data-renderer-start-pos=\"9649\"><span data-renderer-mark=\"true\">References<\/span><\/h2>\n<ul class=\"ak-ul\">\n<li>\n<p data-renderer-start-pos=\"9663\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/learn.adafruit.com\/adafruit-ultimate-gps-hat-for-raspberry-pi\/\" href=\"https:\/\/learn.adafruit.com\/adafruit-ultimate-gps-hat-for-raspberry-pi\/\" data-renderer-mark=\"true\">Adafruit Ultimate GPS HAT for Raspberry Pi<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"9709\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/opensource.com\/article\/18\/12\/manage-ntp-chrony\" href=\"https:\/\/opensource.com\/article\/18\/12\/manage-ntp-chrony\" data-renderer-mark=\"true\">Manage NTP with Chrony<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"9735\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/wiki.alpinelinux.org\/wiki\/Chrony_and_GPSD\" href=\"https:\/\/wiki.alpinelinux.org\/wiki\/Chrony_and_GPSD\" data-renderer-mark=\"true\">Chrony and GPSD<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"9754\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/chrony.tuxfamily.org\/doc\/3.4\/chrony.conf.html\" href=\"https:\/\/chrony.tuxfamily.org\/doc\/3.4\/chrony.conf.html\" data-renderer-mark=\"true\">chrony.conf(5) Manual Page<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"9784\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/medium.com\/@srfilipek\/chronos-a-stratum-1-time-server-e7a89cd808bc\" href=\"https:\/\/medium.com\/@srfilipek\/chronos-a-stratum-1-time-server-e7a89cd808bc\" data-renderer-mark=\"true\">Chronos: A Stratum 1 Time Server<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"9820\"><a class=\"sc-fQejPQ dhiIZD\" title=\"http:\/\/robotsforroboticists.com\/chrony-gps-for-time-synchronization\/\" href=\"http:\/\/robotsforroboticists.com\/chrony-gps-for-time-synchronization\/\" data-renderer-mark=\"true\">chrony with GPS for Time Synchronization \u2013 Kicks NTP\u2019s A$$<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"9882\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/github.com\/beta-tester\/RPi-GPS-PPS-StratumOne\" href=\"https:\/\/github.com\/beta-tester\/RPi-GPS-PPS-StratumOne\" data-renderer-mark=\"true\">Github &#8211;\u00a0RPi-GPS-PPS-StratumOne<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"9917\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/www.raspberrypi.org\/forums\/viewtopic.php?t=189865\" href=\"https:\/\/www.raspberrypi.org\/forums\/viewtopic.php?t=189865\" data-renderer-mark=\"true\">How to lock GPS (with pps) in Rpi!<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"9955\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/gpsd.gitlab.io\/gpsd\/gpsd-time-service-howto.html#_enabling_pps\" href=\"https:\/\/gpsd.gitlab.io\/gpsd\/gpsd-time-service-howto.html#_enabling_pps\" data-renderer-mark=\"true\">GPSD Time Service HOWTO &#8211; Enabling PPS<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"9997\"><a class=\"sc-fQejPQ dhiIZD\" title=\"http:\/\/www.unixwiz.net\/techtips\/raspberry-pi3-gps-time.html#ntpd\" href=\"http:\/\/www.unixwiz.net\/techtips\/raspberry-pi3-gps-time.html#ntpd\" data-renderer-mark=\"true\">Building a GPS Time Server with the Raspberry Pi 3<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"10051\"><a class=\"sc-fQejPQ dhiIZD\" title=\"http:\/\/lists.ntp.org\/pipermail\/questions\/2017-August\/041269.html\" href=\"http:\/\/lists.ntp.org\/pipermail\/questions\/2017-August\/041269.html\" data-renderer-mark=\"true\">[ntp:questions] How to get shared memory access from gpsd to ntpd to work?<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"10129\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/wiki.dragino.com\/index.php?title=Getting_GPS_to_work_on_Raspberry_Pi_2_Model_B\" href=\"https:\/\/wiki.dragino.com\/index.php?title=Getting_GPS_to_work_on_Raspberry_Pi_2_Model_B\" data-renderer-mark=\"true\">Getting GPS to work on Raspberry Pi 2 Model B<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"10178\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/gpsd.gitlab.io\/gpsd\/installation.html\" href=\"https:\/\/gpsd.gitlab.io\/gpsd\/installation.html\" data-renderer-mark=\"true\">GPSD Installation Instructions<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"10212\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/github.com\/ntpsec\/gpsd\" href=\"https:\/\/github.com\/ntpsec\/gpsd\" data-renderer-mark=\"true\">Github &#8211;\u00a0<\/a><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/github.com\/ntpsec\" href=\"https:\/\/github.com\/ntpsec\" data-renderer-mark=\"true\">ntpsec<\/a>\/<a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/github.com\/ntpsec\/gpsd\" href=\"https:\/\/github.com\/ntpsec\/gpsd\" data-renderer-mark=\"true\">gpsd<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"10236\"><a class=\"sc-fQejPQ dhiIZD\" title=\"http:\/\/blog.boberglund.com\/Build_GPSD_from_sources.txt\" href=\"http:\/\/blog.boberglund.com\/Build_GPSD_from_sources.txt\" data-renderer-mark=\"true\">BUILDING GPSD FROM SOURCES ON RASPBERRY PI3<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"10283\"><a class=\"sc-fQejPQ dhiIZD\" title=\"https:\/\/www.raspberrypi.org\/forums\/viewtopic.php?f=28&amp;t=138711&amp;sid=d2a8b6c8f016a5ee200ca001c1af367c\" href=\"https:\/\/www.raspberrypi.org\/forums\/viewtopic.php?f=28&amp;t=138711&amp;sid=d2a8b6c8f016a5ee200ca001c1af367c\" data-renderer-mark=\"true\">Cannot get gpsd working on Pi3<\/a><\/p>\n<\/li>\n<li>\n<p data-renderer-start-pos=\"10317\">Description of <a class=\"sc-fQejPQ dhiIZD\" title=\"http:\/\/www.gpsinformation.org\/dale\/nmea.htm#GSA\" href=\"http:\/\/www.gpsinformation.org\/dale\/nmea.htm#GSA\" data-renderer-mark=\"true\">NMEA data<\/a> strings.<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div id=\"likes-and-labels-container\" class=\"ViewPage_likesAndLabelsContainer_nyS\" data-test-id=\"likes-and-labels-container\">\n<div>\n<div><span class=\"sc-dVhcbM kpxHwE\"><button class=\"sc-gqjmRU pGmuf\">Like<\/button><span data-test-id=\"likes-summary-span\">Be the first to like this<\/span><\/span><\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;A man with a\u00a0watch\u00a0knows what\u00a0time\u00a0it is. A man with two watches is never sure.&#8221; &#8211; Segal&#8217;s Law Introduction Keeping accurate time is critical for a number of things at an ISP. Accurate time is needed for debugging to see what devices were affected at what time.\u00a0 \u00a0If you had one reference clock that everything synced &hellip; <a href=\"https:\/\/blog.lns.com\/?p=210\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;A GPS Stratum 1 NTP Server&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,16],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.lns.com\/index.php?rest_route=\/wp\/v2\/posts\/210"}],"collection":[{"href":"https:\/\/blog.lns.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.lns.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.lns.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.lns.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=210"}],"version-history":[{"count":7,"href":"https:\/\/blog.lns.com\/index.php?rest_route=\/wp\/v2\/posts\/210\/revisions"}],"predecessor-version":[{"id":217,"href":"https:\/\/blog.lns.com\/index.php?rest_route=\/wp\/v2\/posts\/210\/revisions\/217"}],"wp:attachment":[{"href":"https:\/\/blog.lns.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=210"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lns.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=210"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lns.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=210"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}