One of my never-ending projects is building a packet radio “Go Kit”, largely based around Ed, W6ELA’s “APRS Box” concept. After some extensions to add Packet BBS, Winlink, and AREDN support, I’ve started calling the thing a “PiComm” unit. One day I’ll write up more on it.
One of the more critical components of the setup is a GPS receiver: this provides location info for APRS, and allows the Raspberry Pi (which has no Real-Time Clock) to know what time it is without accessing the internet. I grabbed this unit, which had great reviews and 1-day shipping.
I am an impatient ham, after all.
Once it arrived, I installed GPSD on Raspbian Jesse and plugged it in. In theory, the system should have seen the GPS device appear on USB and automatically started GPSd. Except…it didn’t. Worried I got a dead unit, I did some digging and found the device was present by running lsusb -v
and dmesg | grep -i usb
, and which showed the device mounting at /dev/ttyACM0
. Running cat /dev/ttyACM0
got me lots of raw GPS data, too - the receiver was fine. So why wasn’t GPSd starting automatically?
On Linux the job of starting services or auto-running commands when devices are plugged in are handled by a service called uDev
, which uses a somewhat cryptic language to define rules that trigger actions - like auto-mounting a USB hard drive when it’s plugged in. When installed on Raspbian, GPSd automatically defines rules for many receivers in /lib/udev/rules.d/60-gpsd.rules
- but doesn’t include rules for u-Blox 7 receivers:
# u-blox AG, u-blox 5 (tested with Navilock NL-402U) [linux module: cdc_acm]
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a5", SYMLINK+="gps%n", TAG+="systemd", ENV{SYSTEMD_WANTS}="gpsdctl@%k.service"
# u-blox AG, u-blox 6 (tested with GNSS Evaluation Kit TCXO) [linux module: cdc_acm]
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a6", SYMLINK+="gps%n", TAG+="systemd", ENV{SYSTEMD_WANTS}="gpsdctl@%k.service"
Admittedly, that looks pretty close to what I saw earlier from running lsusb -v
- but not close enough:
Bus 001 Device 008: ID 1546:01a7 U-Blox AG
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 2 Communications
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1546 U-Blox AG
idProduct 0x01a7
bcdDevice 1.00
iManufacturer 1
iProduct 2
iSerial 0
bNumConfigurations 1
Everything is the same with the uBlox 7 chipset, except the idProduct
is different: 01a7, vs. 01a6 or 01a5. So, to get uDev to launch GPSd automatically when I plug it in (or when the system boots), I just copy one of the existing lines and edit the idProduct
to match mine:
# u-blox AG, u-blox 7 (Tested with VANWEI VK-162) [linux module: cdc_acm]
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a7", SYMLINK+="gps%n", TAG+="systemd", ENV{SYSTEMD_WANTS}="gpsdctl@%k.service"
Reload the uDev rules and et voilà! Even better, GPSd re-maps the devices entry in /dev to /dev/gps0
, which makes it easy to configure other apps like Polaric to grab position data - regardless of what receiver you use.