Skip to main content...

ChroGPS Dash Hardware Setup

Overview

Before installing ChroGPS Dash, you need a working GPS/NTP stack: GPSd receiving position and timing data from your GNSS receiver, and Chrony disciplined by that data. The hardware provisioning script builds this stack for you automatically, handling package installation, device configuration, and Chrony refclock setup.

Two GNSS connection modes are supported:

Mode Hardware Platform PPS Support Typical Accuracy
GPIO GNSS HAT via UART + PPS GPIO pin Raspberry Pi only Yes < 1 µs offset
USB USB GNSS receiver (e.g. u-blox) Any Debian-based system No — NMEA only ±0.5 ms or worse

Note
GPIO mode with PPS delivers the best timing accuracy because the PPS pulse arrives outside the OS scheduler — independent of USB latency, interrupt jitter, and NMEA sentence processing. USB mode is convenient and broadly compatible but disciplines the clock solely from NMEA sentences, which carry unavoidable USB latency.

Hardware Provisioning

Important
Connect your GNSS hardware before running the script. Auto-detection of USB devices and GPIO serial interfaces depends on the hardware being present. If the receiver is not connected, the script may fall back to the wrong mode or prompt you to specify a device manually.
Recommended

Hardware Provisioning — One-Line Setup

Run the following command on your GPS server. The script auto-detects your platform and GNSS connection and prompts for confirmation before making any changes.

curl -fsSL https://chro.gpsda.sh/hardware-init | sudo bash

You can also pass flags to skip auto-detection and force a specific configuration:

# GPIO mode (Raspberry Pi + GNSS HAT), default GPIO pin 18:
curl -fsSL https://chro.gpsda.sh/hardware-init | sudo bash -s -- --mode gpio

# GPIO mode with a specific PPS GPIO pin:
curl -fsSL https://chro.gpsda.sh/hardware-init | sudo bash -s -- --mode gpio --gpio 4

# USB mode (auto-detect device):
curl -fsSL https://chro.gpsda.sh/hardware-init | sudo bash -s -- --mode usb

# USB mode with a specific device path:
curl -fsSL https://chro.gpsda.sh/hardware-init | sudo bash -s -- --mode usb --device /dev/ttyACM0

What the script provisions

All modes:

  • Installs: gpsd, gpsd-clients, chrony, pps-tools
  • Configures /etc/default/gpsd for your GNSS device
  • Configures Chrony refclocks appropriate for the mode
  • Enables gpsd.socket, gpsd, and chrony to start at boot

GPIO mode (Raspberry Pi only) — additionally:

  • Adds to /boot[/firmware]/config.txt:
    • enable_uart=1 — enables the hardware UART
    • dtoverlay=disable-bt — disables Bluetooth on Pi 3/4/Zero W/Zero 2W, which would otherwise occupy the reliable PL011 UART and force the GPS onto the unreliable mini-UART
    • dtoverlay=pps-gpio,gpiopin=N — exposes the PPS signal from the HAT as /dev/pps0
  • Removes the serial console from cmdline.txt (backed up as cmdline.txt.bak) so GPSd can own the UART
  • Masks serial-getty@ttyS0 and serial-getty@ttyAMA0 to prevent conflicts
  • Creates /etc/modules-load.d/pps-gpio.conf so the pps-gpio kernel module loads at boot
  • Configures Chrony with SHM 0 noselect (NMEA used only as a lock anchor) + PPS /dev/pps0 lock GPS prefer (PPS drives synchronization)

USB mode — additionally:

  • Configures Chrony with SHM 0 (NMEA disciplines the clock, with offset 0.5 to compensate for USB latency)
  • Restarts GPSd and Chrony immediately — no reboot needed

GPIO mode: reboot required

Important

After GPIO mode setup, you must reboot before GPSd and Chrony will work correctly. The Device Tree overlays added to config.txt (pps-gpio, disable-bt) only take effect after a reboot. The /dev/pps0 device will not exist until then, and Chrony will not be able to start with the PPS refclock configured.

sudo reboot

Once provisioning completes, the script will prompt whether you want to install ChroGPS Dash. If you choose yes, the dashboard installer runs automatically — no need to run a separate command. If you are in GPIO mode and install before rebooting, the dashboard installer will show a yellow advisory message about the deferred Chrony restart — this is expected. Everything will work after reboot.

Verifying the setup (after reboot)

After rebooting a GPIO mode system, verify the stack:

# PPS device is present:
ls -l /dev/pps0

# Confirm pps-gpio and disable-bt overlays loaded:
dtoverlay -l

# GPSd has a fix and is receiving data:
gpsmon

# Chrony sees the GPS/PPS refclocks:
chronyc sources -v

# Chrony is synchronized and stable:
chronyc tracking

In chronyc sources, a healthy GPIO/PPS setup shows two refclock lines. The NMEA source will be marked ? or x (used only as a lock anchor, not a sync source), while the PPS source will be marked * (the active sync source).

For USB mode, skip the pps0 and dtoverlay checks — just verify GPSd is receiving data and Chrony shows the NMEA refclock marked *.

Removing Hardware Provisioning

To fully reverse everything the provisioning script configured:

Recommended

Hardware Provisioning Removal — One-Line Teardown

curl -fsSL https://chro.gpsda.sh/hardware-uninit | sudo bash

The removal script:

  • Stops and disables gpsd.socket, gpsd, and chrony
  • Purges pps-tools, gpsd, gpsd-clients, and chrony (including their configs)
  • GPIO mode: removes all entries added to config.txt, restores cmdline.txt from the .bak backup, unmasks serial-getty units, and removes the pps-gpio module load config
  • Prompts whether to also uninstall the ChroGPS Dash web dashboard
Important
A reboot is recommended after GPIO mode removal to deactivate the Device Tree overlays. Until then, the pps-gpio overlay remains active from the previous boot.

Command Reference

hardware-init — Provisioning Script

Flag Description
(no flag) Auto-detect platform and GNSS connection, then provision
-m gpio / --mode gpio Force GPIO mode (Raspberry Pi GNSS HAT + PPS). Requires Raspberry Pi hardware.
-m usb / --mode usb Force USB mode (USB GNSS receiver, NMEA-only, no PPS)
-g <pin> / --gpio <pin> PPS GPIO pin number — GPIO mode only (default: 18)
-d <path> / --device <path> GNSS device path (default: auto — /dev/serial0 for GPIO, /dev/ttyACM0 or /dev/ttyUSB0 for USB)
-h / --help Show usage information

Examples:

Auto-detect and provision:

curl -fsSL https://chro.gpsda.sh/hardware-init | sudo bash

GPIO mode, default PPS pin (18):

curl -fsSL https://chro.gpsda.sh/hardware-init | sudo bash -s -- --mode gpio

GPIO mode, custom PPS pin:

curl -fsSL https://chro.gpsda.sh/hardware-init | sudo bash -s -- --mode gpio --gpio 4

USB mode, auto-detect device:

curl -fsSL https://chro.gpsda.sh/hardware-init | sudo bash -s -- --mode usb

USB mode, specific device path:

curl -fsSL https://chro.gpsda.sh/hardware-init | sudo bash -s -- --mode usb --device /dev/ttyACM0

hardware-uninit — Removal Script

The removal script takes no flags. It detects what the init script provisioned and prompts for confirmation before removing anything.

curl -fsSL https://chro.gpsda.sh/hardware-uninit | sudo bash

Supported Platforms

Platform GPIO Mode USB Mode
Raspberry Pi OS (Bookworm or newer) Yes Yes
Debian 12 (bookworm) or newer No Yes
Ubuntu 22.04 LTS or newer No Yes
Armbian (Debian 12+ / Ubuntu 24.04+ base) No* Yes

*GPIO mode requires Raspberry Pi Device Tree infrastructure (config.txt, dtoverlay). It is only supported on Raspberry Pi hardware.

Note
Troubleshooting hardware provisioning issues? See the Troubleshooting page for common post-provisioning problems, including Chrony failure before the first reboot and GPSd not seeing the serial device.

Last Revision: 2026-06-30 -- Document Version: e59e52d
Permanent Link: <https://w0chp.radio/chrogps-dash/hardware-setup/>