Raspberry Pi APRS Tracker

As the SD cards of my Raspberry Pi based APRS tracker died I had to rebuild it. And due to not having a backup the the config files it is documented here.

# Install/Remove Software packages

Install necessary software packages:

$ sudo apt install gpsd gpsd-clients gpsd-tools minicom ntp direwolf

Also delete unnecessary / conflicting software packages:

$ sudo apt purge modemmanager

# Disable Serial Console on GPIO Header

Edit /boot/cmdline.txt and remove the “console=serial0,115200”. Then stop and disable the corresponding services:

$ sudo systemctl stop serial-getty@ttyAMA0.service
$ sudo systemctl disable serial-getty@ttyAMA0.service

# Enable WM8731 Audio Hat

Edit /boot/config.txt and disable onboard sound and instead enable WM8731 sound chip on GPIO header:

# Disable snd_bcm2835 onboard audio
# dtparam=audio=on

# Enable WM8731 codec

# Change Device Name of Sound Card

To find out the device path execute udevadm monitor for sound subsystem:

$ udevadm monitor --kernel --property --subsystem-match=sound

While unloading and loading the snd_soc_rpi_proto module. Then add udev rule like:

SUBSYSTEM=="sound" DEVPATH=="/devices/platform/soc/soc:sound/sound/card0", ATTR{id}="SVX_HAT" TAG+="systemd", ENV{SYSTEMD_WANTS}="direwolf.service"

Just add an udev rule /etc/udev/rules.d/50-usbserial.rules:

SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="AH01CE6Q", SYMLINK+="gpsmouse", GROUP="dialout", MODE="0660"

GPS device will be available as /dev/gpsmouse

# Building GPSD

Apparently the shipped package version 3.22 in Debian bullseye has a problem. For some reason clients only get one fix once they connect but this position is not updated while holding the connection. Instead the position is only updated upon restart of gpsd (see [1]). This is obviously not what we want :)

So gpsd has to be compiled from source. The current version 3.25 does not suffer from this problem. So here is the script to compile the sources:

$ sudo apt purge gpsd
$ sudo apt install -y scons   libncurses-dev python-dev pps-tools git-core asciidoctor python3-matplotlib  build-essential manpages-dev pkg-config python3-distutils
$ wget http://download-mirror.savannah.gnu.org/releases/gpsd/gpsd-3.25.tar.gz
$ tar -zvxf gpsd-3.25.tar.gz
$ cd gpsd-3.25/
$ scons
$ sudo scons install
$ sudo scons udev-install

# GPSD configuration

Edit /etc/default/gpsd:

# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.

# Other options you want to pass to gpsd
GPSD_OPTIONS="-n -s 9600 -f 8N1"

# Automatically hot add/remove USB GPS devices via gpsdctl
GPS Receiver with PPS wired to DCD
GPS Receiver with PPS wired to DCD

Testing of gpsd can be done using cgps on the console:

Screenshot of cgps
Screenshot of cgps

# NTP configuration

Edit /etc/ntp.conf and comment out the internet available servers. Add:

# PPS sync 
server prefer
fudge time1 1 refid PPS

# GPSD sync
fudge time1 0.183 flag1 1 refid GPS

This shall lead to ntp reading the time off gpsd to solve the issue that the Raspberry Pi A+ itself does not have a RTC and no internet to sync to NTP servers (see [2] and [3]). The flag1 set to 1 is important to allow time changes by NTP larger than 24h which can happen after hours of powered-off.

# Configurung direwolf

With a few hints from [4] it is easy to add gpsd connection to direwolf:

ADEVICE plughw:0,0
MODEM 1200
TBEACON DELAY=0:00 EVERY=1:00 VIA=WIDE1-1,WIDE2-1 SYMBOL=car COMMENT="Florian N18 Bochum"
SMARTBEACONING 30 0:90 5 20 0:15 30 255
CBEACON DELAY=10:00 DEST=APRS EVERY=10 INFO=">https://www.florian-wolters.de/posts/raspberry-pi-aprs-tracker/"
#LOGDIR /var/log/direwolf

If smart beaconing is used there also has to be a config line TBEACON to configure symbol and message etc. Just a single SMARTBEACONING line will simply result in no positions being sent at all.

By default direwolf starts way too early in the boot process where soundcard and GPIOs are not setup or available yet. Therefore the systemd service file for direwolf has been changed so that it requires multi-user.target to be reached before starting direwolf:

Description=DireWolf is a software "soundcard" modem/TNC and APRS decoder
After=sys-devices-platform-soc-soc:sound-sound-card0.device multi-user.target

SupplementaryGroups=dialout audio
ExecStart=/usr/bin/direwolf -c /etc/direwolf.conf


# Read-Only Filesystems

As the last SD card probably died by wearing in out this time the operating system was setup to work from read-only filesystem. There is a number of things to change which are documented in [5]. After that the system mounts the SD card read-only and prevents the OS from writing to the card all the time and make it immune against power-offs during write operations to the SD card.

# References

[1] https://raspberrypi.stackexchange.com/questions/136196/why-does-gpsd-not-update-a-location-past-its-first-fix
[2] https://www.rjsystems.nl/en/2100-ntpd-garmin-gps-18-lvc-gpsd.php
[3] https://raspberry.tips/raspberrypi-tutorials/raspberry-pi-uhrzeit-ueber-gps-beziehen-zeitserver
[4] https://www.marrold.co.uk/2019/04/adding-usb-gps-receiver-to-direwolf-to.html
[5] https://medium.com/@andreas.schallwig/how-to-make-your-raspberry-pi-file-system-read-only-raspbian-stretch-80c0f7be7353