Real-time solutions with RTKLIB and NTRIP using a cell phone as data link

As I mentioned in an earlier post, I’ve recently acquired access to some low cost dual frequency receivers, specifically a Tersus Precis BX306 and a pair of Swift Piksi Multis.  I have been playing with them over the past few weeks and plan to share my experiences with them over a series of posts.

Both receivers provide internal RTK solutions as well as raw measurements that can be processed with RTKLIB.  I’m interested in how the RTKLIB solutions compare to the internal solutions as well as how both of these compare to solutions derived from single frequency data collected simultaneously with the dual frequency data.

The first issue I ran into with this experiment, however, is that both receivers will only provide an RTK solution for real-time data, neither have the capability to post-process previously collected data.  This meant that I needed a way to provide a real-time stream of dual frequency base station data to the receivers.  I wanted to be able to  do this while driving a car around the local area so I needed more range than a low cost set of radios would give.

Fortunately, I have fairly good cell phone coverage in this area so I was able to rely on my cell phone for the data link.  In this post I will explain how I did that, both for an external CORS reference station and for my own base station.  In both cases I used  NTRIP server/caster/clients to do this.  NTRIP is a protocol for streaming of DGPS or RTK correction data via the internet using TCP/IP.  The NTRIP server sends out the data to an NTRIP caster and the NTRIP client receives it. For more details, there is a good description here.

Using this setup I was able to run real-time solutions with RTKLIB as well as with the intenal RTK engines in the Swift and Tersus receivers.  Here’s a diagram from the RTKLIB manual showing the setup I used for running a real-time RTKLIB solution using RTKNAVI.  When I ran a Swift or Tersus solution, the configuration was similar, but the NTRIP caster streamed the base station data to STRSVR instead of RTKNAVI, and STRSVR then streamed it to the receiver where it was combined with the raw receiver observations to create an internal RTK solution.  Also missing in this diagram is the cell phone which should be in between the internet and the rover PC.


The amount of free base station reference data that is available online on a real-time basis is a fair bit more limited that what is available after the fact for post-processing.  Fortunately I was able to find a CORS reference station about 17 km away that is available real-time through the UNAVCO NTRIP caster.  The service is free if the data is used for educational purposes and appropriately attributed.   Most of their stations are on the west coast of the U.S. but they do have some scattered across the rest of the country as you can see in this map from their site.  There are other networks available in other parts of the world that can be found by searching online.


To access the UNAVCO data I had to request access through email but the process was very simple and within a couple hours of my request I was all setup with an account and password.

Once I had my account set up, I used RTKLIB on my laptop computer to collect the data from the internet and stream it to the rover receiver over a serial port.  If I were doing this experiment within range of a wireless router then I could leave the computer connected to the wireless.  In this case though, I wanted to roam outside the range of my home wireless.  To do this, I enabled a hot spot on my cell phone and logged into that with my computer.

I was able to access the raw observation data stream from the UNAVCO NTRIP caster directly using the NTRIP client option in RTKLIB.  If I had wanted to generate a real-time RTKLIB solution, I would have configured the input streams of RTKNAVI but in this case I want to stream the raw data directly to the receiver so it can use the observation data for it’s internal solution.  I did this using the STRSVR app in RTKLIB.  I specifed the “NTRIP Client” option as input type and then entered the information from my UNAVCO account into the “Ntrip Client Options” as shown below.


In this case I wanted the data from station P041 in RTCM3 format so I had to specify the Mountpoint as “P041_RTCM3”.  For other networks, the mountpoint details may be a little different.  Most NTRIP casters use Port 2101, and that was the case for this one.  For the STRSVR output type, I specified “Serial” and then configured the serial port options for whichever rover receiver I was using.  Before doing the configuration, I had connected the receiver to the laptop using a USB cable.

I then had to configure the receiver to tell it to get its base station data from the COM port and specify that it is in RTCM3 format.  The details for doing this on the two receivers are a little different but fairly straightforward in both cases.  You may also need to specify the exact base station location manually or the receiver may be able to get it from the data stream depending on the receiver and NTRIP stream details.

And that’s it.  With this configuration, either receiver was able to fairly quickly lock to a fixed RTK solution and continue to receive base data as long as I stayed in range of cell reception.  Any lag in the base station observations appeared to be less than a second.

That worked great for using an existing external reference as base station.  However, I also wanted to run another real-time experiment where I used one Swift receiver as base and the other as rover.   To do this, I needed to set up an NTRIP server to stream the data to  a caster on the internet as well as an NTRIP client to receive it.

I started by connecting the second Swift receiver to an old laptop with a USB cable and then downloading RTKLIB, the Swift console app,  and the right USB drivers.  The base station antenna is on top of my roof and the laptop is in the house so I was able to connect the laptop to the internet using my home wireless.

For the NTRIP caster, I found it convenient to use RTK2GO which is a community caster available for anyone to use at no cost.  To send the data to the caster, I used the “NTRIP Server” as the STRSVR output type and configured it as shown below.


Again, the port is 2101.  You can choose any name for the mountpoint.  If that name is already in use, then rtk2go will assign a suffix to it, so it is best to choose a name that is unlikely to already be in use.  The password at the current time is BETATEST but that may change from time to time so it’s worth verifying it is still correct.

For the STRSVR input, I selected “Serial” and specified the correct COM port for the base station receiver.  In this case the raw observations are in Swift binary format which RTKLIB does not support so it sends them unaltered.  If they were in a format that RTKLIB did support, then they could be converted to RTCM3 to reduce bandwidth and make them more easily usable by someone else not using a Swift receiver as rover.  You can specify the conversion to RTCM3 using the “Conv” menu on the STRSVR output.

Start STRSVR and your base station observations are now accessible to anyone in the world through!

On the rover side, the NTRIP client is set up as I previously described using STRSVR except you want to use the same caster/mountpint/password as you just did on the base station.  In this case the user-id is left blank.  Again, set the STRSVR output to “Serial” to send it to the receiver.   Then set up the receiver to get it’s base station data from the serial port and, in this case, specify that it is in the Swift Binary Protocol (sbp).  Start the receiver and it should fairly quickly get a fix.  If you are seeing baseline data but not a solution, then most likely you have not specified the base station location to the rover.

I was now able to drive around almost anywhere and get continuous real-time RTK solutions using either my own base station or the CORS reference station as base.  In the next post I will discuss some of the data I collected and analyzed.





Newest U-blox M8N receivers not usable with RTKLIB

It looks like it is no longer possible to access the raw GPS measurements on the newest version of the u-blox M8N receiver.  Access to these raw measurements on the M8N has always been through debug messages not officially supported by u-blox.  Last year, when they migrated from the 2.01 version of firmware to the 3.01, version they scrambled the output of these messages so they were no longer readable by RTKLIB.

Until recently though, the units they were shipping still had an older 2.01 version of ROM.  With these units it is possible to downgrade the firmware to 2.01 using the instructions on their website.  With the older firmware loaded, the receivers revert to their previous behavior and the debug messages are no longer scrambled.

Apparently their newest units are shipping with a 3.01 version of ROM and this ROM is not compatible with the older 2.01 version of firmware.  If you attempt to load the older firmware it will appear to succeed but will still be running the newer code.

You can see what version of ROM and firmware your receiver is running using the UBX-MON-VER message from the u-center console.  The example below shows the message output for one of the newer modules with the 3.01 ROM after attempting to download the older firmware.  I believe the firmware listed under “Extension(s)” is the ROM version and the firmware listed under “Software Version” is the version of firmware loaded to flash.  In this case you can see that the ROM is version 3.01 and that the flash is still running version 3.01 even though it was attempted to load the 2.01 firmware.


In an older version of the M8N module, the ROM code listed under “Extension(s)” would have been 2.01 and the firmware listed under “Software Version” could be either 2.01 or 3.01 depending on how old the module was and what firmware had been downloaded to it.

There are a few more details about the issue on the u-blox forum in this thread.  Thanks to Marco for making me aware of the issue and Clive and Helge for providing a detailed explanation of what is going on.

If you are using the u-blox M8T, and not the M8N, then you will be using the officially supported raw measurement messages and would normally not care about access to the debug messages.  The only exception I know of is that the resolution of the SNR measurements are 0.2 dB in the debug messages and 1.0 in the official messages.  I have not confirmed that the debug messages on the 3.01 M8T firmware are scrambled but it is likely that they are.

[Note 6/25/17:  A couple of readers have pointed out that this is not the whole story.  It would have been more correct to say that the newest M8N modules are not usable with the publicly available versions of u-blox firmware and RTKLIB.  It turns out that u-blox did not use a particularly sophisticated method to scramble the debug messages and there are now several modified versions of u-blox firmware and RTKLIB floating around that have been hacked to unscramble the messages.  I don’t want to get into the question of ethics or legality of using these codes but just say that I personally am less comfortable using the debug messages in the modules where u-blox has made an obvious attempt to prevent this and have avoided any use of them at least for the time being.]

Update to RTKLIB config file recommendations

I’ve just updated my “RTKLIB: Customizing the input configuration file” post from a few months ago with information on all of the new config parameters I have added to the demo5 code up through B26B.  I’ve also added more notes to some of the existing features based on my more recent experiences.

Receiver warm-up glitches

I’ve described before the occasional glitches that both the M8N and M8T seem to be susceptible too in their first few minutes of operation, but my previous description was buried in one of my more technical posts and maybe not seen by people more interested in just the practical side of using RTKLIB, so I thought it was worth bringing them up again.

Here is an example of one of these glitches which was in a data set recently sent to me by a reader, and one that was giving him trouble finding a solution.  The data is very clean, except for a nearly simultaneous cycle-slip (shown by red ticks) on every satellite.


Here is a zoomed in image of the same glitch.


I see these glitches on both the M8N and the M8T receivers.  Every occurrence I have seen, the glitch occurred within a few minutes of turning on the receiver, and was present on every satellite.  In this example it occurred seven minutes after starting up, usually I see it within in the first five minutes.

These glitches are very disruptive to the RTKLIB solution.  Since the cycle-slips affect every satellite, all the phase-bias kalman filter states are reset and the solution has to start again from the beginning.  In some cases, the phase-biases initial values may have larger than normal errors in which case it is even worse than starting over.

I don’t have any good suggestions on how to deal with these other than to avoid them in the first place.  From my experience I believe they are more likely to occur if the external environment of the receiver has just changed.  For example if it went from hot to cold, or into the sun.  Once the receiver has had time to stabilize, everything is usually OK.

Giving the receiver time to adapt to it’s current environment before collecting data and protecting the receiver from sudden changes should help avoid these glitches.  Using external antennas with cables rather than the small antennas that come with the receivers helps because it allows you to place the receiver in a more protected location than the antenna.  For example, when I collect data from a moving car, I place the antenna on the roof but keep the receiver in the car.

For information on plotting the observations with cycle slip enabled see this post.  For another post where I discuss this problem in more detail, see this post.

Does anyone else have more information on what causes these glitches and maybe other steps that can be taken to avoid or deal with them?



Selecting a GPS receiver (M8N vs M8T)

[Update 6/7/17: The newest version of the M8N is no longer usable with RTKLIB.  See this post for details]

[This is an updated version of my very first post with more info about the differences between the M8N and M8T]

Selecting a GPS receiver

The first thing you will need to begin your journey into low-cost precision GPS is a receiver that provides access to the raw GPS position signals;  pseudorange and carrier phase.  There are only a few low cost GPS chips that provide these signals.  I chose the u-blox receivers because they seem to be the most available and lowest cost option out there.  Also I was able to find examples of other people successfully using them with RTKLIB, including Tomoji Takasu, the author of RTKLIB (see here).

The NEO-M8 series is the latest generation from Ublox.  There are three basic versions of the chip, the NEO-M8N,  the NEO-M8T, and the NEO-M8P.  The NEO-M8P uses u-blox’s own integerated RTK (real-time kinematics) solution and is significantly more expensive than the other two.  I have not worked with this version and don’t know anything about it.  Assuming you plan to use the RTKLIB open-source software to process the raw GPS signals, then you will want to choose between the M8T and the M8N.


The NEO-M8T is more capable and more expensive than the NEO-M8N.  Unlike the M8N, it is specifically intended to be used for precision positioning and officially supports output of the raw signals.  The current firmware supports the GPS and GLONASS satellite systems and newer firmware should be available soon to also support the Galileo system.

The best source for a M8T based receiver that I am aware of is from CSG Shop for $75.  It has a USB interface which means it can easily be connected directly to a computer without any kind of adapter.  It does not come with an antenna but CSG also sells a u-blox antenna for an additional $20.  I have had good results with this antenna and would recommend it.  Assuming you buy two units, one for a base and one for a rover, this setup will cost just over $200 with shipping.  If you are looking for maximum performance and easy setup, and the $200 is within your budget, I would recommend this choice over the M8N.  Here’s a photo of the receiver and antenna from CSG.

UBLOX NEO-M8N GPS GNSS receiver board with SMA for UAV, Robotsantenna

Another M8T-based option, if you are looking for a more integrated solution and willing to spend a little more is the  Emlid Reach.  This is a pair of M8T receivers combined with Intel Edison SBCs with wireless and bluetooth as well as higher quality Tallysman antennas for $570 for the pair.  It uses RTKLIB for the GPS solutions but also includes an additional layer of code to make setup and use easier for the average user.


If you’d prefer a less expensive choice than the M8T and are willing to accept a few compromises then you should consider the M8N.  The NEO-M8N chip does not officially support output of the raw GPS signals but can be configured to do so with undocumented and unsupported commands over the serial port.  These commands are no longer available in the latest firmware (3.01).  However most units shipping today still have the older 2.01 firmware and so still work.  Also, the firmware can be downgraded from 3.01 to 2.01 if you did end up with a receiver with the newer firmware.  [Update 6/7/17: This is no longer true if the M8N comes with ROM version 3.01] The older firmware does not support Galileo.  Going forward, as that system becomes more capable,  this will become a more significant disadvantage of the M8N receiver.

Performance-wise, the M8N and M8T are based on the same core and for the most part are very similar.  There is one noticeable difference however in the way the M8N processes the GLONASS measurements.  Without getting into too many of the details, the issue is that normally when using two identical receivers, the GLONASS satellites can be used to solve the integer ambiguities, but with the M8N this is generally not true because of some additional error terms.  I have added a partial fix to my public branch of RTKLIB to calibrate out these errors after first fix.  If you are using the standard 2.4.3 version of RTKLIB, though, you will not have this capability, and either way you will not have this for the initial acquisition which means it will take a little longer with the M8N to get a good fix.

Most of the inexpensive M8N receivers are intended for use in drones and use a UART interface rather a USB interface.  This means you will need an FTDI type adapter to translate UART to USB and most likely will need to solder a few wires to get this hooked up.  You will find many choices available online for $15 to $40 per receiver including shipping.  These usually include an inexpensive, lower-performance antenna.  You will have to add $5-$15 for the FTDI adapter.  Still, you should be able to put together a pair of receivers fairly easily for under $75, less than half the cost of using the M8Ts.  If you are willing to wait for parts from China, you could do it for less than $50 for the pair.  Although not quite as capable as the M8Ts, if you are careful to collect good quality data and include a little more time for initial acquire, much of the time the results will be indistinguishable between the M8N and the M8T.

I have experience with three different M8N based receivers and have gotten good results with all three.  The first was from CSG Shop and while a perfectly good receiver I would not recommend it because the price is only ten dollars less than the M8T so if you are going to go that route, get the M8T.

The second receiver I have used is intended for drones and is marked as a GY-GPSV3-NEOM8N.  It is available from several suppliers, I bought it on Ebay for $25.78 including antenna and shipping.

The third type of receiver I have used is very similar but includes an on-board magnetometer.  It is labeled as GY-GPSV5-NEOM8N and sells for about $5 more than the GY-GPSV3-NEOM8N and is also available from multiple sources.  The magnetometer can be useful for collecting additional information about heading and orientation but I have not used it much yet.

Here’s a couple of other M8N receivers worth considering.  I have ordered both of them but have not had time to evaluate them yet.  For the very lowest cost and with an integrated receiver/antenna package, the unit on the left from ebay, shipped from China is  $16.65 including shipping.   The Reyax RY835AI unit on the right includes an accelerometer, gyroscope, and magnetometer with onboard antenna, all for $18.99 from Amazon Prime  (thanks to Ken McGuire for this suggestion).

[Update 12/6/16:  I have not tested the unit on the left yet but have verified the M8N module is counterfeit based on inconsistencies between the labels on this module and my other modules.  Preliminary testing of the Reyax unit was disappointing for me with low satellite count and low SNRs.  I suspect it may be because the antenna is passive unlike my other receivers that all have active antennas, but Ken has shown data with his receiver that looks much better so I’m not sure why the differences.  He has extended the ground plane on his unit but that doesn’t usually have a large enough effect to explain the differences I see.]


neom8n_dg 81yneho8uxl-_sl1500_


In summary, I would recommend the M8T receiver with a u-blox antenna for someone that has a specific application in mind and is looking for maximum performance and ease of setup.  However, the M8N with included antennas is how I got started and I still think it is a good choice for anyone that just wants to explore the capability of precision GPS without spending a lot of money.  It could also be a good choice for someone planning on building multiple units for a more price-sensitive application and is willing to work within it’s constraints.   Combining the M8N with a u-blox or other external antenna is another possibility that will put you somewhere in the middle for both capability and cost.

Another Raspberry Pi RTKLIB project

After describing my simple Pi based data logger in my last post, I stumbled across this Raspberry Pi based GPS project on  It uses an M8T receiver and includes a touchscreen GUI to manage RTKLIB.  It has downloadable files for 3D printing the case as well as an image file with all the code for the SD card (something I should probably provide with mine).

I haven’t looked at in great detail but it seems very intriguing and could be a good alternative to what I described in my last post if you are looking for something with greater capability.

Here’s a photo of the completed project.


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/” 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
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://” where 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.




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.