Pi Zero Based GPS data logger

loggers2

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.

pizero

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.

diskimager

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.

zero_pinout

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.

loggers2

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.

winscp

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
make
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:

str2str

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.

#!/bin/bash

path=”/home/pi/gps/”

# find unused file name
i=0
fname=$path”rover”$i”.ubx”
while [ -f $fname ]; do
     let “i=i+1”
     fname=$path”rover”$i”.ubx”
done

fname=$path”rover”$i”.ubx”

# 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 ]
then
     echo Exit on error
     exit
fi

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

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.

[Unit]
Description=Startup Script Service
After=multi-user.target

[Service]
Type=idle
ExecStart=/home/pi/str2str_start.sh

[Install]
WantedBy=multi-user.target

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

[Note 12/8/16: For a more complete tutorial on connecting your Zero to the internet, see this tutorial (thanks to Jernej Tekavec for pointing me to this link) ]

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.

logger3logger1

 

 

Here is a link to a sample data set I collected with this data logger.  It was on a small sailboat while sailing on a lake and got consistent fixes for the duration of the data.

Advertisements

26 thoughts on “Pi Zero Based GPS data logger”

  1. Hi friends, I plan to develop a project using a raspberry pi 2 and the 3DR radios system. I modified the script used with Pi zero by adding a button and two leds to indicate that the data collection is running. I would like suggestions.
    Thank you

    #!/bin/bash
    path=”/home/pi/gps_rtk/”
    import RPi.GPIO as GPIO         
    GPIO.setmode(GPIO.BOARD)   
    GPIO.setwarnings(False)                  
    btn=17
    LED1=16
    LED2=15
    GPIO.setup(btn, GPIO.IN,pull_up_down=GPIO.PUD_UP)
    GPIO.setup(LED1,GPIO.OUT)
    GPIO.setup(LED2,GPIO.OUT)
    BS=False

    while(1)
    do
    if GPIO.input(btn)==0
    then
    print “=== START ===”
    if BS==False
    then
    #Cria e nomeia os arquivos em função da data
    time=$(date “+%H%M%S-%d%m_%y”)
    fname_R=$path”rover_”$time”.ubx”
    fname_B=$path”base
    ”$_time”.ubx”
    #ROVER — 5Hz — Radio Link
    str2str -in serial://ttyUSB0:230400:8:n:1:#ubx -out /home/pi/gps_rtk/ -out $fname_R -c home/pi/gps/m8n_rover_5hz.cmd &
    #BASE — 1Hz — Radio Link
    str2str -in serial://ttyUSB1:115200:8:n:1:#ubx -out /home/pi/gps_rtk/ -out $fname_B -c home/pi/gps/m8n_base_1hz.cmd &
    GPIO.output(LED1,True)
    GPIO.output(LED2,False)
    BS=True
    sleep(1)
    else
    GPIO.output(LED2,True)
    GPIO.output(LED1,False)
    BS=False
    str2str Ctrl-C
    print “=== STOP ===”
    sleep(1)
    fi
    fi

    done

    Like

  2. Hi friend,
    Is it possible to use this code to adapt the radio link system? (Replacing the computer portable with the raspberry pi)
    How would that part of the code look?

    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 &

    Like

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

      Like

      1. Hi Neilon, I believe the pi zero has only one UART so you would have to figure out how to communicate to the radio with something other than the UART or choose a SBC like the Beaglebone that has more than one UART. Also the options format for rtkrcv are different from str2str. You will need a configuration file for the solution parameters which can include the input and output stream configurations as well.

        Like

        1. Understand. In my project I’m going to use a raspberry pi 2 (4 usb port) and 3DR radios (1 USB – Base and 1 UART – Rover).

          So I should create new configuration files for rtkrcv. I looked in the manual and did not find it. Where can I find it?

          Thank you

          Like

          1. Hi Neilon. Section B.4 in the RTKLIB manual describe the config file format and options, it is the same for RTKNAVI, RTKRCV, RTKPOST, or RNX2RTKP. Appendix A.1 describes the input options for RTKRCV including how to specify the config file in the command line.

            Like

    1. Hi Krill. How do you send commands to the u-blox receiver to configure it to output RAW commands with this logger? With the Pi logger, I run the STR2STR app from RTKLIB to do this but it is not obvious you can do the same with this logger, at least not right out of the package without installing anything.

      Like

    1. Hi Alxg. The systemctl commands below will stop and restart the service/script and give you its current status. This isn’t exactly the same as pausing the script since the receiver will be re-configured and the data will go to a new file when you restart it, but hopefully they will do what you are looking for. The str2str_start.sh script starts STR2STR in a background task then loops around blinking the LED, so pausing the script itself would only pause the LED blinking, not the data stream.

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

      Like

      1. Thx rtklibexplorer, exactly what I was looking for! 🙂
        Btw another tip if someone want timestamped files, these two lines add timestamp to filename and since they change every second there is no need for checking for exisiting files:
        _time=$(date “+%H%M%S-%d_%m_%y”)
        fname=$path”rover_”$_time”.ubx”

        Like

  3. Hello,
    first, thank you for this blog, I am following you
    almost from the start and what you are doing is fantastic.
    I have some troubles getting the logger working.
    I have put jessie.lite on the sd card and then followed OTG setup.
    I can successfully connect with Pi Zero via putty.exe (I get pi@raspberrypi:~ $)
    Then, I don’t know how to connect to Pi using WinSCP (which file protocol to choose,
    and which parameters?)
    I’ve chosen SFTP and it gave errors that I don’t have permission
    to change files (next step is to change cmdline.txt).
    I then chose sudo -su shell under advanced settings and that allowed me to change files.
    I also cannot run make just using ‘cd rtklib/app/str2str/gcc’ and then ‘make’
    It says that I don’t have permission. If I first type ‘sudo su’ and then navigate to
    ‘cd rtklib/app/str2str/gcc’ and then ‘make’ it works, but gives me warning :
    ‘Warning: File ‘makefile’ has modification time (big number) in the future’.
    I solved that with ‘find . -exec touch {} \;’ command and the warning is gone.
    It stops when I try to run ‘str2str -in serial://ttyAMA0:230400#ubx -out rover.ubx -c /home/pi/gps/m8n_gpsglo_5hz.cmd’ as you did. It does not run, I have to type sudo su again and
    then navigate to directory of str2str executable (I’m using 115200 and different name for cmd – provided
    with demo5 win executables – m8n_base_1hz.cmd).
    It then works, but when I continue to make startup script, it does nothing.
    Would be really grateful for any help.
    Best regards!

    Like

    1. Hi Bene. Yes you’re right , WinSCP doesn’t let you modify files outside your user space, I’ll fix that oversight in my tutorial. The warning when you do the make is happening because your clock is wrong but I think you can ignore it. Before running str2str, I mentioned copying it to your local executable folder. Maybe you missed that step?, or maybe your config is a little different and you need to copy to a different folder? In the str2str command the 230400 is the baud rate, did you change that to 115200 when you ran that line? For debug, you can run str2str in four incrementally more complete steps. First run str2str directly as you did, then run the str2str_start script, then manually start the systemctl task, then enable the systemctl task and let the boot sequence start it. Which of these first fails in your case?

      Like

      1. Thank you for your answer.
        I did copy str2str to usr folder, and
        it works if I run it manually.
        The problem is, that it runs only if
        I type sudo su after log in in putty and then navigate to folder where str2str is copied.
        In your picture it is clear that it should work as pi@raspberrypi:~ $ (shown when you log in to putty). If i type str2str -in serial://ttyAMA0… command right after pi@raspberrypi:~ $ as in your picture, it says that I don’t have permission.
        I think that the root of the problem is that I used sudo su shell in advenced settings in WinSCP (only that allowed me to copy rtklib files from pc to RPi zero). I copied all files from your demo5 github branch, is that ok? What settings did you use in WinSCP for logging in?(which protocol? Did you chhange anything under advenced settings?)
        I really want to make this work, but I’m really not familliar with linux. I hope I’m not annoying, feel free to remove my posts, as they are probably trivial for most readers.
        Best regards

        Like

      2. You wouldn’t believe what caused the problems.
        First, everything that is done inside home directory (copying rtklib files…) should not be done in sudo su shell (advenced settings in WinSCP).
        The second problem were the ” signs in .sh script. I had to delete all your ” signs and type new ones in the same spot. The consequence was, that out file was not created and the error check in the script prevented it from running.

        Like

        1. Hi Bene. That’s strange … I don’t know why the signs would make a difference but I’m glad you got it sorted out. I tried to follow the tutorial myself with a new SD card and ran into the same permission issues you did so I have updated the instructions to avoid any use of WinSCP outside of the user space. I also added a few images and a couple of intermediate checks so if anyone does run into a problem it may be more obvious where the problem is.

          Like

  4. Thank you for an excellent tutorial! A few tips from my experience:
    if you struggle with access denied in WinScp then just make the files via “nano” or “sudo nano” in the putty terminal, but remember copy paste doesn’t like ” and ‘
    I had to set the permissions on str2str_start.sh via WinScp
    My ublox LEA-M8T draws too much power so I could only access ssh with an extra USB for power connected

    Like

    1. Hi Alxg. Thanks for the tips. I have had to connect an extra USB for power when using the Beaglebone, even with the Neo-M8N, but so far I’ve been fine with the Pi Zero but maybe I’ve just been lucky.

      Like

  5. Hmm, anyone thought about creating a logger with an Arduino + SD card? Should be possible to send the init messages over serial? Or maybe just config everything in ublox and only log with two status leds or something which reads a ubx-nav message for nr of satelittes etc.

    Like

    1. Hi Felipe (and JB). I suspect the biggest issue with using a dedicated datalogger would be in initializing the GPS receiver at the beginning of the data collection. Each command in the RTKLIB startup command file needs to be translated correctly and a checksum calculated before sending to the GPS receiver. I believe writing custom code to do this would make this a more complicated solution than using the Zero. Maybe you are able compile the RTKLIB STR2STR app on these data loggers like I did, and setup up an autorun script but then the task would become very similar to using the Pi Zero. I also would be concerned you would lose some of the flexibility that the Pi Zero provides. Through socat you can get direct bi-directional connection with the receiver, STR2STR has the option to save the results in much smaller RTCM format if you are collecting large amounts of data, all data is output to the USB port while it is being collected so it gives the flexibility of plugging directly into the PC without reconfiguring. Hardware-wise, these data loggers use the same UART interface as the Zero, so there would be no difference there. And cost-wise, the dataloggers are more expensive than the Zero.

      Like

    1. Hi Stephan. No I didn’t, but that would be a nice addition since it would enable you to put the correct date stamp in the data file names. In my script I just number the data files sequentially.

      One issue you might run into is that although the tutorial I used to help me write the auto-start feature was intended to run a Python script I found it didn’t work with Python and ended up using a shell script instead. I originally used an older image of Raspbian, though, when I first wrote this script, and it’s possible that it would just work with the newer version I used in this example.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s