Python och GPS-spårning

Detta är en artikel från SparkFun, December 17, 2012


In my quest to design a radio tracking system for my next HAB, I found it very easy to create applications on my computer and interact with embedded hardware over a serial port using the Python programming language. My goal was to have my HAB transmit GPS data (as well as other sensor data) over RF, to a base station, and graphically display position and altitude on a map. My base station is a radio receiver connected to my laptop over a serial to USB connection. However, in this tutorial, instead of using radios, we will use a GPS tethered to your computer over USB, as a proof of concept.

Of course, with an internet connection, I could easily load my waypoints into many different online tools to view my position on a map, but I didn’t want to rely on internet coverage. I wanted the position of the balloon plotted on my own map, so that I could actively track, without the need for internet or paper maps. The program can also be used as a general purpose NMEA parser, that will plot positions on a map of your choice. Just enter your NMEA data into a text file and the program will do the rest.

Showing a trip from SparkFun to Boulder, CO. 

This tutorial will start with a general introduction to Python and Python programming. Once you can run a simple Python script, we move to an example that shows you how to perform a serial loop back test, by creating a stripped down serial terminal program. The loopback test demonstrates how to send and receive serial data through Python, which is the first step to interacting with all kinds of embedded hardware over the serial port. We will finish with a real-world example that takes GPS data over the serial port and plots position overlaid on a scaled map of your choice. If you want to follow along with everything in this tutorial, there are a few pieces of hardware you will need.

For the loopback test, all you need is the FTDI Basic. For the GPS tracking example, you will need a GPS unit, as well as the FTDI. 

What is Python?

If you are already familiar with installing and running Python, feel free to skip ahead. Python is an interpreted programming language, which is slightly different than something like Arduino or programming in C. The program you write isn’t compiled as a whole, into machine code, rather each line of the program is sequentially fed into something called a Python interpreter. Once you get the Python interpreter installed, you can write scripts using any text editor. Your program is run by simply calling your Python script and, line by line, your code is fed into the interpreter. If your code has a mistake, the interpreter will stop at that line and give you an error code, along with the line number of the error.

The holy grail for Python 2.7 reference can be found here:

Installing Python

At the time of this tutorial, Python 2.7 is the most widely used version of Python and has the most compatible libraries (aka modules). Python 3 is available, but I suggest sticking with 2.7, if you want the greatest compatibility. 

After you install Python, you should be able to open a command prompt within any directory and type ’python’. You should see the interpreter fire up.

If you don’t see this, it is time to start some detective work. Copy your error code, enter it into your search engine along with the name ’python’ and your OS name, and then you should see a wealth of solutions to issues similar, if not exact, to yours. Very likely, if the command ’python’ is not found, you will need to edit your PATH variables. More information on this can be found here. FYI, be VERY careful editing PATH variables. If you don’t do it correctly, you can really mess up your computer, so follow the instructions exactly. You have been warned. 

If you don’t want to edit PATH variables, you can always run Python.exe directly out of your Python installation folder.

Running a Python Script 

Once you can invoke the Python interpreter, you can now run a simple test script. Now is a good time to choose a text editor, preferably one that knows you are writing Python code. In Windows, I suggest Programmers Notepad, and in Mac/Linux I use gedit. One of the main rules you need to follow when writing Python code is that code chunks are not enclosed by brackets {}, like they are in C programming. Instead, Python uses tabs to separate code blocks, specifically 4 space tabs. If you don’t use 4 space tabs or don’t use an editor that tabs correctly, you could get errant formatting, the interpreter will throw errors, and you will no doubt have a bad time. 

For example, here is a simple script that will print ’test’ continuously. 

# simple script
def test():
    print "test"
while 1:

Now save this code in a text editor with the extention

The first line is a comment (text that isn’t executed) and can be created by using a # .

The second line is a function definition named test().

The third line is spaced 4 times and is the function body, which just prints ”test” to the command window.

The third line is where the code starts in a while loop, running the test() function.

To run this script, copy and paste the code into a file and save it with the extention .py. Now open a command line in the directory of your script and type:


The window should see the word ’test’ screaming by.

To stop the program, hit Ctrl+c or close the window. 

Installing a Python Module

At some point in your development, you will want to use a library or module that someone else has written. There is a simple process of installing Python modules. The first one we want to install is pyserial.

Download the tar.gz file and un-compress it to an accessible location. Open a command prompt in the location of the pyserial directory and send the command (use sudo if using linux):

python install

You should see a bunch of action in the command window and hopefully no errors. All this process is doing is moving some files into your main Python installation location, so that when you call the module in your script, Python knows where to find it. You can actually delete the module folder and tar.gz file when you are done, since the relevant source code was just copied to a location in your main Python directory. More information on how this works can be found here:

FYI, many Python modules can be found in Windows .exe installation packages that allow you to forgo the above steps for a ’one-click’ installation. A good resource for Windows binary files for 32-bit and 64-bit OS can be found here:

Python Serial Loopback Test

This example requires using an FTDI Basic or any other serial COM port device.

Simply, connect the TX pin to the RX pin with a wire to form a loopback. Anything that gets sent out of the serial port transmit pin gets bounced back to the receive pin. This test proves your serial device works and that you can send and receive data.  

Now, plug your FTDI Basic into your computer and find your COM port number. We can see a list of available ports by typing this:

python -m

If you are using linux:

dmesg | grep tty

Note your COM port number. 

Now download the piece of code below and open it in a text editor (make sure everything is tabbed in 4 space intervals!!):

import serial

#####Global Variables######################################
#be sure to declare the variable as 'global var' in the fxn
ser = 0

#initialize serial connection 
def init_serial():
    COMNUM = 9 #set you COM port # here
    global ser #must be declared in each fxn used
    ser = serial.Serial()
    ser.baudrate = 9600
    ser.port = COMNUM - 1 #starts at 0, so subtract 1
    #ser.port = '/dev/ttyUSB0' #uncomment for linux

    #you must specify a timeout (in seconds) so that the
    # serial port doesn't hang
    ser.timeout = 1 #open the serial port

    # print port open or closed
    if ser.isOpen():
        print 'Open: ' + ser.portstr
#this is a good spot to run your initializations 

#####MAIN LOOP############################################
while 1:
    #prints what is sent in on the serial port
    temp = raw_input('Type what you want to send, hit enter:\n\r')
    ser.write(temp) #write to the serial port
    bytes = ser.readline() #reads in bytes followed by a newline 
    print 'You sent: ' + bytes #print to the console
    break #jump out of loop 
#hit ctr-c to close python window

First thing you need to do before running this code is to change the COM port number to the one that is attached to your FTDI. The COMNUM variable in the first few lines is where you enter your COM port number. If you are running linux, read the comments above for ser.port.

Now, if you want to send data over the serial port, use: 


your_data can be one byte or multiple bytes.

If you want to receive data over the serial port, use:

your_data = ser.readline() 

The readline() function will read in a series of bytes terminated with a new line character (i.e. typing something then hitting enter on your keyboard). This works great with GPS, because each GPS NMEA sentence is terminated with a newline. For more information on how to use pyserial, look here.

You might realize that there are three communication channels being used:

  1. ser.write – writes or transmitts data out of the serial port
  2. – reads or receives data from the serial port
  3. print – prints to the console window

Just be aware that ’print’ does not mean print out to the serial port, it prints to the console window. 

Notice, we don’t define the type of variables (i.e. int i = 0). This is because Python treats all variables like strings, which makes parsing text/data very easy. If you need to make calculations, you will need to type cast your variables as floats. An example of this is in the GPS tracking section below.

Now try to run the script by typing (remember you need to be working out of the directory of the file):


This script will open a port and display the port number, then wait for you to enter a string followed by the enter key. If the loopback was successful, you should see what you sent and the program should end with a Python prompt >>>. 

To close the window after successfully running, hit Ctrl + c.

Congratulations! You have just made yourself a very simple serial terminal program that can transmit and receive data!

Read a GPS and plot position with Python

Now that we know how to run a python script and open a serial port, there are many things you can do to create computer applications that communicate with embedded hardware. In this example, I am going to show you a program that reads GPS data over a serial port, saves the data to a txt file; then the data is read from the txt file, parsed, and plotted on a map. 

There are a few steps that need to be followed in order for this program to work.Install the modules in the order below.

Install modules

Use the same module installation process as above or find an executable package. 

The above process worked for me on my W7 machine, but I had to do some extra steps to get it to work on Ubuntu. Same might be said about Macs. With Ubuntu, you will need to completely clean your system of numpy, then build the source for numpy and matplotlib separately, so that you don’t mess up all of the dependencies. Here is the process I used for Ubuntu.

Once you have all of these modules installed without errors, you can download my project from github and run the program with a pre-loaded map and GPS NMEA data to see how it works:

Or you can proceed and create your own map and GPS NMEA data.

Select a map

Any map image will work, all you need to know are the bottom left and top right coordinates of the image. The map I used was a screen shot from Google Earth. I set placemarks at each corner and noted the latitude and longitude of each corner. Be sure to use decimal degrees coordinates.

Then I cropped the image around the two points using gimp. The more accurate you crop the image the more accurate your tracking will be. Save the image as ’map.png’ and keep it to the side for now.

Hardware Setup

The hardware for this example includes a FTDI Basic and any NMEA capable GPS unit.

EM-406 GPS connected to a FTDI Basic

For the connections, all you need to do is power the GPS with the FTDI basic (3.3V or 5V and GND), then connect the TX pin of the GPS to the RX pin on the FTDI Basic.

It is probably best to allow the GPS to get a lock by leaving it powered for a few minutes before running the program. If the GPS doesn’t have a lock when you run the program, the maps will not be generated and you will see the raw NMEA data streaming in the console window. If you don’t have a GPS connected and you try to run the program, you will get out-of-bound errors from the parsing. You can verify your GPS is working correctly by opening a serial terminal program.  

Run the program

Here is the main GPS tracking program file:

Save the python script into a folder and drop your map.png file along side Here is what your program directory should look like if you have a GPS connected:

The nmea.txt file will automatically be created if you have your GPS connected. If you don’t have a GPS connected and you already have NMEA sentences to be displayed, create a file called ’nmea.txt’ and drop the data into the file.

Now open, we will need to edit some variables, so that your map image will scale correctly. 

Edit these variables specific to the top right and bottom left corners of your map. Don’t forget to use decimal degree units!

#adjust these values based on your location and map, lat and long are in decimal degrees
TRX = -105.1621     #top right longitude
TRY = 40.0868       #top right latitude
BLX = -105.2898     #bottom left longitude
BLY = 40.0010       #bottom left latitude

Run the program by typing:


The program starts by getting some information from the user.

You will select to either run the program with a GPS device connected or you can load your own GPS NMEA sentences into a file called nmea.txt. Since you have your GPS connected, you will select your COM port and be presented with two mapping options: a position map…

…or an altitude map.

Once you open the serial port to your GPS, the nmea.txt file will automatically be created and raw GPS NMEA data, specifically GPGGA sentences, will be logged in a private thread. When you make a map selection, the nmea.txt file is copied into a file called temp.txt, which is parsed for latitude and longitude (or altitude). The temp.txt file is created to parse the data so that we don’t corrupt or happen to change the main nmea.txt log file. 

The maps are generated in their own windows with options to save, zoom, and hover your mouse over points to get fine grain x,y coordinates. 

Also, the maps don’t refresh automatically, so as your GPS logs data, you will need to close the map window and run the map generation commands to get new data. If you close the entire Python program, the logging to nmea.txt halts. 

This program isn’t finished by any means. I found myself constantly wanting to add features and fix bugs. I binged on Python for a weekend, simply because there are so many modules to work with: GUI tools, interfacing to the web, etc. It is seriously addicting. If you have any modifications or suggestions, please feel free to leave them in the comments below. Thanks for reading!

Getting Started with U-Center for u-blox


U-center from u-blox is a free software tool for configuring u-blox GPS receivers under Windows. U-center is a dense program with many interface elements. It can be overwhelming at first but over time it will become easier to use. For all its GUI weaknesses, it is very powerful for configuring the u-blox line of modules (such as the NEO-M8P-2 and SAM-M8Q to name a few). In this tutorial, we will be exploring some of its features with the NEO-M8P-2.

U-center default look

Required Software

The software can be obtained from u-blox. To follow along with this tutorial please download and install u-center. Once completed, open it.DOWNLOAD U-CENTER

Install Drivers

For this tutorial we’ll assume you have the SparkFun GPS-RTK but u-center can be used with any u-blox based product. Start by attaching a micro-B cable to the GPS-RTK board.

NEO-M8 module seen as location sensor in device manager

Now open Windows Device Manager. The NEO-M8 series has an annoying feature where the module comes up as a Windows Sensor rather than a serial device. If your u-blox receiver does not appear under COM ports then right click on the u-blox GNSS Location Sensor and then Update Driver. Next, click on Browse my computer for driver software.

Click browse my computer

Then “Let me pick”…

Let me pick button

Select the first USB serial device.

Select USB device

The SparkFun GPS-RTK board should now enumerate as a USB serial COM port. In the list below, the GPS-RTK board is COM12.

NEO-M8P showing up as COM port

Return to u-center and drop down the port list. Select the COM port that is your RTK board. Congrats! You can now use u-center.

List of com ports in u-center

Configuring and Outputting NMEA Sentences

Let’s go over a few features you’ll likely use:

Text Console

The text console button will show you the raw NMEA sentences. This is handy for quickly inspecting the visible ASCII coming from the module over USB.

u-center text console


The configuration button opens the most powerful window. From this window you can inspect and configure new settings. It’s not obvious but when you click on a setting such as ‘MSG (Messages),’ u-center will poll the module for its current state. The ‘10s’ in the corner indicates how old the displayed information is. In this case it’s been 10 seconds since this setting was last queried. Click on the ‘Poll’ button to update the information. Go ahead and select the F0-00 NMEA GxGGA message. As you click the dropdown menu, the software will poll the current settings. It’s a bit disorienting at first but gets better over time.

Configuration button and msg window

The MSG configuration is very powerful. It allows you to enable or disable various NMEA sentences as well as binary protocols such as NAV-PVT (checkout the [full protocol datasheet](link text). Once a sentence is selected, such as GxGGA, the check boxes will be populated. If you want to disable the GxGGA sentence for the SPI interface, uncheck the SPI checkbox and then click ‘Send’. Congrats! The GxGGA sentence is no longer presented on the SPI interface. This raises an important fact:

Note: The NEO-M8 series has 4 interfaces: USB(serial), I2C, SPI, and UART. All interfaces can access information simultaneously. This means you can inspect configuration settings over the USB serial port while your Arduino makes setting changes over the I2C port. You can read NMEA sentences over the I2C port or send RTCM data into the module over SPI. It’s all highly configurable.

What is the USB Port on the NEO-M8P?

It’s like any other USB to serial device. It will enumerate on your computer as a COM port and acts as such. It is independent and separate from the UART port that is a dedicated TTL serial port.

If something is not accessible through u-center, it probably means that feature or setting is not compatible with the currently attached device. For example, the UART2 box is grayed out in the image above. The NEO-M8P does not have a second UART so you can’t address it.


The Ports (PRT) sub-menu under Configuration is very helpful. You can do things like change the baud rate, I2C address, and protocols. Depending on your application, you may want to enable or disable entire interface protocols. For example, if you want to enable NMEA sentences for the SPI interface, you would do it here. Fortunately, the factory default for the NEO-M8P is good for I2C and UART1 for RTK purposes (input of RTCM3 is enabled for both ports).

u-center ports menu

This is also the menu that allows you to change the I2C address of your GPS-RTK. Because we are big fans of the Qwiic system, we’ll be using the GPS-RTK on the I2C bus. If we had another device on the bus that uses address 0x42 this menu will allow us to change the address of the GPS-RTK.

Poke around the various config menus. If you get your module into an unknown state you can unplug and replug to reset the settings.


The messages window will allow you to view the various sentences reported by the module. It’s not obvious but if you double click on ‘NMEA’, the tree of messages will fold away. Similarly, if you double click on ‘UBX’, it will expand showing the various UBX sentences. By default, many of these are not enabled.

MSG window

Resources and Going Further

GPS Coordinates

Ready to get hands-on with GPS?

We’ve got a page just for you! We’ll walk you through the basics of how GPS works, the hardware needed, and project tutorials to get you started.


Once you’ve mastered U-Center you’re ready to begin configuring your Ublox module! Check out some of these related tutorials:Building an Autonomous Vehicle: The BatmobileDocumenting a six-month project to race autonomous Power Wheels at the SparkFun Autonomous Vehicle Competition (AVC) in 2016.GPS-RTK Hookup GuideFind out where you are! Use this easy hook-up guide to get up and running with the SparkFun high precision GPS-RTK board.GPS-RTK2 Hookup GuideGet precision down to the diameter of a dime with the new ZED-F9P from Ublox.

GPS-RTK2 Hookup Guide


Artikel från SparkFun:

The SparkFun GPS-RTK2 raises the bar for high-precision GPS. Utilizing the latest ZED-F9P module from u-blox the RTK2 is capable of 10mm 3 dimensional accuracy. Yes, you read that right, the SparkFun GPS-RTK2 board can output your X, Y, and Z location that is roughly the width of your fingernail. With great power comes a few requirements: high precision GPS requires a clear view of the sky (sorry, no indoor location) and a stream of correction data from an RTCM source. We’ll get into this more in a later section but as long as you have two GPS-RTK2 units, or access to an online correction source, your GPS-RTK2 can output lat, long, and altitude with centimeter grade accuracy.

SparkFun GPS-RTK2 Board - ZED-F9P (Qwiic)

SparkFun GPS-RTK2 Board – ZED-F9P (Qwiic)

Suggested Reading

Before getting started, be sure to checkout our What is GPS RTK? tutorial and if you want to pre-read a bit have a look at our Getting Started with U-Center.


An introduction to I2C, one of the main embedded communications protocols in use today.

Serial Basic Hookup Guide

Get connected quickly with this Serial to USB adapter.

What is GPS RTK?

Learn about the latest generation of GPS and GNSS receivers to get 2.5cm positional accuracy!

Getting Started with U-Center for u-blox

Learn the tips and tricks to use the u-blox software tool to configure your GPS receiver.

Hardware Overview

One of the key differentiators between the ZED-F9P and almost all other low-cost RTK solutions is the ZED-F9P is capable of receiving both L1 and L2 bands.

L1 and L2 GNSS reception on the ZED-F9P

Communication Ports

The ZED-F9P is unique in that it has five communication ports which are all active simultaneously. You can read NMEA data over I2C while you send configuration commands over the UART and vice/versa. The only limit is that the SPI pins are mapped onto the I2C and UART pins so it’s either SPI or I2C+UART. The USB port is available at all times.

SparkFun GPS-RTK2 board


The USB C connector makes it easy to connect the ZED-F9P to u-center for configuration and quick viewing of NMEA sentences. It is also possible to connect a Raspberry Pi or other SBC over USB. The ZED-F9P enumerates as a serial COM port and it is a separate serial port from the UART interface. See Getting Started with U-Center for more information about getting the USB port to be a serial COM port.

The USB port highlighted on the ZED-F9P breakout board

A 3.3V regulator is provided to regulate the 5V USB down to 3.3V the module requires. External 5V can be applied or a direct feed of 3.3V can be provided. Note that if you’re provide the board with 3.3V directly it should be a clean supply with minimal noise (less than 50mV VPP ripple is ideal for precision locating).

The 3.3V regulator is capable of sourcing 600mA from a 5V input and the USB C connection is capable of sourcing 2A.

I2C (a.k.a DDC)

The u-blox ZED-F9P has a “DDC” port which is really just an I2C port (without all the fuss of trademark issues). All features are accessible over the I2C ports including reading NMEA sentences, sending UBX configuration strings, piping RTCM data into the module, etc. We’ve written an extensive Arduino library showing how to configure most aspects of the ZED-F9P making I2C our preferred communication method on the ZED. You can get the library through the Arduino library manager by searching ‘SparkFun Ublox’. Checkout the SparkFun U-blox Library section for more information.

The GPS-RTK2 from SparkFun also includes two Qwiic connectors to make daisy chaining this GPS receiver with a large variety of I2C devices. Checkout Qwiic for your next project.

Highlighted I2C port and Qwiic connectors


The classic serial pins are available on the ZED-F9P but are shared with the SPI pins. By default, the UART pins are enabled. Be sure the DSEL jumper on the rear of the board is open.

  • TX/MISO = TX out from ZED-F9P
  • RX/MOSI = RX into ZED-F9P
Serial pins on SparkFun ZED-F9P highlighted

There is a second serial port (UART2) available on the ZED-F9P that is primarily used for RTCM3 correction data. By default, this port will automatically receive and parse incoming RTCM3 strings enabling RTK mode on the board. In addition to the TX2/RX2 pins we have added an additional ‘RTCM Correction’ port where we arranged the pins to match the industry standard serial connection (aka the ’FTDI’ pinout). This pinout is compatible with our Bluetooth Mate and Serial Basic so you can send RTCM correction data from a cell phone or computer. Note that RTCM3 data can also be sent over I2C, UART1, SPI, or USB if desired.

UART2 and RTCM correction port highlighted on ZED-F9P

The RTCM correction port (UART2) defaults to 38400bps serial but can be configured via software commands (checkout our Arduino library) or over USB using u-center. Keep in mind our Bluetooth Mate defaults to 115200bps. If you plan to use Bluetooth for correction data (we found it to be easiest), we recommend you increase this port speed to 115200bps using u-center. Additionally, but less often needed, the UART2 can be configured for NMEA output. In general, we don’t use UART2 for anything but RTCM correction data, so we recommend leaving the in/out protocols as RTCM.

UART2 configuration inside u-center

If you’ve got the ZED-F9P setup for base station mode (also called survey-in mode) the UART2 will output RTCM3 correction data. This means you can connect a radio or wired link to UART2 and the board will automatically send just RTCM bytes over the link (no NMEA data taking up bandwidth).

GPS-RTK2 with Bluetooth Mate attached

Base station setup to send RTCM bytes out over Bluetooth


The ZED-F9P can also be configured for SPI communication. By default, the SPI port is disabled. To enable SPI close the DSEL jumper on the rear of the board. Closing this jumper will disable the UART1 and I2C interfaces (UART2 will continue to operate as normal).

The SPI pins highlighted on the SparkFun RTK2

Control Pins

The control pins are highlighted below.

Highlighted control pins of the SparkFun GPS-RTK2

These pins are used for various extra control of the ZED-F9P:

  • FENCE: Geofence output pin. Configured with U-Center. Will go high or low when a geofence is setup. Useful for triggering alarms and actions when the module exits a programmed perimeter.
  • RTK: Real Time Kinematic output pin. Remains high when module is in normal GPS mode. Begins blinking when RTCM corrections are received and module enters RTK float mode. Goes low when module enters RTK fixed mode and begins outputting cm-level accurate locations.
  • PPS: Pulse-per-second output pin. Begins blinking at 1Hz when module gets basic GPS/GNSS position lock.
  • RST: Reset input pin. Pull this line low to reset the module.
  • SAFE: Safeboot input pin. This is required for firmware updates to the module and generally should not be used or connected.
  • INT: Interrupt input/output pin. Can be configured using U-Center to bring the module out of deep sleep or to output an interrupt for various module states.


The ZED-F9P requires a good quality GPS or GNSS (preferred) antenna. A U.FL connector is provided. Note: U.FL connectors are rated for only a few mating cycles (about 30) so we recommend you set it and forget it. A U.FL to SMA cable threaded through the mounting hole provides a robust connection that is also easy to disconnect at the SMA connection if needed. Low-cost magnetic GPS/GNSS antennas can be used (checkout the ublox white paper) but a 4” / 10cm metal disc is required to be placed under the antenna as a ground plane.

U.FL antenna connector and SMA cut-out on the SparkFun GPS-RTK2

A cutout for the SMA bulkhead is available for those who want an extra sturdy connection. We recommended installing the SMA into the board only when the board is mounted in an enclosure. Otherwise, the cable runs the risk of being damaged when compressed (for example, students carrying the board loose in a backpack).

SMA inserted and screwed to PCB


The board includes four status LEDs as indicated in the image below.

SparkFun GPS-RTK2 LEDs
  • PWR: The power LED will illuminate when 3.3V is activated either over USB or via the Qwiic bus.
  • PPS: The pulse per second LED will illuminate each second once a position lock has been achieved.
  • RTK: The RTK LED will be illuminated constantly upon power up. Once RTCM data has been successfully received it will begin to blink. This is a good way to see if the ZED-F9P is getting RTCM from various sources. Once an RTK fix is obtained, the LED will turn off.
  • FENCE: The FENCE LED can be configured to turn on/off for geofencing applications.


There are five jumpers used to configure the GPS-RTK2.

User jumpers on the SparkFun RTK2

Closing DSEL with solder enables the SPI interface and disables the UART and I2C interfaces. USB will still function.

Cutting the I2C jumper will remove the 2.2k Ohm resistors from the I2C bus. If you have many devices on your I2C bus you may want to remove these jumpers. Not sure how to cut a jumper? Read here!

Cutting the JP1JP2JP3 jumpers will disconnect of the various status LEDs from their associated pins.

Backup Battery

The MS621FE rechargeable battery maintains the battery backed RAM (BBR) on the GNSS module. This allows for much faster position locks. The BBR is also used for module configuration retention. The battery is automatically trickle charged when power is applied and should maintain settings and GNSS orbit data for up to two weeks without power.

The backup battery on the SparkFun RTK2

Connecting an Antenna

U.FL connectors are very good but they are a designed to be implemented inside a small embedded application like a laptop. Exposing a U.FL connector to the wild risks it getting damaged. To prevent damaging the U.FL connection we recommend threading the U.FL cable through the stand-off hole, then attach the U.FL connectors. This will provide a great stress relief for the antenna connection. Now attach your SMA antenna of choice.

U.FL cable threaded through the standoff hole

Be Careful! U.FL connectors are easily damaged. Make sure the connectors are aligned, flush face to face (not at an angle), then press down using a rigid blunt edge such as the edge of a PCB or point of a small flat head screwdriver. For more information checkout our tutorial Three Quick Tips About Using U.FL.

Three Quick Tips About Using U.FL

DECEMBER 28, 2018

Quick tips regarding how to connect, protect, and disconnect U.FL connectors.

Additionally, a bulkhead cut-out is provided to screw the SMA onto the PCB if desired.

SMA inserted and screwed to PCB

While this method decreases stress from the U.FL connector it is only recommended when the board has been permanently mounted. If the board is not mounted, the cable on the U.FL cable is susceptible to being kinked causing impedance changes that may decrease reception quality.

If you’re indoors you must run a SMA extension cable long enough to locate the antenna where it has a clear view of the sky. That means no trees, buildings, walls, vehicles, or concrete metally things between the antenna and the sky. Be sure to mount the antenna on a 4”/10cm metal ground plate to increase reception.

GPS antenna in grass

Connecting the GPS-RTK2 to a Correction Source

Before you go out into the field it’s good to understand how to get RTCM data and how to pipe it to the GPS-RTK2. We recommend you read Connecting a Correction Source section of the original GPS-RTK tutorial. This will give you the basics of how to get a UNAVCO account and how to identify a Mount Point within 10km of where your ZED-F9P rover will be used. This section builds upon these concepts.

For this example, we will show how to get correction data from the UNAVCO network and pull that data in using the Android app called NTRIP Client. The correction data will then be transmitted from the app over Bluetooth to the ZED-F9P using the SparkFun Bluetooth Mate.

Required Materials

Camera Tripod with GNSS Antenna on Ground Plate

GNSS antenna sitting on a metal ground plate elevated with clear view of the sky

Now setup your GPS receiver such that you can work from your desk but have the antenna outdoors with a clear view of the sky.

Required Software

  • Credentials with a free RTCM provider such as UNAVCO
  • U-Center
  • Get the NTRIP By Lefebure app from Google Play. There seem to be NTRIP apps for iOS but we have not been able to verify any one app in particular. If you have a favorite, please let us know.

First we need to attach the Bluetooth Module to the GPS-RTK2 board. Solder a female header to the Bluetooth Mate so that it hangs off the end.

SparkFun Bluetooth Mate with Female header connection

On the GPS-RTK2 board we recommend soldering the right-angle male header underneath the board. This will allow the Bluetooth module to be succinctly tucked under the board.

When attaching the Bluetooth Mate to GPS-RTK2 be sure to align the pins so that the GND indicator align on both Bluetooth module and RTK board. Once Bluetooth has been installed attach your GNSS antenna and connect the RTK2 board over USB. This will power the board and the Bluetooth Mate.

RTK2 connected over USB with Bluetooth

Where the male and female headers go is personal preference. For example, here are two Bluetooth Mates; one with male headers, one with female.

Two Bluetooth Mates with different headers

Soldering a female header to a Bluetooth Mate makes it easier to add Bluetooth to boards that have a ’FTDI’ style connection like our OpenScaleArduino Pro, or Simultaneous RFID Reader. Whereas, soldering a male header to the Bluetooth Mate makes it much easier to use in a breadboard. It’s really up to you!

The Bluetooth Mate defaults to 115200bps whereas the RTK2 is expecting serial over UART2 to be 38400bps. To fix this we need to open u-center and change the port settings for UART2. If you haven’t already, be sure to checkout the tutorial Getting Started with U-Center to get your bearings.

Open the Configure window and navigate to the PRT (Ports) section. Drop down the target to UART2 and set the baud rate to 115200. Finally, click on the ‘Send’ button.

Ublox UCenter Port configuration for RTK

By this time you should have a valid 3D GPS lock with ~1.5m accuracy. It’s about to get a lot better.

We are going to assume you’ve read the original RTK tutorial and obtained your UNAVCO credentials including the following:

  • Username
  • Password
  • IP Address for UNAVCO ( at time of writing)
  • Caster Port (2101 at time of writing)
  • Data Stream a.k.a. Mount Point (‘P041_RTCM3’ if you want the one near Boulder, CO – but you should really find one nearest your rover location)

The Bluetooth Mate should be powered up. From your phone, discover the Bluetooth Mate and pair with it. The module used in this tutorial was discovered as RNBT-E0DC where E0DC is the last four characters of the MAC address of the module and should be unique to your module.

Once you have your UNAVCO credentials and you’ve paired with the Bluetooth module open the NTRIP client.

Homescreen of NTRIP Client for Android

From the home screen, click on the gear in upper right corner then Receiver Settings.

NTRIP Client Receiver Settings

Verify that the Receiver Connection is set to Bluetooth then select Bluetooth Device and select the Bluetooth module you just paired with. Next, open NTRIP settings and enter your credentials including mounting point (a.k.a. Data Stream).

NTRIP Client Server Settings

This example demonstrates how to obtain correction data from UNAVCO’s servers but you could similarly setup your own base station using another ZED-F9P and RTKLIB to broadcast the correction data. This NTRIP app would connect to your RTKLIB based server giving you some amazing flexibility (the base station could be anywhere there’s a laptop and Wifi within 10km of your rover).

Ok. You ready? This is the fun part. Return to the main NTRIP window and click Connect. The app will connect to the Bluetooth module. Once connected, it will then connect to your NTRIP source. Once data is flowing you will see the number of bytes increase every second.

NTRIP Client downloading correction data

Within a few seconds you should see the RTK LED on the GPS-RTK2 board turn off. This indicates you have an RTK fix. To verify this, open u-center on your computer. The first thing to notice is that Fix Mode in the left hand black window has changed from 3D to 3D/DGNSS/FIXED.

U-center showing 17mm accuracy

Navigate to the UBX-NAV-HPPOSECEF message. This will show you a high-precision 3D accuracy estimate. We were able to achieve 17mm accuracy using a low-cost GNSS antenna with a metal plate ground plane and we were over 10km from the correction station.

Congrats! You now know where you are within the diameter of a dime!

SparkFun U-blox Library

Note: This example assumes you are using the latest version of the Arduino IDE on your desktop. If this is your first time using Arduino, please review our tutorial on installing the Arduino IDE. If you have not previously installed an Arduino library, please check out our installation guide.

The SparkFun Ublox Arduino library enables the reading of all positional datums as well as sending binary UBX configuration commands over I2C. This is helpful for configuring advanced modules like the ZED-F9P but also the NEO-M8P-2, SAM-M8Q and any other Ublox module that use the Ublox binary protocol.

The SparkFun U-blox Arduino library can be downloaded with the Arduino library manager by searching ’SparkFun Ublox’ or you can grab the zip here from the GitHub repository:SPARKFUN U-BLOX ARDUINO LIBRARY (ZIP)

Once you have the library installed checkout the various examples.

  • Example1: Read NMEA sentences over I2C using Ublox module SAM-M8Q, NEO-M8P, etc
  • Example2: Parse NMEA sentences using MicroNMEA library. This example also demonstrates how to overwrite the processNMEA function so that you can direct the incoming NMEA characters from the Ublox module to any library, display, radio, etc that you prefer.
  • Example3: Get latitude, longitude, altitude, and satellites in view (SIV). This example also demonstrates how to turn off NMEA messages being sent out of the I2C port. You’ll still see NMEA on UART1 and USB, but not on I2C. Using only UBX binary messages helps reduce I2C traffic and is a much lighter weight protocol.
  • Example4: Displays what type of a fix you have the two most common being none and a full 3D fix. This sketch also shows how to find out if you have an RTK fix and what type (floating vs. fixed).
  • Example5: Shows how to get the current speed, heading, and dilution of precision.
  • Example6: Demonstrates how to increase the output rate from the default 1 per second to many per second; up to 30Hz on some modules!
  • Example7: Older modules like the SAM-M8Q utilize an older protocol (version 18) whereas the newer modules like the ZED-F9P depricate some commands using the latest protocol (version 27). This sketch shows how to query the module to get the protocol version.
  • Example8: Ublox modules use I2C address 0x42 but this is configurable via software. This sketch will allow you to change the module’s I2C address.
  • Example9: Altitude is not a simple measurement. This sketch shows how to get both the ellipsoid based altitude and the MSL (mean sea level) based altitude readings.
  • Example10: Sometimes you just need to do a hard reset of the hardware. This sketch shows how to set your Ublox module back to factory default settings.
  • NEO-M8P
    • NEO-M8P Example1: Send UBX binary commands to enable RTCM sentences on U-blox NEO-M8P-2 module. This example is one of the steps required to setup the NEO-M8P as a base station. For more information have a look at the Ublox manual for setting up an RTK link.
    • NEO-M8P Example2: This example extends the previous example sending all the commands to the NEO-M8P-2 to have it operate as a base. Additionally the processRTCM function is exposed. This allows the user to overwrite the function to direct the RTCM bytes to whatever connection the user would like (radio, serial, etc).
    • NEO-M8P Example3: This is the same example as NEO-M8P’s Example2. However, the data is sent to a serial LCD via I2C.
  • ZED-F9P
    • ZED-F9P Example1: This module is capable of high precision solutions. This sketch shows how to inspect the accuracy of the solution. It’s fun to watch our location accuracy drop into the millimeter scale.
    • ZED-F9P Example2: The ZED-F9P uses a new Ublox configuration system of VALGET/VALSET/VALDEL. This sketch demonstrates the basics of these methods.
    • ZED-F9P Example3: Setting up the ZED-F9P as a base station and outputting RTCM data.
    • ZED-F9P Example4: This is the same example as ZED-F9P’s Example3. However, the data is sent to a serial LCD via I2C.

This SparkFun Ublox library really focuses on I2C because it’s faster than serial and supports daisy-chaining. The library also uses the UBX protocol because it requires far less overhead than NMEA parsing and does not have the precision limitations that NMEA has.

Setting the GPS-RTK2 as a Correction Source

If you’re located further than 20km from a correction station you can create your own station using the ZED-F9P. Ublox provides a setup guide within the ZED-F9P Integration Manual showing the various settings needed via U-Center. We’ll be covering how to setup the GPS-RTK2 using I2C commands only. This will enable a headless (computerless) configuration of a base station that outputs RTCM correction data.

Before getting started we recommend you configure the module using U-Center. Checkout our tutorial on using U-Center then read section 3.5.8 Base Station Configuration of the Ublox Integration Manual for getting the ZED-F9P configured for RTK using U-Center. Once you’ve been successful controlling the module in the comfort of your lab using U-Center, then consider heading outdoors.

For this exercise we’ll be using the following parts:

The ZED-F9P can be configured using Serial, SPI, or I2C. We’re fans of the daisychain-ability of I2C so we’ll be focusing on the Qwiic system. For this exercise we’ll be connecting the an LCD and GPS-RTK2 to a BlackBoard using two Qwiic cables.

ZED-F9P in survey in mode

For the antenna, you’ll need a clear view of the sky. The better your antenna position the better your accuracy and performance of the system. We designed the GPS Antenna Ground Plate to make this setup easy. The plate has a ¼” threaded hole that threads directly onto a camera tripod. The plate thickness was chosen to be thick enough so that the threaded screw is flush with the plate so it won’t interfere with the antenna. Not sure why we’re using a ground plate? Read the Ublox white paper on using low-cost GNSS antennas with RTK. Mount your magnetic mount antenna and run the SMA cable to the U.FL to SMA cable to the GPS-RTK2 board.

GPS RTK antenna on camera tripod

There are only three steps to initiating a base station:

  • Enable Survey-In mode for 1 minute (60 seconds)
  • Enable RTCM output messages
  • Being Transmitting the RTCM packets over the backhaul of choice

Be sure to grab the SparkFun Arduino Library for Ublox. You can easily install this via the library manager by searching ‘SparkFun Ublox’. Once installed click on File->Examples->SparkFun_Ublox_Arduino_Library.

The ZED-F9P subfolder houses a handful of sketches specific to its setup. Example3 of the library demonstrates how to send the various commands to the GPS-RTK2 to enable Survey-In mode. Let’s discuss the important bits of code.

COPY CODEresponse = myGPS.enableSurveyMode(60, 5.000); //Enable Survey in, 60 seconds, 5.0m

The library is capable of sending UBX binary commands with all necessary headers, packet length, and CRC bytes over I2C. The enableSurveyMode(minimumTime, minimumRadius) command does all the hard work to tell the module to go into survey mode. The module will begin to record lock data and calculate a 3D standard deviation. The survey-in process ends when both the minimum time and minimum radius are achieved. Ublox recommends 60 seconds and a radius of 5m. With a clear view of the sky, with a low cost GNSS antenna mounted to a ground plate we’ve seen the survey complete at 61 seconds with a radius of around 1.5m.

COPY CODEresponse &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_I2C, 1); //Enable message 1005 to output through I2C port, message every second
response &= myGPS.enableRTCMmessage(UBX_RTCM_1074, COM_PORT_I2C, 1);
response &= myGPS.enableRTCMmessage(UBX_RTCM_1084, COM_PORT_I2C, 1);
response &= myGPS.enableRTCMmessage(UBX_RTCM_1094, COM_PORT_I2C, 1);
response &= myGPS.enableRTCMmessage(UBX_RTCM_1124, COM_PORT_I2C, 1);
response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_I2C, 10); //Enable message every 10 seconds

These six lines enable the six RTCM output messages needed for a second GPS-RTK2 to receive correction data. Once these sentences have been enabled (and assuming a survey process is complete) the GPS-RTK2 base module will begin outputting RTCM data every second after the NMEA sentences (the RTCM_1230 sentence will be output once every 10 seconds). You can view an example of what this output looks like here.

The size of the RTCM correction data varies but in general it is approximately 2000 bytes every second (~2500 bytes every 10th second when 1230 is transmitted).

COPY CODE//This function gets called from the SparkFun Ublox Arduino Library.
//As each RTCM byte comes in you can specify what to do with it
//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
  //Let's just pretty-print the HEX values for now
  if (myGPS.rtcmFrameCounter % 16 == 0) Serial.println();
  Serial.print(" ");
  if (incoming < 0x10) Serial.print("0");
  Serial.print(incoming, HEX);

If you have a ‘rover’ in the field in need of correction data you’ll need to get the RTCM bytes to the rover. The SparkFun Ublox library automatically detects the difference between NMEA sentences and RTCM data. The processRTCM() function allows you to ‘pipe’ just the RTCM correction data to the channel of your choice. Once the base station has completed the survey and has the RTCM messages enabled, your custom processRTCM() function can pass each byte to any number of channels:

  • A wireless system such as LoRa or Cellular
  • Posting the bytes over the internet using WiFi or wired ethernet over an Ntrip caster
  • Over a wired solution such as RS485

The power of the processRTCM() function is that it doesn’t care; it presents the user with the incoming byte and is agnostic about the back channel.Heads up! We’ve been experimenting with various LoRa solutions and the bandwidth needed for the best RTCM (~500 bytes per second) is right at the usable byte limit for many LoRa setups. It’s possible but you may need to adjust your LoRa settings to reach the throughput necessary for RTK.

What about configuring the rover? Ublox designed the ZED-F9P to automatically go into RTK mode once RTCM data is detected on any of the ports. Simply push the RTCM bytes from your back channel into one of the ports (UART, SPI, I2C) on the rover’s GPS-RTK2 and the location accuracy will go from meters to centimeters. The rover’s NMEA messages will contain the improved Lat/Long data and you’ll know where you are with mind-bending accuracy. It’s a lot of fun to watch!

Can I Really Use NMEA with a High Precision GPS Receiver?

Yes! Except that NMEA sentences are right on the edge of enough precision. NMEA sentences look something like this:

COPY CODE$GNGGA,012911.00,4003.19080,N,10416.95542,W,1,12,0.75,1647.1,M,-21.3,M,,*4F

NMEA outputs coordinates in the ddmm.mmmmm format. So what is the weight of the least significant digit? Said differently, what is the impact of one digit change?

COPY CODE104 16.95542


COPY CODE104 16.95543

If we know 1 degree of latitude is 111.3km at the equator, we can glean the change of a fraction of a minute:

  • 1 degree = 60 minutes
  • 1 minute = 1 degree/60 = 111.32km / 60 = 1.855km
  • 1 minute = 1855m
  • 0.1min = 185.5m
  • 0.01min = 18.55m
  • 0.001min = 1.855m
  • 0.0001min = .1855m = 185.5mm
  • 0.00001min = 0.0185m = 18.55mm = 1.855cm

Using the NMEA sentence, the ZED-F9P will only be able to communicate a change of ~1.5cm location change for each digit in the 5th position. This is pretty close to the 1.0cm accuracy of the module. If you want additional precision, you should consider using the UBX protocol which can output up to 8 digits of precision in dd.dddddddd format which will get you down to 1.11mm of precision! Be sure to checkout the examples in the SparkFun Ublox Arduino Library. We have various examples outputting the full 8 digits of precision over I2C without the burden of parsing NMEA sentences.

Resources and Going Further

GPS Coordinates

Ready to get hands-on with GPS?

We’ve got a page just for you! We’ll walk you through the basics of how GPS works, the hardware needed, and project tutorials to get you started.


Have fun with your new found super power: sub decimeter grade GPS!

For more on the GPS-RTK2, check out the links below:

Need some inspiration? Check out some of these related tutorials:

Building an Autonomous Vehicle: The Batmobile

Documenting a six-month project to race autonomous Power Wheels at the SparkFun Autonomous Vehicle Competition (AVC) in 2016.

What is GPS RTK?

Learn about the latest generation of GPS and GNSS receivers to get 2.5cm positional accuracy!

GPS-RTK Hookup Guide

Find out where you are! Use this easy hook-up guide to get up and running with the SparkFun high precision GPS-RTK board.

Getting Started with U-Center for u-blox

Learn the tips and tricks to use the u-blox software tool to configure your GPS receiver.