GNSS Correction Data Receiver (NEO-D9S) Hookup Guide a learn.sparkfun.com tutorial

Available online at: http://sfe.io/t2352

Contents

Introduction

The SparkFun GNSS Correction Data Receiver - NEO-D9S is a satellite data receiver for L-band correction broadcast. It can be configured for use with a variety of correction services including u-blox's PointPerfect satellite GNSS augmentation service, which provides homogenous coverage in contiguous USA and Europe. With a clear view of the sky, especially a clear view to the South, it decodes the satellite transmission and outputs a correction stream, enabling a multi-band high precision GNSS receiver (such as the u-blox ZED-F9P) to reach accuracies down to centimeter-level positioning without needing a separate RTK or NTRIP correction!

SparkFun GNSS Correction Data Receiver - NEO-D9S (Qwiic)

SparkFun GNSS Correction Data Receiver - NEO-D9S (Qwiic)

GPS-19390
$124.95

Required Materials

To follow along with this tutorial, you will need the following materials. You may not need everything though depending on what you have. Add it to your cart, read through the guide, and adjust the cart as necessary.

Arduino Microcontroller

We recommend an Arduino microcontroller with the ability to connect to WiFi. This is useful for those users taking advantage of both the ThingStream PointPerfect Location-as-a-Service over L-Band Satellite and Internet Protocol (IP). The following boards with the ESP32 WROOM module can work.

SparkFun Thing Plus - ESP32 WROOM (USB-C)

SparkFun Thing Plus - ESP32 WROOM (USB-C)

WRL-20168
$24.95
3
SparkFun IoT RedBoard - ESP32 Development Board

SparkFun IoT RedBoard - ESP32 Development Board

WRL-19177
$29.95
7

High Precision GNSS (HPG) Module

Along with the NEO-D9S, you will need a high precision GNSS (HPG) module from u-blox. As of the writing of his tutorial, the GNSS correction data receiver works for the ZED-F9P module. You will need to make sure that it has the latest firmware when using the modules together.

SparkFun GPS-RTK-SMA Breakout - ZED-F9P (Qwiic)

SparkFun GPS-RTK-SMA Breakout - ZED-F9P (Qwiic)

GPS-16481
$274.95
18
SparkFun GPS-RTK2 Board - ZED-F9P (Qwiic)

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

GPS-15136
$274.95
21

Antennae and Cables

For the ZED-F9P, you will need a multi-band antenna to take advantage of the L1 and L2 bands. For the NEO-D9S, you will need a L-band antenna. While the GNSS Multi-band L1/L2 Surveying Antenna (TNC) TOP106 was designed for L1 and L2, we found that it was able to pick up the correction data tuned to a frequency within the L-band (1556.29MHz in the US and 1545.26MHz in EU). Make sure to also pick up the TNC to SMA male interface cable and if necessary, an additional SMA extension cable or u.FL to SMA interface cable for the ZED-F9P breakout boards populated with the u.FL connector.

GNSS Multi-Band L1/L2 Surveying Antenna - TNC (TOP106)

GNSS Multi-Band L1/L2 Surveying Antenna - TNC (TOP106)

GPS-17751
$133.95
14
Reinforced Interface Cable - SMA Male to TNC Male (10m)

Reinforced Interface Cable - SMA Male to TNC Male (10m)

CAB-21740
$29.95
1
Interface Cable U.FL to SMA - 100mm

Interface Cable U.FL to SMA - 100mm

WRL-18154
$8.95

Interface Cable - SMA Female to SMA Male (25cm)

WRL-12861
1

You could also use the u-blox or MagmaX2 multi-band antenna for the ZED-F9P and NEO-D9S in the US. However, you would also need the ground plate. Again, while they were designed for L1 and L2, we found that it was also able to pick up the correction data tuned to a frequency within the L-band within the US. You may also need an additional u.FL to SMA interface cable for ZED-F9P breakout boards populated with the u.FL connector.

GNSS L1/L2 Multi-Band Magnetic Mount Antenna - 5m (SMA)

GNSS L1/L2 Multi-Band Magnetic Mount Antenna - 5m (SMA)

GPS-15192
$72.95
1
GPS Antenna Ground Plate

GPS Antenna Ground Plate

GPS-17519
$6.95
Interface Cable U.FL to SMA - 100mm

Interface Cable U.FL to SMA - 100mm

WRL-18154
$8.95
MagmaX2 Active Multiband GNSS Magnetic Mount Antenna - AA.200

MagmaX2 Active Multiband GNSS Magnetic Mount Antenna - AA.200

GPS-17108
$83.50

Qwiic Cables

For those that want to take advantage of the Qwiic enabled devices, you'll want to grab a Qwiic cable between each board.

SparkFun Qwiic Cable Kit

SparkFun Qwiic Cable Kit

KIT-15081
$8.95
21
Qwiic Cable - 100mm

Qwiic Cable - 100mm

PRT-14427
$1.50

Qwiic Cable - 500mm

PRT-14429
1 Retired
Qwiic Cable - Breadboard Jumper (4-pin)

Qwiic Cable - Breadboard Jumper (4-pin)

PRT-14425
$1.50

LiPo Battery

A single-cell Lithium-ion battery can be connected to the ESP32 IoT RedBoard's JST connector. In turn, this will power the NEO-D9S and ZED-F9P for portability.

Lithium Ion Battery - 850mAh

Lithium Ion Battery - 850mAh

PRT-13854
$10.95
2
Lithium Ion Battery - 2Ah

Lithium Ion Battery - 2Ah

PRT-13855
$13.95
9
Lithium Ion Battery - 6Ah

Lithium Ion Battery - 6Ah

PRT-13856
$32.50
7

Lithium Ion Battery - 1Ah

PRT-13813
8 Retired

Tools

Depending on your setup, you may need a soldering iron, solder, and general soldering accessories for a secure connection when using the plated through holes.

PINECIL Soldering Iron Kit

PINECIL Soldering Iron Kit

KIT-24063
$69.95
1
Solder Lead Free - 15-gram Tube

Solder Lead Free - 15-gram Tube

TOL-09163
$3.95
4

Prototyping Accessories

Depending on your setup, you may want to use IC hooks for a temporary connection. However, you will want to solder header pins to connect devices to the plated through holes for a secure connection.

Breadboard - Self-Adhesive (White)

Breadboard - Self-Adhesive (White)

PRT-12002
$5.50
48
Break Away Headers - Straight

Break Away Headers - Straight

PRT-00116
$1.75
20
IC Hook with Pigtail

IC Hook with Pigtail

CAB-09741
$5.50
10
Jumper - 2 Pin

Jumper - 2 Pin

PRT-09044
$0.45

You Will Also Need

You will need access to dynamic keys to decrypt the correct data sent from an L-band satellite. Users will need to purchase a pricing plan with the ThingStream PointPerfect Location-as-a-Service over L-Band Satellite. You can also purchase a pricing plan that includes the L-Band and Internet Protocol (IP).

u-blox Thingstream IoT Location-as-a-Service: PointPerfect Pricing Options

As stated on the coverage map from u-blox, the service includes homogeneous coverage in the contiguous USA and Europe This includes up to 12 nautical miles (roughly 22 kilometers) off coastlines. Make sure to check back on the u-blox's website to see if there is additional coverage in your region. There are additional regions under consideration for the future but they have not been included yet for L-band reception.

L-Band Coverage

Image courtesy of u-blox Thingstream: PerfectPoint Service Description

Suggested Reading

If you aren't familiar with the Qwiic system, we recommend reading here for an overview.

Qwiic Connect System
Qwiic Connect System

We would also recommend taking a look at the following tutorials if you aren't familiar with them.

GPS Basics

The Global Positioning System (GPS) is an engineering marvel that we all have access to for a relatively low cost and no subscription fee. With the correct hardware and minimal effort, you can determine your position and time almost anywhere on the globe.

Serial Peripheral Interface (SPI)

SPI is commonly used to connect microcontrollers to peripherals such as sensors, shift registers, and SD cards.

How to Power a Project

A tutorial to help figure out the power requirements of your project.

Logic Levels

Learn the difference between 3.3V and 5V devices and logic levels.

I2C

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

How to Work with Jumper Pads and PCB Traces

Handling PCB jumper pads and traces is an essential skill. Learn how to cut a PCB trace, add a solder jumper between pads to reroute connections, and repair a trace with the green wire method if a trace is damaged.

What is GPS RTK?

Learn about the latest generation of GPS and GNSS receivers to get 14mm 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.

GPS-RTK2 Hookup Guide

Get precision down to the diameter of a dime with the new ZED-F9P from u-blox.

Hardware Overview

The NEO-D9S-00B is a satellite data receiver for L-band correction broadcast, which can be configured for use with a variety of correction services. It decodes the satellite transmission and outputs a correction stream, enabling a high precision GNSS receiver to reach accuracies down to centimeter level! In this section, we'll highlight important parts of the board. For more information about the NEO-D9S, check out the Resources and Going Further for more information.

u-blox NEO-D9S Module

Power

Power for this board is 3.3V and we have provided multiple power options. This first and most obvious is the USB-C connector. Secondly, are the Qwiic Connectors on the left and right of the board for ground and 3.3V. Thirdly, there is a 5V pin on the PTH header along the left side of the board that is regulated down to 3.3V with the 3.3V/600mA AP2112K voltage regulator (as indicated with the 5-pin component next to the 3V3 pin). Make sure that power you provide to this pin does not exceed 6 volts. Just below the 5V pin is a 3V3 pin that should only be provided a clean 3.3V power signal. 3V3 are also broken out on the USB-to-serial port and on the other side of the board. GND is also provided near each power pin.

Power Through USB, PTH Pins, Qwiic Connector

LED

There is one power LED labeled as PWR. The LED will illuminate when 3.3V is activated. This can be disabled by cutting the jumper on the back of the board labeled as "PWR" as well.

LED

Qwiic and I2C

There are two pins labeled SDA and SCL which indicates the I2C data and clock lines. Similarly, you can use either of the Qwiic connectors to provide power and utilize I2C. The Qwiic ecosystem is made for fast prototyping by removing the need for soldering. All you need to do is plug a Qwiic cable into the Qwiic connector and voila!

Qwiic and I2C connectors highlighted

SPI

There are four pins that are labeled with their corresponding SPI functionality. These pins are broken out on both sides of the board. As mentioned in the jumpers section, you'll need to close the SPI jumper on the underside to enable SPI.

SPI pins highlighted

UART

There are two pins labeled as TXD1/POCI and RXD1/PICO. The UART pins are shared with the SPI pins. By default, the UART interface is enabled. Be sure that the SPI jumper on the back of the board is open.

UART1 port

There is also a second UART port. You can connect this to a u-blox F9 module that supports correction data output from the NEO-D9S. The datasheet indicates that you could potentially use any high precision GNSS receiver from the u-blox F9 platform as denoted as the ZED-F9X, where the "X" indicates different variant. Make sure to check the latest u-blox F9 product Integration Manual for more information on whether the correction data is supported with the respective module

UART2 and UART-to-Serial standard port

Broken Out Pins

There are four other pins broken out:

Miscellaneous Pins and RF Trace

Jumpers

If you flip the board over, you will notice a few jumper pads. For more information on modifying the jumpers, check out our tutorial on working with jumper pads and PCB traces.

Jumpers

SMA Connector

The board is equipped with a SMA connector. You will need an active antenna that can receive signals from an L-Band satellite between 1525.0 MHz to 1559.0 MHz as stated in the datasheet. The specific frequency between the L-Band that the NEO-D9S uses depends on your region and service provider. Make sure to check the antenna's datasheet, region, and service provider for more information.

SMA Connector

Board Dimensions

The board dimensions are 1.70"x1.70". This does not include the dimensions for the SMA connector and USB Type C connector. There are four mounting holes by each corner of the board.

Board Dimensions

Hardware Hookup

To add GNSS correction data to your high precision GNSS receiver like the ZED-F9P, you can connect any of the serial ports between the two boards. If you are using SPI to connect, just make sure to enable the SPI port by adding a solder jumper to the SPI jumper pads. For an embedded application, we recommend adding an ESP32 to the setup. In addition to the Thingstream PointPerfect over L-band satellite, the ESP32 will also allow you to use the Thingstream PointPerfect service over Internet Protocol (IP) using MQTT.

I2C via Qwiic

Below is one example to connect using the I2C port and Qwiic. Simply insert a Qwiic cable between the ZED-F9P, NEO-D9S, and Arduino microcontroller's Qwiic connectors. Plug in a compatible antenna with SMA connector to the ZED-F9P and NEO-D9S board. For the ZED-F9P, you will need the multiband antenna that is capable of receiving L1/L2 bands. For boards that have a u.FL connector, make sure use a u.FL to SMA adapter cable. For the NEO-D9S, you will need to attach an L-Band antenna. Secure the connection on both antennas using the hex nut until it is finger-tight. For power, we will use a USB-C cable to power the ESP32 development board. You can also use this cable to connect each breakout to your computer when using the u-blox u-center software.

ESP32 IoT RedBoard, ZED-F9P w/ u.FL connector, and NEO-D9S connected via Qwiic Cables

I2C and UART2 Ports via PTH

For those that prefer a PTH connection, you could connect using male header pins, 2-pin jumpers, F/F jumper wires, and M/F jumper wires. In this case, the ZED-F9P and NEO-D9S breakout boards were connected using the male header pins and 2-pin jumpers. The Arduino microcontroller was connected using a Qwiic cable. Of course, you will still need to plug in a compatible antenna with SMA connector to the ZED-F9P and NEO-D9S board. For the ZED-F9P, you will need the multiband antenna that is capable of receiving L1/L2 bands. For boards that have a u.FL connector, make sure use a u.FL to SMA adapter cable. For the NEO-D9S, you will need to attach an L-Band antenna. Secure the connection using the hex nut until it is finger-tight. For power, we will use a USB-C cable to power the ESP32 development board. You can also use this cable to connect each breakout to your computer when using the u-blox u-center software.

ESP32 IoT RedBoard, ZED-F9P w/ u.FL connector, and NEO-D9S connected via Male Header Pins, Jumper Shunts, and Qwiic Cable

u-blox Firmware Update

We recommend checking the firmware on your high precision GNSS (HPG) module (in this case, the ZED-F9P). If the firmware is old, you will need to upgrade the firmware on the HPG module.

How to Upgrade Firmware of a u-blox GNSS Receiver

March 26, 2021

A few steps and you'll upgrade to the latest features on a u-blox GNSS receiver.

You can download the latest firmware from u-blox. Below is a link to the ZED-F9P module's product page. Click the "Documentation & resources" tab and look for the latest firmware under the section Firmware Update. You may need to hit the Load more button a few times before you can see the firmware.

u-blox: ZED-F9P Module Product Page

u-Blox Thingstream Services

There are three key steps to be able to achieve centimeter positioning accuracy using the ZED-F9P and NEO-D9S.

By default, the ZED-F9P is configured such that the correction data is passed from the NEO to the ZED using the UART2 interface. However, it is also possible to read the correction data from the NEO and push (write) it to the ZED using I2C. We just need to configure the modules so that the I2C port is enabled and set the protocol.

Thingstream and PointPerfect Services

The NEO-D9S was designed to receive correction data from an L-band satellite and push it to a high precision GNSS module like the ZED-F9P. You will need to use u-blox Thingstream and PointPerfect service to provide dynamic keys in order to decrypt the correction data.

u-blox Thingstream Service Logo


Thingstream is u-blox service delivery platform for IoT Communication-as-a-Service, IoT Security-as-a-Service and IoT Location-as-a-Service.

u-blox Point Perfect GNSS Augmentation Logo

PointPerfect is u-blox GNSS augmentation service which is designed to provide high-precision GNSS corrections to suitable receivers with decimeter-level location accuracy. The following webinar from u-blox has an excellent explanation of the service and how the system works.

PointPerfect data is delivered through Thingstream. The first step is to register with Thingstream and then request an L-Band plan:

PointPerfect Pricing

PointPerfect pricing (correct at Sept. 14th 2022). (Click to enlarge)

You can find the current pricing on u-blox portal. Select IoT Location-as-a-Service and then PointPerfect.

You may need to contact u-blox first, to enable the option to purchase an L-Band plan through your Thingstream account.

The PointPerfect L-band plan provides unlimited access to the L-band satellite correction data stream (via the NEO-D9S).

If you have an internet connection, you can also receive PointPerfect corrections via IP (MQTT). The PointPerfect L-band and IP plan may be a better choice if you think you may want to receive correction data via both satellite and Internet.

Once L-band permissions are enabled on your Thingstream account, you will be able to add a new L-band Location Thing and view its credentials:

u-blox have written a comprehensive application note which describes in detail: the configuration of both NEO and ZED; and how to interpret the expiry date for the L-band encryption keys. In the following sections, we describe how to configure the NEO and ZED using our u-blox GNSS Arduino Library.

Installing the Arduino 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 IDE, library, or board add-on, please review the following tutorials.


If you've never connected an CH340 device to your computer before, you may need to install drivers for the USB-to-serial converter. Check out our section on How to Install CH340 Drivers" for help with the installation.


The SparkFun u-blox 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-D9S, NEO-M8P-2, SAM-M8Q and other u-blox modules that use the u-blox binary protocol.

Note: We support two versions of the SparkFun u-blox GNSS library. Version 2 and Version 3. Version 3 uses the u-blox Configuration Interface (VALSET and VALGET) to configure the module, instead of the deprecated UBX-CFG messages. For modules like the D9, F9 and M10, we recommend upgrading to Version 3. However, older modules like the M8 do not support the Configuration Interface. For those you will need to keep using Version 2 of the library. We will continue to support both.

The SparkFun u-blox Arduino library can be downloaded with the Arduino library manager by searching 'SparkFun u-blox GNSS v3' or you can grab the zip here from the GitHub repository to manually install. Once the library is installed, you can take advantage of the examples for the ZED-F9P.

SparkFun u-blox Arduino Library v3 (ZIP)


Arduino Library Overview

We will be highlighting a few parts of the SparkFun u-blox Arduino GNSS Library below for the NEO-D9S and the ZED-F9P.

NEO-D9S Configuration

The first step is to declare the SFE_UBLOX_GNSS object. Like most Arduino sketches, this is done at a global scope (after the include file declaration), not within the setup() or loop() functions.

language:c
#include <SparkFun_u-blox_GNSS_v3.h> //http://librarymanager/All#SparkFun_u-blox_GNSS_v3
SFE_UBLOX_GNSS myLBand; // NEO-D9S

Within setup() we then need to start (initialize) communiation with the NEO-D9S. The NEO-D9S has a default I2C address of 0x43 and so we need to provide that when calling the begin method:

language:c
Wire.begin(); //Start I2C

while (myLBand.begin(Wire, 0x43) == false) //Connect to the u-blox NEO-D9S using Wire port. The D9S default I2C address is 0x43 (not 0x42)
{
    Serial.println(F("u-blox NEO-D9S not detected at default I2C address. Please check wiring."));
    delay(2000);
}
Serial.println(F("u-blox NEO-D9S connected"));

The NEO-D9S needs to be configured so it can receive the PointPerfect correction stream. The configuration items are:

Configuration item Default value
CFG-PMP-CENTER_FREQUENCY 1539812500 Hz
CFG-PMP-SEARCH_WINDOW 2200 Hz
CFG-PMP-USE_SERVICE_ID 1 (true)
CFG-PMP-SERVICE_ID 50821
CFG-PMP-DATA_RATE 2400 (B2400) bps
CFG-PMP-USE_DESCRAMBLER 1 (true)
CFG-PMP-DESCRAMBLER_INIT 23560
CFG-PMP-USE_PRESCRAMBLING 0 (false)
CFG-PMP-UNIQUE_WORD 0xe15ae893e15ae893

The centre frequency varies depending on which satellite is broadcasting corrections for your geographical area. The frequency for the USA is different to that for Europe:

The up-to-date frequencies are distributed via the MQTT /pp/frequencies/Lb topic. At the time of writing, they are (in MHz):

language:c
{
  "frequencies": {
    "us": {
      "current": {
        "value": "1556.29"
      }
    },
    "eu": {
      "current": {
        "value": "1545.26"
      }
    }
  }
}

We can add those to the code as follows:

language:c
const uint32_t myLBandFreq = 1556290000; // Uncomment this line to use the US SPARTN 1.8 service
//const uint32_t myLBandFreq = 1545260000; // Uncomment this line to use the EU SPARTN 1.8 service

The code to configure the NEO-D9S is as follows. Note that the UBLOX_CFG_PMP_USE_SERVICE_ID, UBLOX_CFG_PMP_SERVICE_ID and UBLOX_CFG_PMP_DESCRAMBLER_INIT also need to be changed.

language:c
  uint8_t ok = myLBand.setVal32(UBLOX_CFG_PMP_CENTER_FREQUENCY,   myLBandFreq); // Default 1539812500 Hz
  if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_SEARCH_WINDOW,      2200);        // Default 2200 Hz
  if (ok) ok = myLBand.setVal8(UBLOX_CFG_PMP_USE_SERVICE_ID,      0);           // Default 1 
  if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_SERVICE_ID,         21845);       // Default 50821
  if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_DATA_RATE,          2400);        // Default 2400 bps
  if (ok) ok = myLBand.setVal8(UBLOX_CFG_PMP_USE_DESCRAMBLER,     1);           // Default 1
  if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_DESCRAMBLER_INIT,   26969);       // Default 23560
  if (ok) ok = myLBand.setVal8(UBLOX_CFG_PMP_USE_PRESCRAMBLING,   0);           // Default 0
  if (ok) ok = myLBand.setVal64(UBLOX_CFG_PMP_UNIQUE_WORD,        16238547128276412563ull); // 0xE15AE893E15AE893

Finally, we need to ensure that the communication port is set correctly. Let's configure the UART2 port. In order to do that, we need to:

Of course, you could set the NEO-D9S to output the correction data to the other communication ports as well (e.g. in the Arduino Library, correction data was sent via the I2C, UART1, and UART2 ports for example 19). The sample code below configures the NEO-D9S module's UART2 port to pass the correction data.

language:c
  if (ok) ok = myLBand.setVal32(UBLOX_CFG_UART2_BAUDRATE,          38400); // match baudrate with ZED default
  if (ok) ok = myLBand.setVal8(UBLOX_CFG_UART2OUTPROT_UBX,         1);     // Enable UBX output on UART2
  if (ok) ok = myLBand.setVal8(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2, 1);     // Output UBX-RXM-PMP on UART2

  Serial.print(F("L-Band configuration: "));
  if (ok)
    Serial.println(F("OK"));
  else
    Serial.println(F("NOT OK!"));

  myLBand.softwareResetGNSSOnly(); // Do a restart

Once the NEO-D9S has aquired the signal from the satellite, it will start outputting PMP correction messages to the ZED-F9P on UART2.

ZED-F9P Configuration

We need to declare a second SFE_UBLOX_GNSS object for the ZED-F9P. Again, this is done at a global scope (after the include file declaration), not within the setup() or loop() functions.

language:c
SFE_UBLOX_GNSS myGNSS; // ZED-F9P

Within setup() we need to start (initialize) communication with the ZED-F9P:

language:c
  while (myGNSS.begin() == false) //Connect to the u-blox module using Wire port and the default I2C address (0x42)
  {
    Serial.println(F("u-blox GNSS module not detected at default I2C address. Please check wiring."));
    delay(2000);
  }
  Serial.println(F("u-blox GNSS module connected"));

We then need to:

The sample code below configures the ZED-F9P module's UART2 port to accept correction data. Again, you could use the other communication ports as well. Just make sure that the communication ports match the settings that were configured on the NEO-D9S.

language:c
          ok = myGNSS.setUART2Input(COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_SPARTN); //Be sure SPARTN input is enabled
  if (ok) ok = myGNSS.setDGNSSConfiguration(SFE_UBLOX_DGNSS_MODE_FIXED); // Set the differential mode - ambiguities are fixed whenever possible
  if (ok) ok = myGNSS.setVal8(UBLOX_CFG_SPARTN_USE_SOURCE, 1); // use LBAND PMP message

The final piece of the puzzle is to provide the ZED-F9P with the keys it needs to decrypt the encrypted SPARTN (PMP) corrections.

The ZED-F9P can hold two dynamic keys: the current key; and the next key. We also need to tell it when each key is valid from, so it knows when to switch to the next key.

You can find the current and next keys in the Location Services \ Location Things \ Thing Details \ Credentials tab in Thingstream:

L-band Dynamic Keys

PointPerfect L-band dynamic keys. (Click to enlarge)

The ZED-F9P actually needs to know when the keys are valid from, rather than when they expire. Each key is valid for four weeks, so we need to work backwards 4 weeks from the expiry date.

The current key expires at midnight (UTC) at the end of Friday, September 23rd, 2022. This means it became valid 4 weeks earlier at midnight (UTC) on August 27th:

Current Dynamic Key Valid 4 Weeks from Expiry Date Next Dynamic Key Valid from Expiry Date

Dynamic Key: Expiry and Valid From dates. (Click to enlarge)

Using the website recommended in the u-blox Application Note:

http://navigationservices.agi.com/GNSSWeb

we can see that the key became valid during GPS week 2224, at time-of-week 518400.

We can use the Arduino Library setDynamicSPARTNKey method to configure a single key:

language:c
  if (ok) ok = myGNSS.setDynamicSPARTNKey(16, 2224, 518400, "500--------------------------177");

  Serial.print(F("GNSS: configuration "));
  if (ok)
    Serial.println(F("OK"));
  else
    Serial.println(F("NOT OK!"));

Alternately, we can set both the current key and the next key together using setDynamicSPARTNKeys. The next key becomes valid during GPS week 2228:

language:c
  if (ok) ok = myGNSS.setDynamicSPARTNKeys(16, 2224, 518400, "500--------------------------177", 16, 2228, 518400, "582--------------------------a7d");

The keys can also be retrieved using MQTT. We have an Arduino Library example which shows how to retrieve the keys from the L-band + IP key distribution topic /pp/ubx/0236/Lb. That topic provides the keys in UBX (binary) format, ready to be pushed to the ZED.

The keys are also available in human-readable JSON format from the MQTT topic /pp/key/Lb . But note that that topic provides the valid from in Unix epoch format, in milliseconds, excluding the 18 leap seconds since GPS time started!

language:c
{
  "dynamickeys": {
    "current": {
      "start": "1661558382000",
      "duration": "2419199999",
      "value": "500--------------------------177"
    },
    "next": {
      "start": "1663977582000",
      "duration": "2419199999",
      "value": "582--------------------------a7d"
    }
  }
}

NEO-D9S and NEO-D9C > Example 1: NEO-D9S

From the menu, select the following: File > Examples > Examples from Custom Libraries | SparkFun u-blox GNSS v3 > NEO-D9S_and_NEO-D9C > Example1_NEO-D9S.

Adjust for Region

By default the example is set up for the US SPARTN 1.8 service. To adjust for Europe, simply comment out the frequency for the US and uncomment the frequency for the EU at the top of the example code using the syntax for a single line comment (i.e. "//").

language:c
const uint32_t myLBandFreq = 1556290000; // Uncomment this line to use the US SPARTN 1.8 service
//const uint32_t myLBandFreq = 1545260000; // Uncomment this line to use the EU SPARTN 1.8 service

Upload Code

When ready, select the correct board definition from the menu (in this case, Tools > Boards > SparkFun ESP32 IoT RedBoard). Then select the correct COM port that the board enumerated to (in this case, it was COM13). Hit the upload button.

What You Should See

Open the Arduino Serial Monitor at 115200 baud. If all is well, you should see the following output indicating that the UBX-RXM-PMP correction data is being received! In this case, the NEO-D9S had a multiband antenna pointing up towards the sky from SparkFun HQ's rooftop.

Arduino Serial Monitor NEO-D9S and SparkFun ESP32 IoT RedBoard

Click image for a closer view.

NEO-D9S and NEO-D9C > Example 2: L-Band Corrections with NEO-D9S

From the menu, select the following: File > Examples > Examples from Custom Libraries | SparkFun u-blox GNSS_v3 > > NEO-D9S_and_NEO-D9C > Example2_LBand_Corrections_with_NEO-D9S.

Adjust for Region

By default the example is set up for the US SPARTN 1.8 service. To adjust for Europe, simply comment out the frequency for the US and uncomment the frequency for the EU at the top of the example code using the syntax for a single line comment (i.e. "//").

language:c
const uint32_t myLBandFreq = 1556290000; // Uncomment this line to use the US SPARTN 1.8 service
//const uint32_t myLBandFreq = 1545260000; // Uncomment this line to use the EU SPARTN 1.8 service

Add Decryption Keys and Valid Dates

In the secrets.h tab, copy the PointPerfect keys and insert the current (i.e. currentDynamicKey[]) and next keys (i.e. nextDynamicKey[]) between each quote where it says "<ADD YOUR L-Band or L-Band + IP DYNAMIC KEY HERE>". Calculate the current and next key GPS weeks based on the expiry date as stated in the Arduino Library Overview for the ZED-F9P configuration. Then adjust the current and next key dates.

language:c
const uint8_t currentKeyLengthBytes =   16; 
const char currentDynamicKey[] =        "<ADD YOUR L-Band or L-Band + IP DYNAMIC KEY HERE>";
const uint16_t currentKeyGPSWeek =      2245; // Update this when you add new keys
const uint32_t currentKeyGPSToW =       0;

const uint8_t nextKeyLengthBytes =      16; 
const char nextDynamicKey[] =           "<ADD YOUR L-Band or L-Band + IP DYNAMIC KEY HERE>";
const uint16_t nextKeyGPSWeek =         2249; // Update this when you add new keys
const uint32_t nextKeyGPSToW =          0;

Upload Code

When ready, select the correct board definition from the menu (in this case, Tools > Boards > SparkFun ESP32 IoT RedBoard). Then select the correct COM port that the board enumerated to (in this case, it was COM13). Hit the upload button.

What You Should See

Open the Arduino Serial Monitor at 115200 baud. If all is well, you should see the following output indicating that the NEO-D9S received the UBX-RXM-PMP correction data and ZED-F9P has decrypted the data! In this case, the NEO-D9S had a multiband antenna pointing up towards the sky from SparkFun HQ's rooftop. Watch the accuracy converge and decrease to a smaller number. Depending on what satellites are in view, it may take a little time before you reach the RTK floating or fixed solution.

Arduino Serial Monitor NEO-D9S, ZED-F9P, and SparkFun ESP32 IoT RedBoard

Click image for a closer view.

Below is the output once the RTK Fixed Solution was achieved. You will notice that the values converged to a point with a horizontal accuracy of about 20mm.

Arduino Serial Monitor NEO-D9S, ZED-F9P, and SparkFun ESP32 IoT RedBoard - RTK Fixed Solution Acheived

Click image for a closer view.

Troubleshooting

ThingStream PointPerfect L-band Reception

In order to receive the u-blox ThingStream PointPerfect correction data, you will need:

SparkFun GNSS Multi-Band L1/L2 Surveying Antenna - TOP106

We have been successful using the SparkFun GNSS Multi-Band L1/L2 Surveying Antenna (TNC) - TOP106 (GPS-17751) antenna to receive PointPerfect correction data in both the USA and Europe.

GNSS Multi-Band L1/L2 Surveying Antenna - TNC (TOP106)

GNSS Multi-Band L1/L2 Surveying Antenna - TNC (TOP106)

GPS-17751
$133.95
14

Thingstream PointPerfect Coverage

The PointPerfect GNSS augmentation service is available on a continental scale with seamless coverage in Europe and contiguous USA, including up to 12 nautical miles (~ 22 km) off coastlines. u-blox are continuously expanding their coverage according to market demand.

L-Band Coverage

PointPerfect Service Coverage. (Click to enlarge)

As stated earlier, make sure to check back on u-blox's website to see if there is additional coverage in your region. Note that while they recently updated the coverage to support South Korea, it seems to be available over IP only. SPARTN correction messages does not appear to be listed under their topics for L-band reception yet. There are additional regions under consideration for the future but they have not been included yet for L-band reception.

PointPerfect Satellite Broadcast

PointPerfect augmentation data is broadcast from satellites covering Europe and contiguous USA. The satellites are in geostationary orbits over the equator - the same as for satellite television broadcasts. It is essential that your antenna has an unobstructed view of the sky, especially to the South where the satellite is positioned.

Depending on your latitude, the satellite for your area could be low in the sky. You need to ensure that trees, buildings etc. are not blocking the signal.

Resources and Going Further

Now that you've successfully got your NEO-D9S up and running, it's time to incorporate it into your own project! Need more information? Check out some of the links below:

SparkFun Resources

u-blox Resources

If you are looking for a more integrated solution, try checking out the RTK Facet L-Band! The RTK Facet L-Band includes the NEO-D9S, ZED-F9P, and ESP32 WROOM in a sweet enclosure. Additionally, the product includes several hardware features such as a built-in LiPo battery, charging circuit, microOLED, L1/L2/L-Band antenna, microSD card socket for datalogging, fuel gauge, accelerometer, and serial ports. The build in software features also make it user friendly. It does not require copy and pasting of keys, certificates, or any other materials. By connecting the RTK Facet L-Band to a WiFi network, the keys will be automatically be updated and stored. There are also five different modes available. Everything is built into one unit and it was made to be as easy as possible to use.

SparkFun RTK Facet L-Band Hookup Guide

June 9, 2022

Setup the RTK Facet L-Band in minutes to begin gathering millimeter level geospatial coordinates.

Need some inspiration for your next project? Check out some of these related tutorials related to GNSS.

ESP32 Thing Motion Shield Hookup Guide

Getting started with the ESP32 Thing Motion Shield to detect movements using the on-board LSM9DS1 IMU and adding a GPS receiver. Data can be easily logged by adding an microSD card to the slot.

What is GPS RTK?

Learn about the latest generation of GPS and GNSS receivers to get 14mm positional accuracy!

nRF9160 Thing Plus Hookup Guide

Getting started with the nRF9160 from Circuit Dojo and SparkFun!

SparkFun RTK Facet Hookup Guide

Setup the RTK Facet in minutes to begin gathering millimeter level geospatial coordinates.

learn.sparkfun.com | CC BY-SA 3.0 | SparkFun Electronics | Niwot, Colorado