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).
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.
The only issue I found with these devices to use Galileo was that as supplied by U-Blox they come with GPS and GLONASS configured, so you're using just two of the three available satellite constellations. So each time the devices are powered up you need to send a command to enable the Galileo mode should you want the extra satellites. It's easy with gpsd 3.20 as it includes a "ubxtool" command, and I'll mention that later. Yes, you can also send that command with gpsd 3.17, but you have to work out the u-blox command yourself, and code it in hex. "ubxtool -e GALILEO" is somewhat easier and less error-prone!
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 unamplified 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 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.
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!
Still to be resolved, getting gpsd to start automatically.
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 RasPi has environmental sensors in place (well, pressure temperature and humidity, (enviromental 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].
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:
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:
/dev/serial0 is the primary UART - GPIO pins
/dev/ttyS0 is the miniUART
The connection is by symbolic links:
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
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.
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.
Some Linux commands that likely you already know!
Thanks to ......
and others I've forgotten!