Pi Zero Based GPS data logger


The easiest way to collect GPS data from the u-blox receivers is simply to plug the receiver into a laptop PC through an FTDI serial to USB converter and run STRSVR or RTKNAVI as I've previously described. Of course, if you want to collect base and rover data, that means lugging around two laptops, which if added to the cost of the system, start to make it not look so low cost and also not so convenient since the laptops are so much larger than the receivers.

An inexpensive alternative to the laptop is to configure one of the many linux-based single board computers that are available to collect the data. They can also be used to process the data but in this post I will focus on collecting the data for post-processing later. I have used both Beaglebone and Pi boards to do this and find they each have their advantages.

In this post I will describe setting up a Pi Zero for this purpose. The advantages of the Pi Zero over the Beaglebone are it's lower price and smaller size. One of the disadvantages is that it does require soldering since there are no host USB ports or headers on the board. The other is that it only has a single UART port, so does not have the flexibility of the Beaglebone. This is important for example if you want to add a radio link for real-time data collection. Like the Beaglebone, it does have an I2C port which can be used to collect magnetometer (digital compass) data if your receiver includes that feature.

The Pi Zero is supposedly a $5 computer but at least at the moment you can only order one at at time and the shipping costs are significant relative to the board price. I paid $13.50 including shipping for the last one I bought from Adafruit. Still, this is less than half the price of the least expensive version of the Beaglebone. Here's a stock photo of one in case you haven't already seen it.


In addition to the Pi Zero, you will need a microSD card to use as non-volatile storage for the operating system, programs, and data. I used an 8 GB card available for $5 or less from many sources. I believe any size 4 GB or larger will work. The last things you will need are a USB portable charger (battery pack) to power it and a USB cable. I have bought 10000 mAh units for $10 on Amazon and 2600 mAh units for $5. Both include USB cables but they are power only, you will need a power and data cable for communication between PC and Zero. The 2600 mAh units are sufficiently large to run the Zero and GPS receiver for many hours.

The total cost for a basic logger with an M8N receiver and basic patch antenna is just under $50, using an M8T receiver and/or higher quality antenna will increase the price.

I will describe the process I went through to connect the receiver to the Zero and to configure the Zero to automatically start collecting data when power is applied. I did this using a Windows PC but I imagine it would not be very different if you are using another machine.  I am no expert in linux so I relied heavily on cutting and pasting various pieces of code from different tutorials I found online.

To get started I downloaded three open-source applications to my PC: The first is Putty to communicate with the Zero through SSH over a USB cable and avoid having to hook up a keyboard or HDMI monitor to the Zero. The second is WinSCP to transfer files between the PC and the Zero. WinSCP also includes a convenient file editor that makes it easy to edit files on the Zero directly with a standard GUI interface. The third is WinDiskImager to transfer memory images between the PC and the SD card.

The next step is to copy an operating system onto the microSD card. I used the “2016-09-23-raspbian-jessie-lite.img” version available here, which is currently the most recent stable version of Raspbian Jessie Lite. Raspbian Jessie Lite is a minimal image of linux based on Debian Jessie.

To get the image onto your SD card, download the image to your computer, decompress it, and copy it to the SD card using the "Write" button on WinDiskImager.


Once you have done that, the next step is to configure the operating system on the microSD card for SSH access over USB. This is done with the card plugged into the laptop using a microSD to SD adapter. There is an excellent tutorial here on how to do this by modifying the config.txt and cmdline.txt files in the boot folder so I won't explain the details here. In the comments section, it also describes how to link the Zero to your network to get internet access. Although not required for this exercise, it is nice to have. Also note that it does require Bonjour, iTunes or Quicktime to be installed on your PC to translate the Zero's SSH address. If you don't already have one of these installed, you will need to do that as well.

While you are editing the config.txt and cmdline.txt files in the previous step, there are two more changes you need to make.  First,  in the config.txt file, add the following line to the end of the file: “init_uart_clock=6000000”. This increases the speed of the UART clock. Without this change you will not be able to run the UART faster than 115200 bps.

Next, in the cmdline.txt file you will find a reference to either serial0 or ttyAMA0. If you are using the same image as I did it will be in the form of: “console=serial0,115200”. Delete this command from the line, then save and close the file. This will free up the UART from it default use as a debug terminal.

Now that the operating system is configured, plug the microSD card into the Zero and connect the Zero to your PC using a USB cable that you know has the data lines hooked up (many USB cables only have power). Verify that you can communicate with the Zero through SSH using Putty (Host Name=raspberrypi.local). There are two micro-USB connectors on the Zero, one is power only, so be sure you use the one labeled USB. You can login to the Zero using the default username=pi, and password=raspberry. Once you are sure this is working, disconnect the Zero for the next step.

Now, we will connect the GPS receiver to the Zero through the UART pins with soldered wires. It is a little more complicated to change the baud rate on the u-blox receiver after it is connected to the Zero, so I would suggest setting the receiver baud rate before doing this step. Be sure to follow up by issuing the CFG-CFG command to save it to flash.

Below is the pin-out of the Zero. TX and RX need to be swapped whenever hooking up a UART so connect TX from the GPS receiver to RXDO (pin 10) on the Zero, and RX from the GPS receiver to TXD0 (pin 8). The solder pads on the edge connector are normally labeled on the GPS receiver. If your receiver has a digital compass it's output will most likely be on an I2C interface using SDA and SCL pins. If that's the case hook those up to pins 3 and 5 on the Zero (these don't get swapped). I won't talk about collecting data from the compass in this post but at least you will have them hooked up for later.


Here are two data loggers I have built (without antenna or power pack). The receiver on the left is a GY-GPSV3-NEO which does not have a digital compass so there are only four wires. I have used double-stick foam tape to connect the two boards. This unit is set up to run with the antenna included with the receiver which has a very short lead. I like to run the lead through a hole in the ground plane so I need to make sure access to the uFL connector is not blocked by the Zero.

The receiver on the right is a GYGPSV5-NEO which does have a digital compass so there are six wires. In this case I connected the two boards using a machine screw with nylon spacer. This one also has a uFL to SMA adapter cable to connect to my more expensive antennas with SMA connectors. The adapter cable is fairly fragile so I have secured it with a simple L bracket to the receiver board. Note that his board has a DF13 connector, I could have chosen to use that instead of soldering directly to the pads on that end.


Now that the hardware is complete, reconnect the Zero to the PC with the USB cable and re-open a SSH window with Putty. Also start WinSCP and login to the Zero, again using Host Name=raspberrypi.local and username/password = pi/raspberry. When WinSCP connects, the left window will list files on your PC and the right window files on the Zero. Be aware that WinSCP only has permission to copy files into your user space, if you want to copy files anywhere else on the Zero, you will need to login in using that users name and password.

Now we need to copy the RTKLIB source code onto the Zero. You can do this with WinSCP. Copy the rtklib folder from your computer to "/home/pi/rtklib". Note that none of the windows executables will run on the Zero so there is no need to copy them. We do need to build code though so you will need to copy all the source files. Also copy the “.cmd” file you use to configure the GPS receiver at startup. Put this in a new folder called gps (/home/pi/gps).  You can create a new folder on the Zero by right-clicking on the right window.


The demo5 version of the RTKLIB code is available here and there are some sample ".cmd" files for the M8N and M8T receivers in the binaries zip file here.

Once you've copied everything over, go to the Putty window, switch to the /home/pi/rtklib/app/str2str/gcc folder and run "make" to build the STR2STR app on the Zero. Copy the STR2STR executable to /usr/local/bin and change its permissions to make it.  You can do all that by executing these commands from the command prompt:

cd rtklib/app/str2str/gcc
sudo cp str2str /usr/local/bin/str2str
sudo chmod +x /usr/local/bin/str2str

You may get a warning from the make process that the build may not be complete because we didn't update the date and time on the Zero, but you can ignore this.

You should now be able to run the STR2STR app to make sure everything you've done so far is working. I use the following command but you may need to adjust it for your baud rate file names/locations etc. Details of the STR2STR command options are in the RTKLIB manual.

str2str -in serial://ttyAMA0:230400#ubx -out rover.ubx -c /home/pi/gps/m8n_gpsglo_5hz.cmd

The output from this command should look something like this:


The output should be in the file rover.ubx.  You can use WinSCP to copy this file to your PC and convert and plot it with RTKCONV. If that works fine, you are almost done.

The last step is to create an auto-run script that will run at power-up and start collecting data. We will use the systemctl command to do this. I used this tutorial as an example on how to do it.

First we'll create the actual script to collect the data. I first tried to do this in python but had an issue with it not working when called during the boot sequence, so switched it to a shell script. Create a new file by maneuvering to your user folder (/home/pi) in WinsSCP then right-click and select New then File. Copy the following text into the file then save as “/home/pi/str2str_start.sh” and exit. You may need to modify the path and str2str command lines in this file to match your file names, locations and baud rate.



# find unused file name
while [ -f $fname ]; do
     let "i=i+1"


# start task to collect rover data at 5 Hz
str2str -in serial://ttyAMA0:230400#ubx -out tcpsvr://:128 -out $fname -c     home/pi/gps/m8n_rover_5hz.cmd &

# check for error by looking for output file
sleep 1
ls $fname
if [ $? -ne 0 ]
     echo Exit on error

# blink LEDs to let user know all is OK and we are collecting data
while [ $X -le 0 ]
     echo 0 > /sys/class/leds/led0/brightness
     sleep 1
     echo 1 > /sys/class/leds/led0/brightness
     sleep 1

Now create another new file in the /home/pi folder named gpslog.service.  Copy the following text into that file then save and exit. This will run our script during the power up sequence.

Description=Startup Script Service



To move the second file into the correct system folder and enable both files, use the following commands:

cd /home/pi
sudo chmod +x str2str_start.sh
sudo mv gpslog.service /lib/systemd/system
sudo systemctl daemon-reload
sudo systemctl enable gpslog.service

To manually test the startup script first without using the autorun task, use the following commands:

sudo systemctl start gpslog.service
sudo systemctl status gpslog.service

The output should look similar to when we ran STR2STR directly.  If not, make sure the baud rate and ".cmd" file name and location in the script are correct.

If the output looks OK, then power-cycle the Zero.  It should come up and automatically start collecting data and flashing the LED on-board the Zero. You can reconnect with Putty and check the status with the previous command;

sudo systemctl status gpslog.service

The raw output files will be saved in the /home/pi/gps folder and will be named roverxx.ubx where “xx” will increment to the next unused number each run. Use WinSCP to copy this over to your laptop for analysis.

And that's it, you should now have a fully functional GPS data logger!

Below is a little more info on using your new data logger.

If you look carefully at the script above you will see in the str2str options, that in addition to directing the output to a file, I also directed it to a tcp server (-out tcpsvr://:128). If the Zero is plugged into the laptop, you can see the receiver output real-time using RTKNAVI or the u-blox u-center evaluation software. Instead of connecting to a serial port, connect to a network connection using the address “tcp://xxx.xxx.xxx.xx:128” where xxx.xxx.xxx.xx is the ip address of your Zero. You can get this number by issuing a “ifconfig” command from the Putty window and then using the inet address of usb0.

Unfortunately this connection does not work in both directions so if you want to change the receiver baud rate using u-center you will need to use "socat" to create a virtual port.

Use the following command to install "socat" on your Zero. You will need to be connected to the internet to do this.

sudo apt-get install socat

Then use the following command to open the virtual port, then connect with u-center as described above. Now the connection will work in both directions and you should be able to change the baud rate with u-center.

sudo socat tcp-listen:128,reuseaddr /dev/ttyAMA0,b38400,raw,echo=0

Here is a complete but unassembled logger on the left with ground plane (aluminum foil glued to cardboard) and waterproof case (Rubbermaid food container). On the right it is assembled but not in the case. I place the receiver/antenna unit face down in the container, put the lid on, then flip it over so the antenna points upwards. If I wanted to make it smaller I could use a smaller battery pack and smaller ground plane, but for my uses this size is fine.



Posted in Projects, Tutorials and tagged , , , .

Leave a Reply

Your email address will not be published. Required fields are marked *