Updating GPSD for Galileo
Having recently purchased a couple of GPS modules from Uputronics which were capable of Galileo operation, I wanted to use these modules to see how they worked in a domestic environment using Raspberry Pi cards. This needs version 3.20 of the gpsd package, but at the time of writing (May-2020) the current release of Raspbian only provides 3.17. 3.20 includes an improved cgps program which includes a better indication of the satellites in use making it easier to see whether the hardware has actually found the satellites! By default, the units I have are activated for just GPS and GLONASS, and require the Galileo to be activated after each power-cycle (although a few hours large capacitor backup is provided).
I've provided notes on installing GPSD from scratch, running as a service, some Linux commands, and the hardware
I've used. My preferred method is now to install GPSD from scratch, as
I've had issues with using backports and trying to update an existing GPSD
installation from the OS distribution. These older method are archived at
the end of this page - using backports, and updating
an existing GPSD install.
My interest in this dates back some time to the first operational availability of Galileo data. I've long been a fan of the professionally made Uputronics GPS modules, so I was delighted to find that a ready-made general purpose unit was available in addition to the HAT device already offered for the full-size Raspberry Pi. This unit is applicable to a wider range of devices that just the Raspberry Pi. Here it is, together with the HAT version. For Galileo operation you need the breakout as that us supplied with the MAX-M8Q-0-10 module, or the HAT supplied since mid-2020 which includes a more recent u-blox module, and a real-time clock (RTC) for operation without GPS signals.
I also had the chance to try the Pico module, which swaps the capacitor backup and SMA socket for a built-in chip antenna. Here it is, together with my test lash-up.
This uses the u-blox MAX-M8C-0-10 device, which basically offers the same facilities in a more compact unit, although there is no 1 PPS timepulse output. Having the un-amplified chip antenna means that the device is much less sensitive indoors. I tried to improve the signal level by clamping the unit to an insulated copper-clad board with the black elastic band you can see in the photo, but that didn't seem to improve things. Eventually I go the unit just poking out of the window on an extension lead but this made testing rather awkward! As with the breakout, you need you need to send a command to enable Galileo.
However, I've more recently discovered that you can send a SAVE command to
the u-blox with the super-capacitor backup so that it keeps the Galileo enabled
over reboots and brief power outages. This is described below.
Note that the Raspberry Pi 3 and 4 have changes so that the PL011 UART0 is set for Bluetooth, and the miniUART is set for the "primary" GPIO pins 14/15. This is undesirable as the mini UART has a variable baud rate according to the CPU speed! You can change this by adding a line to /boot/config.txt which allocated the miniUART to the Bluetooth and the better PL011 UART to the GPIO pins. In devices:
The connection is by symbolic links, which you can check for yourself:
As supplied, by default:
pi@RasPi-23:~ $ ls -l /dev/ser* lrwxrwxrwx 1 root root 5 May 31 11:21 /dev/serial0 -> ttyS0 lrwxrwxrwx 1 root root 7 May 31 11:21 /dev/serial1 -> ttyAMA0
Edit: sudo nano /boot/config.txt, add: dtoverlay=pi3-miniuart-bt
pi@RasPi-23:~ $ ls -l /dev/ser* lrwxrwxrwx 1 root root 7 Jun 1 08:56 /dev/serial0 -> ttyAMA0 lrwxrwxrwx 1 root root 5 Jun 1 08:56 /dev/serial1 -> ttyS0
Be aware of this in the notes above. This is better explained here: https://www.raspberrypi.org/documentation/configuration/uart.md
Building GPSD from scratch
At the end of May-2020, a beta of the 64-bit Raspberry Pi OS was released. This basically works just the same way as the 32-bit version, so here are some very condensed notes. The same commands also work on the 32-bit Buster OS and the recently renamed Raspberry Pi OS.
Compiling a monitoring program
I wrote a GPS monitoring program which is described here. With each of the methods listed here I had minor issues when compiling linking and running. With the install from scratch method, I noted:
Enabling Galileo as a permanent option
If you have a u-blox module with the Galileo capability, you can use this command to enable it:
# ubxtool -e GALILEO -P 18.00
To save that capability (and other settings) permanently in a module with the battery backup option:
# ubxtool -p SAVE -P 18.00
It's unclear whether these commands need to be run as root or not. The "-P 18.00" is for my u-blox device, your may be different, and it's not needed if you've run the export command: export UBXOPTS="-P 18"
There is more about saving u-blox settings in section 3.1 Configuration Concept in this document:
Base on notes from Charles Curley, many thanks! Paul Theodoropoulos commented that he prefer to have the option variables left in the gpsd.service file and set the values in /etc/default/gpsd file instead, as per the normal practice.
Check if there is already a service running:
pi@RasPi-23:~ $ sudo systemctl status gpsd.service
If it reports "Unit gpsd.service could not be found" then check in /etc/systemd/system for a gpsd.service file. if there's not one there, there is an example one in the download from GIT at ~/gpsd/systemd/gpsd.service (if you're using the directory structure from the previous paragraphs). This is a somewhat generic file, with the options and device for gpsd not complete.
The gpsd.service file, along with the other two, must be copied to /etc/systemd/system, and you can check with the "ls -l" command:
pi@RasPi-23:~/gpsd/systemd $ sudo cp gpsd* /etc/systemd/systempi@RasPi-23:~ $ ls -l /etc/systemd/system/gps* -rw-r--r-- 1 root root 452 Jun 6 18:37 /etc/systemd/system/gpsdctl@.service -rw-r--r-- 1 root root 356 Jun 6 18:52 /etc/systemd/system/gpsd.service -rw-r--r-- 1 root root 362 Jun 6 18:37 /etc/systemd/system/gpsd.socket
I'm unsure about the times here, but I think that 18:37 may be the time I ran the commands below, and 18:52 may be when I rebooted the RPi just to ensure that the service started at boot time. Once you've copied the file, you may need to edit the line in /etc/systemd/system/gpsd.service to point to your choice of options and device. I changed:
[Service] Type=forking EnvironmentFile=-/etc/default/gpsd EnvironmentFile=-/etc/sysconfig/gpsd ExecStart=/usr/local/sbin/gpsd $GPSD_OPTIONS $OPTIONS $DEVICES
[Service] Type=forking ExecStart=/usr/local/sbin/gpsd /dev/ttyAMA0 -n -F /var/run/gpsd.sock
You then need to run commands to enable and run the gpsd service, and to check the service status:
sudo systemctl enable gpsd sudo systemctl start gpsd sudo systemctl status gpsd
* gpsd.service - GPS (Global Positioning System) Daemon Loaded: loaded (/etc/systemd/system/gpsd.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2020-06-06 18:54:08 BST; 15h ago Process: 358 ExecStart=/usr/local/sbin/gpsd /dev/ttyAMA0 -n -F /var/run/gpsd.sock (code=exited, status=0/SUCCESS) Main PID: 383 (gpsd) Tasks: 2 (limit: 4249) CGroup: /system.slice/gpsd.service `-383 /usr/local/sbin/gpsd /dev/ttyAMA0 -n -F /var/run/gpsd.sock Jun 06 18:54:08 RasPi-23 systemd: Starting GPS (Global Positioning System) Daemon... Jun 06 18:54:08 RasPi-23 systemd: Started GPS (Global Positioning System) Daemon.
You can also use the usual "sudo service gpsd stop" and "sudo service gpsd start" commands to control the service.
To get the gpsd service to start automatically: systemctl enable gpsd
Here are some sample files. When using a different version (3.17) I found that the executable daemon was in /usr/local/sbin/ rather than /usr/local/sbin/ so I simply copied the file (with sudo, of course). Note that you would also need sudo to edit or create the examples below.
If you don't use systemd, Gary E. Miller suggests an option to auto-start gpsd, using SU mode:
# echo "gpsd /dev/ttyAMA0 -s 115200 -n /dev/pps0" >> /etc/local.d/local.start
In the light of later experience, I no longer recommend this backports route. Instead, go for and installation of GPSD from scratch as detailed earlier.
The Buster OS includes gpsd 3.17, and back ports are available of 3.20, so the steps required are to tell APT that an update is available in the backports resource, and install that version. These steps are detailed in http://marksrpicluster.blogspot.com/2019/12/add-buster-backports-to-raspberry-pi.html
A couple of keys are required:
Now simply update the software, but tell the install to use the backports:
You can use "cgps -s" to check what satellite constellations are in use - this shot from a unit indoors upstairs nearer to the centre of the room:
You should then be able to tell the gps hardware to enable Galileo with the ubxtool (included in gpsd), using -d for disable or -e for enable and see the difference almost immediately in the cgps display.
Another screen-shot, this time from a downstairs unit with the antenna on the floor right in the corner of the room. This is the version I built from the source and it shows greater precision in the QTH locator grid square, and although a similar number of satellites is visible there are fewer used. I don't know why, but perhaps lower SNR reduces the number used? This might also account for the greater errors in lat/lon etc. I don't know what the (18) after the time means!
In view of my later experience, I no longer recommend this "remove and add" route. Instead, go for and installation of GPSD from scratch as detailed earlier.
Unfortunately the same approach cannot be used for the Raspberry Pi model 1 B. Why would you want to use such an old RasPi? Well, if it works and has all the hardware connections in place - why not! This particular Raspberry Pi has environmental sensors in place (well, pressure temperature and humidity, (environmental is the more modern term!) so "if it works, leave it".
Building from source
When I tried the backports approach it became clear that there were incompatibilities, possibly due to the backport not being tested (or even designed) for the ARMv6 instruction set. Gary E Miller suggested compiling from the master source instead. This turned into a very long saga, so let's just post what actually worked, what snags and work-rounds I used, and a few new-to-me Linux commands I needed.
I used the information here: https://gpsd.gitlab.io/gpsd/installation.html
For Buster, it was necessary to install some required software, and I installed the minimum as I don't need X capability nor the documentation on that particular RasPi. What is critical is to remove any existing gpsd:
Having done that I did still find some lurking gps files in /local/bin (or elsewhere) so I zapped them as well.
Doubtless there would be a cleaner way to do this but after many days of struggling it seems to be not unwise. The next step would have been a complete re-install anyway! Having done that, install the minimum required tools:
Then find a directory to place the downloaded source files - I chose /Home/pi/gpsd, so I ran the command:
Now I deviated from the documented procedure here as it implied running two steps as sudo. When I did this, one of the steps gave a privilege error. So instead I ran the first step as a normal user (compiling the programs) and the install step with priviilege:
After that a test program (in /home/pi/) would not compile, as the required shared object wasn't available. The install procedure hadn't copied it to the required system location. Moving my program into the pi/gpsd directory fixed that one I discovered the -L (upper case) link option in gcc. So something like:
I was disappointed that the "install" hadn't already done this. On trying to run the program, it couldn't find the libgps.so which it needed, so I had to copy the .so file from my gpsd directory into /usr/local/lib and create some llinks:
Likely an "apt-get install" would have made a better job!
At this point, my program worked, so I stopped [for the time being]. Instead, I would recommend the route below.
Some Linux commands that likely you already know!
Thanks to ......
and others I've forgotten!