{"id":13587326,"url":"https://github.com/beta-tester/RPi-GPS-PPS-StratumOne","last_synced_at":"2025-04-07T21:33:36.118Z","repository":{"id":187081624,"uuid":"57456020","full_name":"beta-tester/RPi-GPS-PPS-StratumOne","owner":"beta-tester","description":"setup a Raspberry Pi as a Stratum One time server (GPS with PPS)","archived":false,"fork":false,"pushed_at":"2024-01-06T08:38:51.000Z","size":214,"stargazers_count":110,"open_issues_count":2,"forks_count":27,"subscribers_count":18,"default_branch":"master","last_synced_at":"2024-02-14T21:49:00.147Z","etag":null,"topics":["chrony","gps","gpsd","ntp","ntp-server","pps","raspberry-pi","raspberrypi","raspbian","rpi","stratum"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/beta-tester.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-04-30T18:24:01.000Z","updated_at":"2024-04-15T08:58:31.977Z","dependencies_parsed_at":null,"dependency_job_id":"26384462-c3eb-4fc6-bbc9-67423f78c992","html_url":"https://github.com/beta-tester/RPi-GPS-PPS-StratumOne","commit_stats":null,"previous_names":["beta-tester/rpi-gps-pps-stratumone"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beta-tester%2FRPi-GPS-PPS-StratumOne","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beta-tester%2FRPi-GPS-PPS-StratumOne/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beta-tester%2FRPi-GPS-PPS-StratumOne/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beta-tester%2FRPi-GPS-PPS-StratumOne/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/beta-tester","download_url":"https://codeload.github.com/beta-tester/RPi-GPS-PPS-StratumOne/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247732871,"owners_count":20986944,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chrony","gps","gpsd","ntp","ntp-server","pps","raspberry-pi","raspberrypi","raspbian","rpi","stratum"],"created_at":"2024-08-01T15:06:09.518Z","updated_at":"2025-04-07T21:33:35.479Z","avatar_url":"https://github.com/beta-tester.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# RPi-GPS-PPS-StratumOne\n\nsetup a Raspberry Pi as an Stratum One NTP server.\u003cbr /\u003e\nit is a private project i have made for myself.\u003cbr /\u003e\ni did not keep an eye on network security.\n\n**the script will override some existing configurations**\u003cbr /\u003e\n(a backup of the changed configuration files will be stored to **backup.tar.xz**)\n\n**USE IT AT YOUR OWN RISK**\n\n**Please give me a '_Star_', if you find that project useful.**\n\n### overview schematic:\n```\n                     ╔═══╗       ╔══════╗         ╔══════╗  GPS-Antenna\n                   ──╢ s ║       ║RPi as╟RX───────╢GPS-  ║    ═╪═\n                     ║ w ║       ║NTP-  ╟TX───────╢module║     │\n                     ║ i ║       ║server║         ╠═══╗  ║     │\n       ╔══════╗      ║ t ╟───eth0╢      ╟GPIO#4───╢PPS║  ╟─────┘\n       ║ RPi  ╟──────╢ c ║       ║      ║         ╚═══╩══╝\n       ╚══════╝   ┌──╢ h ╟──┐    ║      ╟GPIO#7╴╴╴╢PPS║  ╟╴╴\n                  │  ╚═══╝  │    ╚══════╝         ╚═══╩══╝\n               ╔══╧══╗   ╔══╧══╗\n               ║ PC1 ║   ║ PC2 ║\n               ╚═════╝   ╚═════╝\n```\n### overview: path of time source\n(without external NTP servers)\n```\n╔═══════╗       ╔══════════════════╗\n║ GPS   ╫──RX───╫──┐ KERNEL        ║\n║ ╔═════╣       ║  │               ║                                     ╔══════════════\n║ ║NMEA─╫──TX───╫─[+]─/dev/ttyAMA0─╫────────┬───NMEA──x                  ║ CHRONY\n║ ╠═════╣       ║                  ║        │                            ║\n║ ║ PPS─╫─GPIO4─╫─────/dev/pps0────╫──────┬─)────────────────────────────╫──[+]────PPS0\n╚═╩═════╝      ╴╫╴╴┐               ║      │ │                            ║   │\n  ╠═════╣      ╴╫╴[+]╴/dev/ttyAMA1╴╫╴╴╴┐  │ │                            ║   │\n║ ║*PPS╴╫╴GPIO7╴╫╴╴╴╴╴/dev/pps1╴╴╴╴╫╴┬╴)╴╴)╴)╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╫╴╴╴)╴[+]╴PPS1*\n╚═╩═════╝       ╚══════════════════╝ ╵ ╵  │ │ ╔══════════════════╗       ║   │  ╵\n                                     ╵ ╵  │ │ ║ GPSD             ║       ║   │  ╵\n                                     ╵ ╵  │ │ ║                  ║       ║   │  ╵\n                                     ╵ ╵  │ └─╫─GPS0──┬──────────╫─SHM0──╫───)──)──GPS0\n                                     ╵ ╵  │   ║       │        ┌─╫─SHM1──╫───┴──)──PSM0\n                                     ╵ ╵  └───╫─PPS0─[+]───────┴─╫─SOCK0─╫──────)──PST0\n                                     ╵ ╵      ║                  ║       ║      ╵\n                                     ╵ └╴╴╴╴╴╴╫╴GPS1╴╴╴╴╴┬╴╴╴╴╴╴╴╫╴SHM2╴╴╫╴╴╴╴╴╴)╴╴GPS1*\n                                     ╵        ║          │     ┌╴╫╴SHM3╴╴╫╴╴╴╴╴╴┴╴╴PSM1*\n                                     └╴╴╴╴╴╴╴╴╫╴PPS1╴╴╴╴[+]╴╴╴╴┴╴╫╴SOCK1╴╫╴╴╴╴╴╴╴╴╴PST1*\n                                              ╚══════════════════╝       ╚══════════════\n*) optional second PPS device\n```\n## requirements\n\n### hardware:\n- Raspberry Pi (with LAN)\n- SD card\n- working network environment (with a connection to internet for installation only)\n- GPS module with PPS output (e.g. [Adafruit Ultimate GPS Breakout - 66 channel w/10 Hz updates - Version 3](https://www.adafruit.com/products/746)\n- optionally a second PPS device\n\n### software:\n- Raspberry Pi OS Bullseye (2021-10-30 or newer, [(link)](https://www.raspberrypi.org/downloads/raspbian/))\n\n## installation:\nassuming,\n- your Raspberry Pi is running Raspberry Pi OS Bullseye (2021-10-30 or newer),\n- and has a proper connection to the internet via LAN.\n- and your SD card is expanded,\n- and you connected the GPS module direct to the RPi's RX/TX pins of the GPIO and the GPS PPS pin to the RPi' GPIO 4\u003cbr\u003e\n  (you can use other GPIO pins for PPS by changing `dtoverlay=pps-gpio,gpiopin=...` in `/boot/config.txt`)\n\n0. clone this repository with:\n   `git clone https://github.com/beta-tester/RPi-GPS-PPS-StratumOne.git`\u003cbr\u003e\n   and change into the folder where it was cloned to (e.g.: `RPi-GPS-PPS-StratumOne`).\u003cbr\u003e\n   (in case it fails, because `git` is not installed yet, please do `sudo apt update; sudo apt install git` and try to clone the repository again)\n2. run `bash install-gps-pps.sh` to install necessary packages and setup Kernel PPS, GPSD, and NTP with PPS support.\n3. reboot your RPi with `sudo reboot`\n4. **_in case you have a RPi3, RPi3+, RPi4 or RPi0w with a built-in Bluetooth adapter, and the script didn't disabled Bluetooth successfully, please run `sudo raspi-conf` and disable the Bluetooth adapter there. otherwise the built-in Bluetooth adapter will block the serial port of the GPIO pins._**\n\ndone.\n\n## NOTES:\ngpsd v3.20 available on bullseye repository may have an issue with autobaud feature (finding the correct baud rate of the gps device automatically).\u003cbr\u003e\nyou may have to set the correct baud rate explicitly in the file `/etc/default/gpsd`\u003cbr\u003e\ne.g. for baud rate 115200:\u003cbr\u003e\n`GPSD_OPTIONS=\"--listenany --nowait --badtime --passive --speed 115200\"`\n### note1:\nthe chrony configuration files are in the `/etc/chrony/statum1` folder.\nonly files with `*.conf` will be included to the configuration.\nall other files in that folder will be ignored.\nby renaming the files you easily can enable and disable different configuration files.\n\n### note2:\n**PPS** is a high precise pulse, without a time information.\u003cbr /\u003e\n**GPS** (NMEA)  has date/time information, but with mostly lower precision.\n\nto combine **GPS** and **PPS** in chrony, there is a specific requirement, [(link)](https://chrony.tuxfamily.org/faq.html#_using_a_pps_reference_clock)\u003cbr /\u003e\nthat GPS data and PPS signal must have a time offset of less than **+/-200ms**\u003cbr /\u003e\notherwise the PPS signal is seen as false-ticker and will be rejected by chrony.\n\ndepending on your GPS device the offset used in my script can be way too off.\n\nto adjust the offset of GPS0 edit the file `/etc/chrony/stratum1/10-refclocks-pps0.conf`\n\nrefclock  SHM 0  refid GPS0  precision 1e-1  **offset _0.0_**  ...\n\nto find the actual offset, you can use gnuplot (already installed by the script)\nand run the plot script 99-calibrate-offset-gps0.gnuplot\nto visualize the actual histogram of the measured offsets.\u003cbr /\u003e\n```\n# stop gpsd and chrony, delete all log files, restart chrony and gpsd\n# wait few seconds to give time to create a log file,\n# and start the histogram.\n\nsudo systemctl stop --now gpsd.{service,socket} \u0026\u0026 sudo systemctl stop --now chrony \u0026\u0026 \\\nsudo rm -f /var/log/chrony/*.log \u0026\u0026 \\\nsudo systemctl start --now chrony \u0026\u0026 sudo systemctl start --now gpsd \u0026\u0026 \\\nsleep 10 \u0026\u0026 \\\ngnuplot ~/RPi-GPS-PPS-StratumOne/gnuplot/99-calibrate-offset-gps0.gnuplot\n```\nthe histogram will updated every minute. keep it running for at least 30 minutes.\nthe longer you keep it running the better offset value you can find.\n(but not longer than 24h. every 24h a new log will started from zero)\n\nthe x-value of the highest spike in the histogram is the offset value for the GPS0 you can \nonce you got a good offset, you can use your RPi + GPS offline.\n\nfor more information, see also:\u003cbr /\u003e\n`/etc/chrony/chrony.conf`\u003cbr /\u003e\n`/etc/chrony/statum1/99-calibrate-offset.gps0`\n\n### note3:\n- **GPS0** (NMEA), has a mostly a low accuracy.\n\n- **PPS0**, has the highest accuracy.\u003cbr /\u003e\nit is passed throught by the kernel to /dev/pps0.\u003cbr /\u003e\nin chrony there is a specific timing offset requirement to PPS, that may cause the PPS0 to be seen as false-ticker by chrony and may be rejected.\u003cbr /\u003e\n(see note2)\n\n- **PSM0**, is coming from the gpsd service via shared memory and is a combination of PPS0+NMEA, but handled by gpsd service.\u003cbr /\u003e\nit has a similar accuracy as the PPS0 directly, but does not require the specific requirements as noted under note 2, because gpsd knows how the relationship of this.\u003cbr /\u003e\nit is very accurate and does not need manual calibration. that's why it is selected by me as prefered refclock in `10-refclocks-pps0.conf`.\n\n- **PST0**, is used by gpsd socket to provide PPS0+NMEA information.\u003cbr /\u003e\nit has the same accuracy as PSM0 because they have the same time source.\n\n- **GPS1, PPS1, PSM1, PST1**, same as above, but only for the second GPS/PPS device.\n\nto properly restart chrony, use:\u003cbr /\u003e\n```\nsudo systemctl stop --now gpsd.{service,socket} \u0026\u0026 \\\nsudo systemctl restart --now chrony \u0026\u0026 \\\nsudo systemctl start --now gpsd\n```\nthis will disconnect all connected gpsd-clients.\n\n## enable second PPS:\nto enable a second PPS source (/dev/pps1), please uncomment the prepared lines in the following files:\n\n- `/boot/config.txt`\u003cbr /\u003e\nuncomment the line to:\u003cbr /\u003e\n`dtoverlay=pps-gpio,gpiopin=7,capture_clear  # /dev/pps1`\n\n- `/etc/default/gpsd`\u003cbr /\u003e\nuncomment the line to:\u003cbr /\u003e\n`DEVICES=\"/dev/ttyAMA0 /dev/pps0 /dev/pps1\"`\n\n- rename file `/etc/chrony/stratum1/11-refclocks-pps1.conf.disabled` to\u003cbr /\u003e\n`/etc/chrony/stratum1/11-refclocks-pps1.conf`\n\nand reboot the system.\n\n**be warned:** as long the kernel of the RPi uses \"soft\"-interrupts for the second PPS its accuracy is questionable.\u003cbr /\u003e\nfor tests i feeded both gpio-pins with the same signal from the same pps-device (shorted both pins) and noticed a time difference of about 20µs in chrony between /dev/pps0 and /dev/pps1\u003cbr /\u003e\nsee [(two gpio pins has different delays?)](https://www.raspberrypi.org/forums/viewtopic.php?f=28\u0026t=277074)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeta-tester%2FRPi-GPS-PPS-StratumOne","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbeta-tester%2FRPi-GPS-PPS-StratumOne","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeta-tester%2FRPi-GPS-PPS-StratumOne/lists"}