Prerequisites for this solution to work (alternatives to some of these items may work, but it is up to you to test them out!):
- simpleRTK2B (sold by digikey or ardusimple)
- A high quality sma to tnc cable such is this one https://www.digikey.ca/en/products/detail/siretta-ltd/asmzg500a058l13/6096481
- a Calibrated survey GNSS Tripleband+Lband antenna(IP67) or equivalent (sold by ardusimple, digikey, mouser etc.) or a gnss antenna + a dedicated antenna for l-band
- u.fl to sma cable
- PointPerfect L-Band Corrections Receiver NEO-D9S (sold by ardusimple)
- A personal computer with the latest AGOPENGPS and AGIO software installed as well as a working ethernet port.
- Teensy 4.1
- HPG firmware version 1.32 for u-blox f9p module
- AOG 4.1 firmware (Autosteer_gps_teensy_v4_1.ino)
- Arduino IDE 1.8.19
- AiO 4.1/4.2 PCB or equivalent
- You live/work in a geographic area which offers the PointPerfect service (please refer to the official ublox site for details)
- You have been given permission by ublox to use the service
- A clear unobstructed view of the southern sky
- a thingstream account with a subscription to the pointperfect L-band service
- 1.32 SingleAntennaRover.txt (firmware for F9p. Further modifications for enabling lband service must be made to the f9p by using the ucenter program. See PointPerfect L-band Configuration for instructions on that.)
- The SparkFun u-blox GNSS Arduino Library - v3 installed via the Arduino IDE
https://github.com/sparkfun/SparkFun_u-blox_GNSS_v3
- In the same directory as the
Autosteer_gps_teensy_v4_1.ino
file, create a new header file calledsecrets.h
and insert the following code to the file:
// You can set the information below after signing up with the u-blox Thingstream portal
// and adding a new New PointPerfect Thing (L-Band or L-Band + IP)
// https://portal.thingstream.io/app/location-services/things
// In the new PointPerfect Thing, you go to the credentials tab and copy and paste the IP Dynamic Keys here.
//
// The keys are valid from a particular GPS Week Number and Time of Week.
// Looking at the credentials tab, the current key expires 23:59 Feb 11th 2022.
// This means the next key is valid _from_ Midnight Feb 12th 2022.
// That is GPS Week 2196. The GPS Time of Week in seconds is 518400.
// Working backwards, the current key became valid exactly 4 weeks earlier (Midnight Jan 15th 2022).
//
// See: https://www.labsat.co.uk/index.php/en/gps-time-calculator
//
// The keys are given as: 32 hexadecimal digits = 128 bits = 16 Bytes
//
// The next example shows how to retrieve the keys using ESP32 WiFi and MQTT.
// You can cut and paste the keys and GPS week/time-of-week from that example into here.
const uint8_t currentKeyLengthBytes = 16;
const char currentDynamicKey[] = "<ADD YOUR L-Band or L-Band + IP DYNAMIC KEY HERE>";
const uint16_t currentKeyGPSWeek = 2254; // 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 = 2258; // Update this when you add new keys
const uint32_t nextKeyGPSToW = 0;
Add your secret credentials to the appropriate places in the file and then save the file. The steps on getting these credentials is beyond the scope of this tutorial. Please browse the ublox documentation for more information on how to acquire the keys.
- Add the following 3 statements somewhere at the top but after the first initial comments of the
Autosteer_gps_teensy_v4_1.ino
file
#include "secrets.h"
#include <SparkFun_u-blox_GNSS_v3.h>
SFE_UBLOX_GNSS_SERIAL myGNSS;
- Within the same file under the Serial port comment, add the following definition:
#define mySerial Serial7
- To avoid any errors during compilation, make sure to change the name of ubxPacket struct definition to something unique so that it does not conflict with the ubxPacket struct definition originating from the Sparkfun GNSS v3 header file. I renamed it to ubxPacket2, but you can rename it anything youâd like:
struct ubxPacket2
{
uint8_t cls;
uint8_t id;
uint16_t len; //Length of the payload. Does not include cls, id, or checksum bytes
uint16_t counter; //Keeps track of number of overall bytes received. Some responses are larger than 255 bytes.
uint16_t startingSpot; //The counter value needed to go past before we begin recording into payload array
uint8_t *payload; // We will allocate RAM for the payload if/when needed.
uint8_t checksumA; //Given to us from module. Checked against the rolling calculated A/B checksums.
uint8_t checksumB;
////sfe_ublox_packet_validity_e valid; //Goes from NOT_DEFINED to VALID or NOT_VALID when checksum is checked
////sfe_ublox_packet_validity_e classAndIDmatch; // Goes from NOT_DEFINED to VALID or NOT_VALID when the Class and ID match the requestedClass and requestedID
};
-
MAKE SURE to find all instances of ubxPacket in
Autosteer_gps_teensy_v4_1.ino
and replace it with the unique name you gave the ubxPacket struct in step 4. -
Add following code just below the
delay(10)
line which is just afterSerial.begin(baudAOG)
in theAutosteer_gps_teensy_v4_1.ino
file:
mySerial.begin(460800);
delay(5000);
Serial.println("F9P LBand Key Insertion");
while (myGNSS.begin(mySerial) == false) //Connect to the u-blox module using Serial
{
Serial.println(F("u-blox GNSS module not detected. Please check wiring."));
delay(10);
}
Serial.println(F("u-blox GNSS module connected"));
uint8_t ok = myGNSS.setDynamicSPARTNKeys(currentKeyLengthBytes, currentKeyGPSWeek, currentKeyGPSToW, currentDynamicKey,nextKeyLengthBytes, nextKeyGPSWeek, nextKeyGPSToW, nextDynamicKey);
Serial.print(F("GNSS: configuration "));
Serial.println(OK(ok));
delay(100);
myGNSS.end();
-
Once you have made the code changes above, save the file, re-compile the code and finally upload it to the teensy 4.1.
-
Connect your hardware to the AiO 4.1/4.2 board and then apply power to the AiO 4.1/4.2 board.
-
If everything is configured properly, you should eventually see an RTK fix in under a minute using the AGOPENGPS UI on your personal computer connected to the system via ethernet cable. I can confirm this is working on my own system.
IMPORTANT TO NOTE: the dynamic keys expire every 28 days. You are given two dynamic keys, so this fix should work unimpeded for a maximum time of 56 days. After day 56 you will have to edit the secrets.h
with your newly updated dynamic keys. This should be a sufficient time window for anyone using it for agricultural purposes.
Lastly, keep in mind this is just a quick hack to integrating this service into the AgOpenGPS ecosystem. By no means is this the best fix, but it should allow someone who is more skilled at programming and has a better understanding of the code base to come up with something that might be worth incorporating to the official repository. Changes to the UI for dynamic key management would be a nice addition as well!
Hope this helps!
Have a happy new year everyone!
Blockquote