Meinen Raspberry Pi 4 (ohne Hardware-Uhr) habe ich mit einem Navilock NL-701US USB 2.0 GPS Empfänger u-blox 7 ausgerüstet. Der Empfänger hat eine sehr kleine Antenne und funktioniert nur eingeschränkt in Innenräumen. Also habe ich ihn an die Fensterscheibe geklebt. Erst nach etwas Probieren lieferte er schließlich über gpsd die Zeit. Allerdings zeigte xgps keinen Fix und ohne Fix liefert gpsd auch keine Zeit an NTP.
Aber der Reihe nach.
Einrichtung GPS
Als Erstes stecken wir den GPS-Dongle an den Raspberry Pi, dann installieren wir die nötige Software. Da der Raspberry Pi über keine Batterie gepufferte Uhr verfügt, ist der Service ntp meist installiert und aktiv. Um zu sehen, ob der Dongle erkannt wurde und auf welchen Schnittstellen er zu erreichen ist, nutze ich hwinfo.
sudo apt install ntp gpsd gpsd-clients gpsd-tools hwinfo
Als Erstes brauchen wir die Schnittstelle für GPS.
thomas@pi2:~ $ sudo hwinfo --usb
...
20: USB 00.0: 10200 Modem
[Created at usb.122]
Unique ID: lfzD.47bdd143Fz2
Parent ID: ADDn.mUqILwxEtWB
SysFS ID: /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0
SysFS BusID: 1-1.1:1.0
Hardware Class: modem
Model: "U-Blox [u-blox 7]"
Hotplug: USB
Vendor: usb 0x1546 "U-Blox AG"
Device: usb 0x01a7 "[u-blox 7]"
Revision: "1.00"
Driver: "cdc_acm"
Driver Modules: "cdc_acm"
Device File: /dev/ttyACM0
Device Files: /dev/ttyACM0, /dev/serial/by-id/usb-u-blox_AG_-_www.u-blox.com_u-blox_7_-_GPS_GNSS_Receiver-if00, /dev/gps0, /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.1:1.0
Speed: 12 Mbps
Module Alias: "usb:v1546p01A7d0100dc02dsc00dp00ic02isc02ip01in00"
Driver Info #0:
Driver Status: cdc_acm is active
Driver Activation Cmd: "modprobe cdc_acm"
Config Status: cfg=new, avail=yes, need=no, active=unknown
Attached to: #21 (Hub)
Für den Eintrag in der Datei /etc/default/gpsd habe ich /dev/gps0 genommen, weil die Bezeichnung eingängiger ist, als /etc/ttyACM0. Als Startoptionen habe ich –nowait genommen, weil GPS mit NTP genutzt werden soll, und –badtime, weil die Zeit auch dann geliefert werden soll, wenn es keine gute Position gibt.
Ein Blick hierzu in die man pages:
n, –nowait
Don’t wait for a client to connect before polling whatever GPS is associated with it. Some RS232 GPSes wait in a standby mode (drawing less power) when the host machine is not asserting DTR, and some cellphone and handheld embedded GPSes have similar behaviors. Accordingly, waiting for a watch request to open the device may save battery power. (This capability is rare in consumer-grade devices). You should use this option if you plan to use gpsd to provide reference clock information to ntpd through a memory-shared segment.
-r, –badtime
Use GPS time even with no current fix. Some GPSs have battery powered Real Time Clocks (RTC’s) built in, making them a valid time source even before a fix is acquired. This can be useful on a Raspberry Pi, or other device that has no battery powered RTC, and thus has no valid time at startup.
man gpsd
Nach diesen Eintragungen können wir gpsd mit den folgenden Befehlen starten und den Start prüfen:
sudo systemctl enable gpsd
sudo systemctl start gpsd
systemctl status gpsd
● gpsd.service - GPS (Global Positioning System) Daemon
Loaded: loaded (/lib/systemd/system/gpsd.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2022-04-02 04:27:18 CEST; 1 day 9h ago
TriggeredBy: ● gpsd.socket
Process: 18854 ExecStart=/usr/sbin/gpsd $GPSD_OPTIONS $OPTIONS $DEVICES (code=exited, status=0/SUCCESS)
Main PID: 18855 (gpsd)
Tasks: 2 (limit: 4915)
CPU: 1min 27.347s
CGroup: /system.slice/gpsd.service
└─18855 /usr/sbin/gpsd -n -r /dev/gps0
Apr 02 04:27:18 pi2 systemd[1]: Starting GPS (Global Positioning System) Daemon...
Apr 02 04:27:18 pi2 systemd[1]: Started GPS (Global Positioning System) Daemon.
Beim Start ohne den Parameter –badtime lieferte der GPS-Dongle anfangs keine Zeit an ntp. Dies wird auch bei einem Neustart des Raspberry Pi so sein, wenn der GPS-Dongle nicht separat mit Strom versorgt wird. Es kann zudem eine Weile dauern, bis die ersten Fix vorliegen. Das lässt sich wie oben beschrieben dem Parameter –badtime in der Datei /etc/defaults/gpsd umgehen.
Mit dem Tool xgps können wir die Funktion des gpsd prüfen. Es bieten sich auch andere Tools an, wie gpsmon oder gpscsv
Einrichtung NTP
In der Datei /etc/ntp.conf müssen wir nun GPS als Zeitquelle hinzufügen.
server 192.168.20.1 burst prefer
server byggvir.de
# GPS
server 127.127.28.0 minpoll 4 maxpoll 4 noselect
fudge 127.127.28.0 time1 0.040 refid GPS
# PPS
server 127.127.28.1
fudge 127.127.28.1 refid PPS
Der erste Eintrag ist meine Fritz!Box, die wiederum die Zeit über den Provider t-online bezieht. Dies ist im Moment die bevorzugte Zeitquelle. Der zweite Eintrag ist dieser Server, auf dem ein öffentlich zugänglicher NTP-Server läuft. Der dritte und vierte Eintrag ist schließlich GPS. Die GPS Zeit wird alle 16 Sekunden geholt. time1 ist ein Wert, der die interne Verarbeitungszeit kompensiert. Dazu später mehr.
Sollte NTP nicht automatisch eingerichtet sein, können wir den Service ntp mit folgenden Befehel aktivieren und starten. In jedem Fall müssen wir ntp nach dem Ändern der Konfigurationsdatei neu starten.
sudo systemctl enable ntp
sudo systemctl start ntp
# bzw.
sudo systemctl restart ntp
Die Einrichtung können wir nun mit ntpq -pn prüfen. Kurz nach dem Neustart ntp wird es wie hier dargestellt aussehen.
pi@pi2:~ $ ntpq -pn
remote refid st t when poll reach delay offset jitter
==============================================================================
*192.168.20.1 194.25.134.196 3 u 63 64 37 0.539 -0.150 0.059
127.127.28.0 .GPS. 0 l 14 16 377 0.000 -0.530 2.078
127.127.28.1 .PPS. 0 l - 64 0 0.000 +0.000 0.000
2a01:238:4216:4 130.149.17.21 2 u 57 64 37 22.164 +4.955 0.439
PPS (reach=0) funktioniert leider nicht. Dafür habe ich noch keine Ursache gefunden.
Fudge
Die Angabe time1 0.040 in der Zeile habe ich Pi mal Daumen auf 0.040s geschätzt.geschätzt.
fudge 127.127.28.0 time1 0.040 refid GPS
Leider ist die GPS Zeit auf dem Raspberry Pi 4 nicht so präzise und stabil, wie ich erwartet habe. Das Offset schwankt erheblich mit der Prozessorlast. Ohne Last und mit einem Korrekturwert 0 Sekunden ergibt sich folgendes Bild:
remote refid st t when poll reach delay offset jitter
==============================================================================
*192.168.20.1 194.25.134.196 3 u 36 64 37 0.790 +0.013 0.140
127.127.28.0 .GPS. 0 l 6 16 377 0.000 -40.578 1.232
127.127.28.1 .PPS. 0 l - 64 0 0.000 +0.000 0.000
2a01:238:4216:4 130.149.17.21 2 u 36 64 37 22.756 +1.417 0.346
Für eine genauere Schätzung habe ich maxpoll auf 4 gesetzt und den Raspberry Pi 1600 Sekunden ohne nennenswerte Last laufen lassen. Aus den 100 Messwerten ergab sich ein durchschnittlicher Offset von -41.41176 msec und Jitter von 1.13828 msec. Damit war die erste Pi mal Daumen Schätzung nicht schlecht.
Der Offset und Jitter zur Fritz!Box ist mit 0.0083 msec und 0.05621 wesentlich geringer, sodass sich durch die Nutzung des GPS als Zeitquelle leider kein Vorteil für die Genauigkeit ergibt. Trotzdem ist ein Pi mit GPS ein Stratum 1 Zeitserver.
Auch auf einem Raspberry PI 4 mit 4 GB wirken sich ressourcenhungrige Prozesse auf die Genauigkeit der Zeit aus. Dies fiel mir auf, weil auf dem Pi alle 5 Minuten umfangreiche Diagramme mit R berechnet werden.
Wenn Montag der Postbote die Hardware-Uhren für meine Pis liefert, werde ich sehen, wie sich diese auf die Genauigkeit auswirkt.
Update
Inzwischen habe ich den Raspberry Pi ein paar Stunden in Ruhe gelassen. Der Navilock hat inzwischen seinen Geist aufgegeben. Aus dem Lockfile /var/log/ntpstats/peerstats habe ich die Offsets der Zeitquellen grafisch in einem Diagramm dargestellt.
Fazit
Aus dem Raspberry Pi wird mit einem GPS USB-Dongle kein präziser Zeitserver.
[…] führte das dazu, dass ich einen alten GPS-USB-Dongle aus der Schublade gekramt habe, und an einem Raspberry Pi 4 als Zeitquelle angeschlossen […]
[…] Artikel Raspberry Pi: NTP und GPS habe ich beschrieben, wie ein GPS Dongle als Zeitquelle in GPS genutzt wird. Rein prinzipiell wird […]