Skip to content

v3.1.0 #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
fc9cf8e
Add PMP-over-Serial and SPARTN-over-Serial examples
PaulZC Oct 9, 2023
24c53b5
Delete obsolete keys files
PaulZC Nov 24, 2023
0e99d30
Update keys for PMP 1.04
PaulZC Nov 24, 2023
7197362
Add keys for D9 QZS
PaulZC Nov 24, 2023
b72768f
Add keys for HPG L1/L5
PaulZC Nov 24, 2023
ef0c177
Extra keys for HPS 1.30
PaulZC Nov 24, 2023
602b301
Add keys for TIM 2.20 (ZED_F9T)
PaulZC Nov 24, 2023
3fa46e0
Add extra keys for NEO-F10
PaulZC Nov 24, 2023
e39502a
Create u-blox-F9-HPG-1.32_InterfaceDescription_UBX-22008968_keys_sort…
PaulZC Nov 24, 2023
cf3fb33
Add key for NEO-F10N GPS L5 health override
PaulZC Nov 24, 2023
94b372f
Update u-blox_Class_and_ID.h
PaulZC Nov 24, 2023
e87a2b2
Add helper methods for NEO-F10N LNA mode and L5 health
PaulZC Nov 24, 2023
a484e4d
v3.0.17
PaulZC Nov 24, 2023
165e98a
Add NEO-F10N RAWX example with L5
PaulZC Nov 24, 2023
fda2568
Add code safety comments for methods that could return junk if the ge…
PaulZC Dec 2, 2023
2c588e6
Add more SPARTN and PMP to Serial examples
PaulZC Dec 15, 2023
bfd03a7
Add support for multiple SFRBX message callbacks - for the PointPerfe…
PaulZC Dec 18, 2023
027040c
Default to US frequency
PaulZC Dec 19, 2023
c5d088d
Add storage for multiple SFRBX data callbacks
PaulZC Dec 19, 2023
d57720f
Update keywords.txt
PaulZC Dec 19, 2023
b2e44ea
Add storage for multiple ESF MEAS callback copies
PaulZC Dec 19, 2023
249113e
Create CallbackExample7_ESF_MEAS.ino
PaulZC Dec 19, 2023
005b565
Bump to v3.1.0
PaulZC Dec 19, 2023
10dbb36
Move parseSPARTN into the library
PaulZC Dec 19, 2023
79b665f
SPARTN debug prints
PaulZC Dec 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/*
u-blox Example: ESF MEAS (Wheel Ticks)
By: Paul Clark
SparkFun Electronics
Date: December 19th, 2023
License: MIT. See license file for more information

This example configures the External Sensor Fusion MEAS sensor messages on the ZED-F9R and
shows how to access the ESF data using callbacks.

Feel like supporting open source hardware?
Buy a board from SparkFun!
ZED-F9R: https://www.sparkfun.com/products/22660

Hardware Connections:
Plug a Qwiic cable into the GPS and a Redboard Qwiic
If you don't have a platform with a Qwiic connection use the
SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)

Open the serial monitor at >>> 230400 <<< baud to see the output

*/

#include <Wire.h> //Needed for I2C to GPS

#include <SparkFun_u-blox_GNSS_v3.h> //http://librarymanager/All#SparkFun_u-blox_GNSS_v3
SFE_UBLOX_GNSS myGNSS;

// Callback: printESFMEASdata will be called when new ESF MEAS data arrives
// See u-blox_structs.h for the full definition of UBX_ESF_MEAS_data_t
// _____ You can use any name you like for the callback. Use the same name when you call setAutoESFMEAScallback
// / _____ This _must_ be UBX_ESF_MEAS_data_t
// | / _____ You can use any name you like for the struct
// | | /
// | | |
void printESFMEASdata(UBX_ESF_MEAS_data_t *ubxDataStruct)
{
// New ESF MEAS data has arrived:

// Print the timeTag
Serial.print(F("Time: "));
Serial.println(ubxDataStruct->timeTag);

// ubxDataStruct->flags.bits.numMeas indicates how many sensor groups the UBX_ESF_MEAS_data_t contains.
for (uint8_t i = 0; i < ubxDataStruct->flags.bits.numMeas; i++)
{
// Print the sensor data type
// From the M8 interface description:
// 0: None
// 1-4: Reserved
// 5: z-axis gyroscope angular rate deg/s * 2^-12 signed
// 6: front-left wheel ticks: Bits 0-22: unsigned tick value. Bit 23: direction indicator (0=forward, 1=backward)
// 7: front-right wheel ticks: Bits 0-22: unsigned tick value. Bit 23: direction indicator (0=forward, 1=backward)
// 8: rear-left wheel ticks: Bits 0-22: unsigned tick value. Bit 23: direction indicator (0=forward, 1=backward)
// 9: rear-right wheel ticks: Bits 0-22: unsigned tick value. Bit 23: direction indicator (0=forward, 1=backward)
// 10: speed ticks: Bits 0-22: unsigned tick value. Bit 23: direction indicator (0=forward, 1=backward)
// 11: speed m/s * 1e-3 signed
// 12: gyroscope temperature deg Celsius * 1e-2 signed
// 13: y-axis gyroscope angular rate deg/s * 2^-12 signed
// 14: x-axis gyroscope angular rate deg/s * 2^-12 signed
// 16: x-axis accelerometer specific force m/s^2 * 2^-10 signed
// 17: y-axis accelerometer specific force m/s^2 * 2^-10 signed
// 18: z-axis accelerometer specific force m/s^2 * 2^-10 signed
switch (ubxDataStruct->data[i].data.bits.dataType)
{
case 5:
Serial.print(F("Z Gyro: "));
break;
case 6:
Serial.print(F("Front Left: "));
break;
case 7:
Serial.print(F("Front Right: "));
break;
case 8:
Serial.print(F("Rear Left: "));
break;
case 9:
Serial.print(F("Rear Right: "));
break;
case 10:
Serial.print(F("Speed Ticks: "));
break;
case 11:
Serial.print(F("Speed: "));
break;
case 12:
Serial.print(F("Temp: "));
break;
case 13:
Serial.print(F("Y Gyro: "));
break;
case 14:
Serial.print(F("X Gyro: "));
break;
case 16:
Serial.print(F("X Accel: "));
break;
case 17:
Serial.print(F("Y Accel: "));
break;
case 18:
Serial.print(F("Z Accel: "));
break;
default:
break;
}

// Tick data
if ((ubxDataStruct->data[i].data.bits.dataType >= 6) && (ubxDataStruct->data[i].data.bits.dataType <= 10))
{
if ((ubxDataStruct->data[i].data.bits.dataField & (1 << 23)) > 0)
Serial.print(F("-")); // Backward
else
Serial.print(F("+")); // Forward
Serial.println(ubxDataStruct->data[i].data.bits.dataField & 0x007FFFFF);
}
// Speed
else if (ubxDataStruct->data[i].data.bits.dataType == 11)
{
union
{
int32_t signed32;
uint32_t unsigned32;
} signedUnsigned; // Avoid any ambiguity casting uint32_t to int32_t
// The dataField is 24-bit signed, stored in the 24 LSBs of a uint32_t
signedUnsigned.unsigned32 = ubxDataStruct->data[i].data.bits.dataField << 8; // Shift left by 8 bits to correctly align the data
float speed = signedUnsigned.signed32; // Extract the signed data. Convert to float
speed /= 256.0; // Divide by 256 to undo the shift
speed *= 0.001; // Convert from m/s * 1e-3 to m/s
Serial.println(speed, 3);
}
// Gyro data
else if ((ubxDataStruct->data[i].data.bits.dataType == 5) || (ubxDataStruct->data[i].data.bits.dataType == 13) || (ubxDataStruct->data[i].data.bits.dataType == 14))
{
union
{
int32_t signed32;
uint32_t unsigned32;
} signedUnsigned; // Avoid any ambiguity casting uint32_t to int32_t
// The dataField is 24-bit signed, stored in the 24 LSBs of a uint32_t
signedUnsigned.unsigned32 = ubxDataStruct->data[i].data.bits.dataField << 8; // Shift left by 8 bits to correctly align the data
float rate = signedUnsigned.signed32; // Extract the signed data. Convert to float
rate /= 256.0; // Divide by 256 to undo the shift
rate *= 0.000244140625; // Convert from deg/s * 2^-12 to deg/s
Serial.println(rate);
}
// Accelerometer data
else if ((ubxDataStruct->data[i].data.bits.dataType == 16) || (ubxDataStruct->data[i].data.bits.dataType == 17) || (ubxDataStruct->data[i].data.bits.dataType == 18))
{
union
{
int32_t signed32;
uint32_t unsigned32;
} signedUnsigned; // Avoid any ambiguity casting uint32_t to int32_t
// The dataField is 24-bit signed, stored in the 24 LSBs of a uint32_t
signedUnsigned.unsigned32 = ubxDataStruct->data[i].data.bits.dataField << 8; // Shift left by 8 bits to correctly align the data
float force = signedUnsigned.signed32; // Extract the signed data. Convert to float
force /= 256.0; // Divide by 256 to undo the shift
force *= 0.0009765625; // Convert from m/s^2 * 2^-10 to m/s^2
Serial.println(force);
}
// Gyro Temperature
else if (ubxDataStruct->data[i].data.bits.dataType == 12)
{
union
{
int32_t signed32;
uint32_t unsigned32;
} signedUnsigned; // Avoid any ambiguity casting uint32_t to int32_t
// The dataField is 24-bit signed, stored in the 24 LSBs of a uint32_t
signedUnsigned.unsigned32 = ubxDataStruct->data[i].data.bits.dataField << 8; // Shift left by 8 bits to correctly align the data
float temperature = signedUnsigned.signed32; // Extract the signed data. Convert to float
temperature /= 256.0; // Divide by 256 to undo the shift
temperature *= 0.01; // Convert from C * 1e-2 to C
Serial.println(temperature);
}
}
}

void setup()
{
Serial.begin(230400); // <-- Use a fast baud rate to avoid the Serial prints slowing the code

while (!Serial)
; // Wait for user to open terminal
Serial.println(F("SparkFun u-blox Example"));

Wire.begin();
Wire.setClock(400000); // <-- Use 400kHz I2C

// myGNSS.enableDebugging(); // Uncomment this line to enable debug messages on Serial

if (myGNSS.begin() == false) // Connect to the u-blox module using Wire port
{
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
while (1)
;
}

myGNSS.setI2COutput(COM_TYPE_UBX); // Set the I2C port to output UBX only (turn off NMEA noise)
myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); // Save (only) the communications port settings to flash and BBR

if (myGNSS.setAutoESFMEAScallbackPtr(&printESFMEASdata) == true) // Enable automatic ESF MEAS messages with callback to printESFMEASdata
Serial.println(F("setAutoESFMEAScallback successful"));
}

void loop()
{
myGNSS.checkUblox(); // Check for the arrival of new data and process it.
myGNSS.checkCallbacks(); // Check if any callbacks are waiting to be processed.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
Use the NEO-D9S L-Band receiver to provide corrections as PMP over Serial
By: SparkFun Electronics / Paul Clark
Based on original code by: u-blox AG / Michael Ammann
v3 updates: Decembe 22nd, 2022
License: MIT. See license file for more information.

This example shows how to obtain PMP correction data from a NEO-D9S L-Band receiver and push it over Serial (UART).

Feel like supporting open source hardware?
Buy a board from SparkFun!
ZED-F9P RTK2: https://www.sparkfun.com/products/16481
NEO-D9S: https://www.sparkfun.com/products/19390
Combo Board: https://www.sparkfun.com/products/20167

Hardware Connections:
Use a Qwiic cable to connect the NEO-D9S to your board
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
Open the serial monitor at 115200 baud to see the output
*/

#include <driver/uart.h> //Required for uart_set_rx_full_threshold() on cores <v2.0.5
HardwareSerial serialGNSS(2); // TX on 17, RX on 16

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

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

#define OK(ok) (ok ? F(" -> OK") : F(" -> ERROR!")) // Convert uint8_t into OK/ERROR

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

// Callback: pushRXMPMP will be called when new PMP data arrives
// See u-blox_structs.h for the full definition of UBX_RXM_PMP_message_data_t
// _____ You can use any name you like for the callback. Use the same name when you call setRXMPMPmessageCallbackPtr
// / _____ This _must_ be UBX_RXM_PMP_message_data_t
// | / _____ You can use any name you like for the struct
// | | /
// | | |
void pushRXMPMP(UBX_RXM_PMP_message_data_t *pmpData)
{
//Extract the raw message payload length
uint16_t payloadLen = ((uint16_t)pmpData->lengthMSB << 8) | (uint16_t)pmpData->lengthLSB;

uint16_t numBytesUserData = pmpData->payload[2] | ((uint16_t)pmpData->payload[3] << 8);
uint16_t fecBits = pmpData->payload[20] | ((uint16_t)pmpData->payload[21] << 8);
float ebno = (float)pmpData->payload[22] / 8;

Serial.print(F("New RXM-PMP data received. userData: "));
Serial.print(numBytesUserData);
Serial.print(F(" Bytes. fecBits: "));
Serial.print(fecBits);
Serial.print(F(". ebno (dB): "));
Serial.print(ebno);
Serial.println(F("."));

Serial.println(F("Pushing PMP to Serial..."));

serialGNSS.write(&pmpData->payload[24], (size_t)numBytesUserData); // Push only the raw PMP userData
(void)payloadLen;

//serialGNSS.write(&pmpData->sync1, (size_t)payloadLen + 6); // Push the sync chars, class, ID, length and payload
//serialGNSS.write(&pmpData->checksumA, (size_t)2); // Push the checksum bytes
}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void setup()
{
delay(1000);

Serial.begin(115200);
Serial.println(F("NEO-D9S SPARTN Corrections"));

serialGNSS.begin(38400); // UART2 on pins 16/17.

Wire.begin(); //Start I2C

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Begin and configure the NEO-D9S L-Band receiver

//myLBand.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial

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"));

myLBand.newCfgValset(); // Create a new Configuration Interface message - this defaults to VAL_LAYER_RAM_BBR (change in RAM and BBR)
myLBand.addCfgValset(UBLOX_CFG_PMP_CENTER_FREQUENCY, myLBandFreq); // Default 1539812500 Hz
myLBand.addCfgValset(UBLOX_CFG_PMP_SEARCH_WINDOW, 2200); // Default 2200 Hz
myLBand.addCfgValset(UBLOX_CFG_PMP_USE_SERVICE_ID, 0); // Default 1
myLBand.addCfgValset(UBLOX_CFG_PMP_SERVICE_ID, 21845); // Default 50821
myLBand.addCfgValset(UBLOX_CFG_PMP_DATA_RATE, 2400); // Default 2400 bps
myLBand.addCfgValset(UBLOX_CFG_PMP_USE_DESCRAMBLER, 1); // Default 1
myLBand.addCfgValset(UBLOX_CFG_PMP_DESCRAMBLER_INIT, 26969); // Default 23560
myLBand.addCfgValset(UBLOX_CFG_PMP_USE_PRESCRAMBLING, 0); // Default 0
myLBand.addCfgValset(UBLOX_CFG_PMP_UNIQUE_WORD, 16238547128276412563ull);
myLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 1); // Ensure UBX-RXM-PMP is enabled on the I2C port
myLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART1, 1); // Output UBX-RXM-PMP on UART1
myLBand.addCfgValset(UBLOX_CFG_UART2OUTPROT_UBX, 1); // Enable UBX output on UART2
myLBand.addCfgValset(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2, 1); // Output UBX-RXM-PMP on UART2
myLBand.addCfgValset(UBLOX_CFG_UART1_BAUDRATE, 38400); // match baudrate with ZED default
myLBand.addCfgValset(UBLOX_CFG_UART2_BAUDRATE, 38400); // match baudrate with ZED default
bool ok = myLBand.sendCfgValset(); // Apply the settings

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

myLBand.softwareResetGNSSOnly(); // Do a restart

myLBand.setRXMPMPmessageCallbackPtr(&pushRXMPMP); // Call pushRXMPMP when new PMP data arrives. Push it to the GNSS

}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void loop()
{
myLBand.checkUblox(); // Check for the arrival of new PMP data and process it.
myLBand.checkCallbacks(); // Check if any LBand callbacks are waiting to be processed.
}
Loading