| 1 | #+TITLE: Ninfacyzga-1 Time Tracking |
| 2 | #+AUTHOR: Steven Baltakatei Sandoval |
| 3 | #+EMAIL: baltakatei@gmail.com |
| 4 | * Time Tracking |
| 5 | ** About |
| 6 | This document was created by Steven Baltakatei Sandoval on |
| 7 | ~2020-07-23T22:27Z~ under a [[https://creativecommons.org/licenses/by-sa/4.0/][Creative Commons BY-SA 4.0 license]]. It |
| 8 | was updated by Steven Baltakatei Sandoval on ~2020-10-17T23:31Z~ |
| 9 | |
| 10 | ** Narrative |
| 11 | The ~ninfacyzga-01~ device is equipped with an Ozzmaker BerryGPS-IMU |
| 12 | module which provides time and location data to ~gpsd~ and ~chrony~. The |
| 13 | time is provided by GPS satellites which themselves are |
| 14 | equipped [fn:nasa_20020408_atomicclock] with atomic clocks. This |
| 15 | extremely accurate set of clocks are needed since a GPS receiver |
| 16 | calculates its position in space using a General Relativity |
| 17 | calculation that uses the small variations in the time stamps received |
| 18 | from each satellite. This means that ~gpsd~ may be used to set the |
| 19 | system clock without a need for an internet connection to a default |
| 20 | Debian time server; ~ninfacyzga-01~ can be its own time server. |
| 21 | |
| 22 | [fn:nasa_20020408_atomicclock] Title:[[https://science.nasa.gov/science-news/science-at-nasa/2002/08apr_atomicclock/][Tick-Tock Atomic Clock]]; |
| 23 | Date:2002-04-08; Website:NASA.gov; [[https://web.archive.org/web/20100429141752/http://science.nasa.gov/science-news/science-at-nasa/2002/08apr_atomicclock/][Archive-link]]; Archive-date: |
| 24 | 2010-04-29 |
| 25 | |
| 26 | ** Description |
| 27 | *** Hardware |
| 28 | Ozzmaker BerryGPS-IMU, Version 3 (see [[https://ozzmaker.com/berrygps-berrygps-imu-quick-start-guide/][ref]]). |
| 29 | *** Software |
| 30 | - [[https://www.raspberrypi.org/downloads/raspberry-pi-os/][Raspberry Pi OS]] : A GNU/Linux operating system derived from |
| 31 | Debian 10. This procedure was developed with version ~August 2020~. |
| 32 | |
| 33 | - [[https://tracker.debian.org/pkg/gpsd][~gpsd~]] : A background daemon app capable of interfacing with the |
| 34 | [[https://ozzmaker.com/berrygps-berrygps-imu-quick-start-guide/][Ozzmaker BerryGPS-IMU]]'s GPS submodule. Installed and initialized by |
| 35 | ~apt~. Should be installed along with the ~gpsd-clients~ |
| 36 | package. This procedure was developed with ~gpsd~ version |
| 37 | |
| 38 | - [[https://chrony.tuxfamily.org/][~chrony~]] : A set of programs capable of continuously adjusting the |
| 39 | system clock until it is synchronized with configurable time sources |
| 40 | such as GPS and PPS data provided by ~gpsd~. ~chrony~ may be |
| 41 | configured to act as an NTP time client or server. It uses the same |
| 42 | protocol as ~ntp~ but is a GPLv2 implementation. This procedure was |
| 43 | developed with ~chrony~ version ~3.4-4~. |
| 44 | |
| 45 | ** Operating Procedures |
| 46 | *** Initial Startup |
| 47 | **** Perform initial setup. |
| 48 | See [[file:../setup/README.org][Main Setup]] procedure. |
| 49 | **** Install Hardware for time tracking |
| 50 | See [[https://ozzmaker.com/forums/topic/connecting-gps-pps-pin/][this]] Ozzmaker forum topic about connecting the BerryGPS-IMU |
| 51 | ~T_PULSE~ pin to GPIO 18. |
| 52 | |
| 53 | #+CAPTION: An image showing how to connect the PPS signal from an Ozzmaker BerryGPS-IMU board to a Raspberry Pi Zero W. |
| 54 | #+NAME: fig:PPS_BERRYGPS_RASPIZW |
| 55 | [[../../img/Compact_Stratum_1_NTP_time_server_hardware,_October_2020.jpg]] |
| 56 | |
| 57 | Connect the ~T_PULSE~ connection on the BerryGPS-IMU-3 to GPIO pin 18 |
| 58 | (ex: with solder and wire) in order to provide the PPS data signal |
| 59 | generated by the BerryGPS-IMU to the Raspberry Pi. Processing of this |
| 60 | data signal is handled by adding a line to ~/boot/config.txt~ in the |
| 61 | next section ("Install Software"). |
| 62 | |
| 63 | Note: If it is desired to specify a custom GPIO pin besides the one |
| 64 | recommended, see this [[https://raspberryautomation.com/connect-multiple-ds18b20-temperature-sensors-to-a-raspberry-pi/][Raspberry Autom]] article. |
| 65 | |
| 66 | **** Install Software for time tracking |
| 67 | The time tracking function can be performed by two programs: ~gpsd~ |
| 68 | and ~chrony~. |
| 69 | |
| 70 | Basically, two things need to happen: |
| 71 | |
| 72 | 1. ~gpsd~ needs to be pointed towards the correct device files for |
| 73 | incoming GPS data (in NMEA format) and the PPS signal ("pulse per |
| 74 | second"; a high precision time signal). |
| 75 | |
| 76 | 2. ~chrony~ needs to be pointed towards the correct local IP addresses |
| 77 | where ~gpsd~ provides GPS data and the PPS signal. |
| 78 | |
| 79 | ~gpsd~ then will provide GPS and PPS data to ~chrony~ via a "shared |
| 80 | memory driver". |
| 81 | |
| 82 | ***** Install packages via ~apt~ |
| 83 | Run the following command to install the required packages. |
| 84 | : $ sudo apt install gpsd gpsd-clients python-gps pps-tools chrony |
| 85 | |
| 86 | ***** Enable PPS device |
| 87 | Modify the ~/boot/config.txt~ file in order to tell the Raspberry Pi |
| 88 | to expect PPS data on ~BCM 18~ (pin number 12; see [[https://pinout.xyz/][link]]). This is done |
| 89 | by adding the following line to ~/boot/config.txt~ as described on |
| 90 | [[https://ozzmaker.com/forums/topic/problems-with-pps-on-a-pi0w-running-raspian-and-attached-to-a-berrygps-imuv3/][this Ozzmaker page]]: |
| 91 | |
| 92 | : dtoverlay=pps-gpio,gpiopin=18 |
| 93 | |
| 94 | The ~/boot/config.txt~ file can be modified via: |
| 95 | |
| 96 | : $ sudo nano /boot/config.txt |
| 97 | |
| 98 | PPS data can be confirmed by running: |
| 99 | |
| 100 | #+BEGIN_EXAMPLE |
| 101 | $ sudo su - |
| 102 | # ppstest /dev/pps0 |
| 103 | trying PPS source "/dev/pps0" |
| 104 | found PPS source "/dev/pps0" |
| 105 | ok, found 1 source(s), now start fetching data... |
| 106 | source 0 - assert 1595708074.003644641, sequence: 219 - clear 0.000000000, sequence: 0 |
| 107 | source 0 - assert 1595708075.003709620, sequence: 220 - clear 0.000000000, sequence: 0 |
| 108 | source 0 - assert 1595708076.003779580, sequence: 221 - clear 0.000000000, sequence: 0 |
| 109 | source 0 - assert 1595708077.003850580, sequence: 222 - clear 0.000000000, sequence: 0 |
| 110 | #+END_EXAMPLE |
| 111 | |
| 112 | Note: For older Raspberry Pi models, it may be necessary to enable |
| 113 | ~pps-gpio~ via modifications to ~/etc/modules~ (see [[https://www.raspberrypi.org/forums/viewtopic.php?p=757747#p757747][link]]). |
| 114 | |
| 115 | ***** Enable GPS device |
| 116 | The Ozzmaker BerryGPS-IMU makes NMEA sentences available via the |
| 117 | serial "UART" device ~/dev/ttyAMA0~. If bluetooth has not been |
| 118 | disabled, the Raspberry Pi OS automatically creates a software "UART" |
| 119 | device at ~/dev/serial0~. See the "[[file:~/git-OC/ninfacyzga-01/doc/setup/README.org::*Disable%20Bluetooth][Disable Bluetooth]]" section in the |
| 120 | [[file:../setup/README.org][Main Setup]] Initial Startup procedure for instructions on how to |
| 121 | disable bluetooth to free up ~/dev/ttyAMA0~ for use by ~gpsd~. |
| 122 | |
| 123 | ***** Setup ~gpsd~ |
| 124 | See the "[[file:~/git-OC/ninfacyzga-01/doc/location/README.org::*Setup%20~gpsd~][Setup ~gpsd~]]" subsection within the "Initial Startup" section |
| 125 | of the Location Logging [[file:~/git-OC/ninfacyzga-01/doc/location/README.org][~README.org~]] file. There is one additional |
| 126 | change that must be made which is to add a ~/dev/pps0~ item to the |
| 127 | ~DEVICES=~ line in ~/etc/default/gpsd~ like so: |
| 128 | |
| 129 | : DEVICES="/dev/ttyAMA0 /dev/pps0" |
| 130 | |
| 131 | ~/dev/ttyAMA0~ is where ~gpsd~ can get NMEA data from the GPS unit. |
| 132 | |
| 133 | ~/dev/pps0~ is where ~gpsd~ can get a PPS signal. |
| 134 | |
| 135 | As an example, the following lines will be present in |
| 136 | ~/etc/default/gpsd~ if both location and time tracking are set up: |
| 137 | |
| 138 | #+BEGIN_EXAMPLE |
| 139 | START_DAEMON="true" |
| 140 | USBAUTO="false" |
| 141 | DEVICES="/dev/ttyAMA0 /dev/pps0" |
| 142 | GPSD_OPTIONS="-n" |
| 143 | #+END_EXAMPLE |
| 144 | |
| 145 | Make sure to enable ~gpsd~ to automatically start as a system service. |
| 146 | |
| 147 | : $ sudo systemctl enable gpsd |
| 148 | : $ sudo systemctl start gpsd |
| 149 | |
| 150 | ***** Setup ~chrony~ |
| 151 | Modify the configuration file for ~chrony~ at ~/etc/chrony/chrony.conf~. |
| 152 | |
| 153 | : $ sudo nano /etc/chrony/chrony.conf |
| 154 | |
| 155 | Add the following lines: |
| 156 | |
| 157 | #+BEGIN_EXAMPLE |
| 158 | # Get time from GPS (/dev/XXXX) and PPS (/dev/YYYY) |
| 159 | #refclock SOCK /run/chrony.XXXX.sock refid GPS precision 1e-1 offset 0.0000 |
| 160 | #refclock SOCK /run/chrony.YYYY.sock refid PP precision 1e-7 |
| 161 | refclock SHM 0 refid GPS precision 1e-1 offset 0.0000 delay 0.2 stratum 1 |
| 162 | refclock SHM 1 refid PPS precision 1e-7 stratum 1 |
| 163 | #+END_EXAMPLE |
| 164 | |
| 165 | Where |
| 166 | - ~XXXX~ : the basename of the GPS device's serial port. In this guide |
| 167 | it should be ~ttyAMA0~; other setups may use ~ttyS0~, ~ttyACM0~, or |
| 168 | ~serial0~. |
| 169 | |
| 170 | - ~YYYY~ : the basename of the PPS device's serial port. In this guide |
| 171 | it should be ~pps0~. |
| 172 | |
| 173 | Note: The ~refclock SOCK~ lines are left as comments in case ~gpsd~ |
| 174 | incorrectly maps the GPS and PPS data. |
| 175 | |
| 176 | The following commands may be useful for testing ~gpsd~ and ~chrony~ |
| 177 | configurations. |
| 178 | - ~sudo chronyc sources -v~ : Shows time sources and associated accuracy |
| 179 | information. |
| 180 | |
| 181 | - ~sudo chronyc tracking~ : Shows the current time difference between |
| 182 | the reference clock and the system clock. Note: ~chrony~ gradually |
| 183 | attempts to reduce the difference by changing the system clock. |
| 184 | |
| 185 | - ~sudo chronyc makestep~ : Force ~chrony~ to set the system clock to |
| 186 | match the reference clock immediately. |
| 187 | |
| 188 | - ~sudo systemctl enable chrony~ : Enable automatic startup of |
| 189 | ~chrony~ (Note: This command shouldn't be necessary since the act of |
| 190 | installing ~chrony~ via ~sudo apt install chrony~ should |
| 191 | automatically enable it). |
| 192 | |
| 193 | - ~sudo systemctl stop chrony~ : Stop ~chrony~. |
| 194 | |
| 195 | - ~sudo systemctl restart chrony~ : Restart ~chrony~. |
| 196 | |
| 197 | - ~sudo systemctl status chrony~ : Check status of ~chrony~ service. |
| 198 | |
| 199 | - ~sudo ntpshmmon~ : Shows live output of data using the shared memory |
| 200 | driver filled by ~gpsd~. ([[https://gpsd.gitlab.io/gpsd/gpsd-time-service-howto.html][ref]]) |
| 201 | |
| 202 | - ~sudo ipcs -m~ : Show live segments of the shared memory. ([[https://gpsd.gitlab.io/gpsd/gpsd-time-service-howto.html][ref]]) |
| 203 | |
| 204 | - ~sudo date -s '2020-07-07T00:00+0000'~ : Manually sets time to a |
| 205 | string. |
| 206 | |
| 207 | An example output of ~sudo chronyc sources -v~ will show something |
| 208 | similar to this: |
| 209 | |
| 210 | #+BEGIN_EXAMPLE |
| 211 | pi@ninfacyzga-1-x:~ $ sudo chronyc sources -v |
| 212 | 210 Number of sources = 6 |
| 213 | |
| 214 | .-- Source mode '^' = server, '=' = peer, '#' = local clock. |
| 215 | / .- Source state '*' = current synced, '+' = combined , '-' = not combined, |
| 216 | | / '?' = unreachable, 'x' = time may be in error, '~' = time too variable. |
| 217 | || .- xxxx [ yyyy ] +/- zzzz |
| 218 | || Reachability register (octal) -. | xxxx = adjusted offset, |
| 219 | || Log2(Polling interval) --. | | yyyy = measured offset, |
| 220 | || \ | | zzzz = estimated error. |
| 221 | || | | \ |
| 222 | MS Name/IP address Stratum Poll Reach LastRx Last sample |
| 223 | =============================================================================== |
| 224 | #- GPS 1 4 377 21 +110ms[ +110ms] +/- 200ms |
| 225 | #* PPS 1 4 377 22 +2496ns[+3045ns] +/- 1000ns |
| 226 | ^- vps-2d3ddab6.vps.ovh.ca 2 6 277 57 +1302us[+1304us] +/- 151ms |
| 227 | ^? time.richiemcintosh.com 2 6 1 59 +2626us[+2628us] +/- 92ms |
| 228 | ^- varuna.ga-group.nl 3 6 377 55 -3962us[-3960us] +/- 151ms |
| 229 | ^- ntp3.junkemailfilter.com 2 6 377 58 -4561us[-4558us] +/- 80ms |
| 230 | #+END_EXAMPLE |
| 231 | |
| 232 | General references for the ~chrony.conf~ file are: |
| 233 | |
| 234 | - The ~chrony~ ~4.0~ documentation. ([[https://chrony.tuxfamily.org/doc/4.0/chrony.conf.html][ref]]) |
| 235 | |
| 236 | - The ~gpsd~ documentation for communicating with ~chrony~. ([[https://gpsd.gitlab.io/gpsd/gpsd-time-service-howto.html#_feeding_chrony_from_gpsd][ref]]) |
| 237 | |
| 238 | - Setup guide for a USB GPS with ~gpsd~ and ~chrony~. ([[https://photobyte.org/raspberry-pi-stretch-gps-dongle-as-a-time-source-with-chrony-timedatectl/][ref]]) |
| 239 | |
| 240 | ***** Disable CPU power saving |
| 241 | Power saving featurs of the Raspberry Pi Zero W may also be disabled |
| 242 | in order to improve accuracy. |
| 243 | |
| 244 | ****** Configure CPU ~scaling_governor~ |
| 245 | If additional precision is required, the PPS signal may be made more |
| 246 | reliable at the cost of increasing CPU power by configuring the CPU to |
| 247 | always run at maximum frequency.[fn:se_20180320_raspicpugov] This |
| 248 | change can be performed by modifying the following file as root: |
| 249 | |
| 250 | : /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor |
| 251 | |
| 252 | The file should consist of one line. Change |
| 253 | |
| 254 | : ondemand |
| 255 | |
| 256 | to |
| 257 | |
| 258 | : performance |
| 259 | |
| 260 | . |
| 261 | |
| 262 | This change can be performed via the ~nano~ text editor by running the |
| 263 | following commands: |
| 264 | |
| 265 | : $ sudo su - |
| 266 | : # nano /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor |
| 267 | |
| 268 | Additionally, in order to prevent the ~raspi-config~ init script from |
| 269 | reverting this text file back to ~ondemand~ after a reboot, this |
| 270 | script must be disabled via: |
| 271 | |
| 272 | : $ sudo systemctl disable raspi-config |
| 273 | |
| 274 | ****** Configure ~/boot/config.txt~ |
| 275 | Modify ~/boot/config.txt~ so that it contains these lines in order to |
| 276 | disable power saving functions: |
| 277 | |
| 278 | #+BEGIN_EXAMPLE |
| 279 | # Disable power saving |
| 280 | nohz=off |
| 281 | #+END_EXAMPLE |
| 282 | |
| 283 | [fn:se_20180320_raspicpugov] Title:[[https://raspberrypi.stackexchange.com/questions/9034/how-to-change-the-default-governor]["How to change the default governor?"]]; Author:[[https://raspberrypi.stackexchange.com/users/5538/goldilocks][goldilocks]]; Date: 2018-03-20; Website:stackexchange.com; |
| 284 | |
| 285 | *** Normal Startup |
| 286 | *** Normal Operation |
| 287 | *** Normal Shutdown |
| 288 | *** Unscheduled Shutdown |
| 289 | ** Appendix A |
| 290 | *** Example ~chrony.conf~ for ~chrony~ |
| 291 | For Raspberry Pi OS, the configuration file should be installed at |
| 292 | ~/etc/chrony/chrony.conf~. |
| 293 | |
| 294 | #+BEGIN_EXAMPLE |
| 295 | # Welcome to the chrony configuration file. See chrony.conf(5) for more |
| 296 | # information about usuable directives. |
| 297 | pool 2.debian.pool.ntp.org iburst |
| 298 | |
| 299 | # This directive specify the location of the file containing ID/key pairs for |
| 300 | # NTP authentication. |
| 301 | keyfile /etc/chrony/chrony.keys |
| 302 | |
| 303 | # This directive specify the file into which chronyd will store the rate |
| 304 | # information. |
| 305 | driftfile /var/lib/chrony/chrony.drift |
| 306 | |
| 307 | # Uncomment the following line to turn logging on. |
| 308 | #log tracking measurements statistics |
| 309 | |
| 310 | # Log files location. |
| 311 | logdir /var/log/chrony |
| 312 | |
| 313 | # Stop bad estimates upsetting machine clock. |
| 314 | maxupdateskew 100.0 |
| 315 | |
| 316 | # This directive enables kernel synchronisation (every 11 minutes) of the |
| 317 | # real-time clock. Note that it can’t be used along with the 'rtcfile' directive. |
| 318 | rtcsync |
| 319 | |
| 320 | # Step the system clock instead of slewing it if the adjustment is larger than |
| 321 | # one second, but only in the first three clock updates. |
| 322 | makestep 1 3 |
| 323 | |
| 324 | # Get time from GPS (/dev/ttyAMA0) and PPS (/dev/pps0) |
| 325 | #refclock SOCK /run/chrony.ttyAMA0.sock refid GPS precision 1e-1 offset 0.0000 |
| 326 | #refclock SOCK /run/chrony.pps0.sock refid PP precision 1e-7 |
| 327 | refclock SHM 0 refid GPS precision 1e-1 offset 0.0000 delay 0.2 stratum 1 |
| 328 | refclock SHM 1 refid PPS precision 1e-7 stratum 1 |
| 329 | #+END_EXAMPLE |