Raspberry Pi: NTP und GPS

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

Screenshot xgps

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.

Offset der GPS Zeit zur Clock (100 Messungen)

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.

Offset der Zeit des Routers zur Clock (100 Messungen)

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.

2 Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.