Skip to content

Version 2.2.22 #186

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 3 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Expand Up @@ -2,9 +2,8 @@
Configuring the GNSS to automatically send odometer reports over I2C and display the data using a callback
By: Paul Clark
SparkFun Electronics
Date: December 30th, 2020
License: MIT. See license file for more information but you can
basically do whatever you want with this code.
Date: March 20th, 2023
License: MIT. See license file for more information.

This example shows how to configure the u-blox GNSS to send odometer reports automatically
and display the data via a callback. No more polling!
Expand Down Expand Up @@ -55,6 +54,8 @@ void printODOdata(UBX_NAV_ODO_data_t *ubxDataStruct)

void setup()
{
delay(1000);

Serial.begin(115200);
while (!Serial); //Wait for user to open terminal
Serial.println("SparkFun u-blox Example");
Expand All @@ -63,17 +64,37 @@ void setup()

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

if (myGNSS.begin() == false) //Connect to the u-blox module using Wire port
while (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);
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring."));
}

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

myGNSS.setNavigationFrequency(1); //Produce one solution per second

//By default, the odometer is disabled. We need to enable it.
//We can enable it using the default settings:
myGNSS.enableOdometer();

//Or we can configure it using our own settings, by performing a read-modify-write:
uint8_t flags; // Odometer/Low-speed COG filter flags
uint8_t odoCfg; // Odometer filter settings
uint8_t cogMaxSpeed; // Speed below which course-over-ground (COG) is computed with the low-speed COG filter : m/s * 0.1
uint8_t cogMaxPosAcc; // Maximum acceptable position accuracy for computing COG with the low-speed COG filter
uint8_t velLpGain; // Velocity low-pass filter level
uint8_t cogLpGain; // COG low-pass filter level

if (myGNSS.getOdometerConfig(&flags, &odoCfg, &cogMaxSpeed, &cogMaxPosAcc, &velLpGain, &cogLpGain))
{
flags = UBX_CFG_ODO_USE_ODO; // Enable the odometer
odoCfg = UBX_CFG_ODO_CAR; // Use the car profile (others are RUN, CYCLE, SWIM, CUSTOM)
myGNSS.setOdometerConfig(flags, odoCfg, cogMaxSpeed, cogMaxPosAcc, velLpGain, cogLpGain); // Set the configuration
}
else
Serial.println("Could not read odometer config!");

//myGNSS.resetOdometer(); //Uncomment this line to reset the odometer

myGNSS.setAutoNAVODOcallbackPtr(&printODOdata); // Enable automatic NAV ODO messages with callback to printODOdata
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
Configure the NEO-M8P-2 as a "moving base"
By: Paul Clark
SparkFun Electronics
Date: March 20th, 2023
License: MIT. See license file for more information.

This example configures the NEO-M8P-2 as a moving base.
It will output RTCM3 1077, 1087, 1230 and 4072.0 messages on UART1.
Connect UART1 TX to UART1 RX on a NEO-M8P rover. Also connect GND to GND.
The next example shows how to display the relative position of the rover.

Feel like supporting open source hardware?
Buy a board from SparkFun!
NEO-M8P RTK: https://www.sparkfun.com/products/15005

Hardware Connections:
Plug a Qwiic cable into the GNSS and a BlackBoard
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
Connect UART1 TX to UART1 RX on a NEO-M8P rover. Also connect GND to GND.
Open the serial monitor at 115200 baud to see the output
*/

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

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

void setup()
{
delay(1000);

Serial.begin(115200);
while(!Serial); //Wait for user to open terminal
Serial.println(F("u-blox NEO-M8P Moving Base Example"));

Wire.begin();

while (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."));
}

// Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
//myGNSS.factoryDefault(); delay(5000);

myGNSS.setUART1Output(COM_TYPE_RTCM3); // Configure UART1 to output RTCM3 only. Disable NMEA.
myGNSS.saveConfiguration(); //Save the current settings to flash and BBR

bool response = true;

response &= myGNSS.enableRTCMmessage(UBX_RTCM_1077, COM_PORT_UART1, 1); //Enable message 1077 on UART1
response &= myGNSS.enableRTCMmessage(UBX_RTCM_1087, COM_PORT_UART1, 1); //Enable message 1087 on UART1
response &= myGNSS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_UART1, 1); //Enable message 1230 on UART1
response &= myGNSS.enableRTCMmessage(UBX_RTCM_4072_0, COM_PORT_UART1, 1); //Enable message 4072.0 on UART1

response &= myGNSS.disableSurveyMode(); //Essential - we need to set TMODE3 to Disabled to allow 4072.0 to be output

if (response == true)
{
Serial.println(F("RTCM messages enabled"));
}
else
{
Serial.println(F("RTCM failed to enable. Are you sure you have an NEO-M8P?"));
}
}

void loop()
{
myGNSS.checkUblox(); //See if new data is available. Process bytes as they come in.

delay(250); //Don't pound too hard on the I2C bus
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
Display the relative position of a NEO-M8P-2 rover
By: Paul Clark
SparkFun Electronics
Date: March 20th, 2023
License: MIT. See license file for more information.

This example shows how to query the module for RELPOS information in the NED frame.
It assumes you already have RTCM correction data being fed to the receiver on UART1.
Connect UART1 TX on the base to UART1 RX on the rover. Also connect GND to GND.

Feel like supporting open source hardware?
Buy a board from SparkFun!
NEO-M8P RTK: https://www.sparkfun.com/products/15005

Hardware Connections:
Plug a Qwiic cable into the GNSS and a RedBoard Qwiic or BlackBoard
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
Connect UART1 TX on the base to UART1 RX on the rover. Also connect GND to GND.
Open the serial monitor at 115200 baud to see the output
*/

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

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

void setup()
{
delay(1000);

Serial.begin(115200);
while (!Serial); //Wait for user to open terminal
Serial.println("u-blox NEO-M8P Rover Example");

Wire.begin();

while (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."));
}

// Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
//myGNSS.factoryDefault(); delay(5000);

// By default, UART1 Protocol In is set to NMEA + UBX + RTCM3. No changes are necessary. But we can manually configure the port if required.
Serial.print(myGNSS.setPortInput(COM_PORT_UART1, COM_TYPE_UBX | COM_TYPE_RTCM3)); //Enable UBX and RTCM3 input on UART1
myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save the communications port settings to flash and BBR
}

void loop()
{
// The data from getRELPOSNED (UBX-NAV-RELPOSNED) is returned in UBX_NAV_RELPOSNED_t packetUBXNAVRELPOSNED
// Please see u-blox_structs.h for the full definition of UBX_NAV_RELPOSNED_t
// You can either read the data from packetUBXNAVRELPOSNED directly
// or can use the helper functions: getRelPosN/E/D; getRelPosAccN/E/D
// Note that NEO-M8P RELPOSNED is different to ZED-F9P. It does not contain the relative length and heading.
if (myGNSS.getRELPOSNED() == true)
{
Serial.print("relPosN: ");
Serial.println(myGNSS.getRelPosN(), 4); // Use the helper functions to get the rel. pos. as m
Serial.print("relPosE: ");
Serial.println(myGNSS.getRelPosE(), 4);
Serial.print("relPosD: ");
Serial.println(myGNSS.getRelPosD(), 4);

Serial.print("relPosHPN: ");
Serial.println((float)myGNSS.packetUBXNAVRELPOSNED->data.relPosHPN / 10, 1); //High-precision component. Convert to mm
Serial.print("relPosHPE: ");
Serial.println((float)myGNSS.packetUBXNAVRELPOSNED->data.relPosHPE / 10, 1);
Serial.print("relPosHPD: ");
Serial.println((float)myGNSS.packetUBXNAVRELPOSNED->data.relPosHPD / 10, 1);

Serial.print("accN: ");
Serial.println(myGNSS.getRelPosAccN(), 4); // Use the helper functions to get the rel. pos. accuracy as m
Serial.print("accE: ");
Serial.println(myGNSS.getRelPosAccE(), 4);
Serial.print("accD: ");
Serial.println(myGNSS.getRelPosAccD(), 4);

Serial.print("gnssFixOk: ");
if (myGNSS.packetUBXNAVRELPOSNED->data.flags.bits.gnssFixOK == true)
Serial.println("x");
else
Serial.println("");

Serial.print("diffSolution: ");
if (myGNSS.packetUBXNAVRELPOSNED->data.flags.bits.diffSoln == true)
Serial.println("x");
else
Serial.println("");

Serial.print("relPosValid: ");
if (myGNSS.packetUBXNAVRELPOSNED->data.flags.bits.relPosValid == true)
Serial.println("x");
else
Serial.println("");

Serial.print("carrier Solution Type: ");
if (myGNSS.packetUBXNAVRELPOSNED->data.flags.bits.carrSoln == 0)
Serial.println("None");
else if (myGNSS.packetUBXNAVRELPOSNED->data.flags.bits.carrSoln == 1)
Serial.println("Float");
else if (myGNSS.packetUBXNAVRELPOSNED->data.flags.bits.carrSoln == 2)
Serial.println("Fixed");

Serial.print("isMoving: ");
if (myGNSS.packetUBXNAVRELPOSNED->data.flags.bits.isMoving == true)
Serial.println("x");
else
Serial.println("");
}
else
Serial.println("RELPOS request failed");

Serial.println("");
}
14 changes: 14 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ setDynamicModel KEYWORD2
getDynamicModel KEYWORD2

resetOdometer KEYWORD2
enableOdometer KEYWORD2
getOdometerConfig KEYWORD2
setOdometerConfig KEYWORD2

enableGNSS KEYWORD2
isGNSSenabled KEYWORD2
Expand Down Expand Up @@ -831,6 +834,17 @@ VAL_CFG_SUBSEC_ANTCONF LITERAL1
VAL_CFG_SUBSEC_LOGCONF LITERAL1
VAL_CFG_SUBSEC_FTSCONF LITERAL1

UBX_CFG_ODO_USE_ODO LITERAL1
UBX_CFG_ODO_USE_COG LITERAL1
UBX_CFG_ODO_OUT_LP_VEL LITERAL1
UBX_CFG_ODO_OUT_LP_COG LITERAL1

UBX_CFG_ODO_RUN LITERAL1
UBX_CFG_ODO_CYCLE LITERAL1
UBX_CFG_ODO_SWIM LITERAL1
UBX_CFG_ODO_CAR LITERAL1
UBX_CFG_ODO_CUSTOM LITERAL1

DYN_MODEL_PORTABLE LITERAL1
DYN_MODEL_STATIONARY LITERAL1
DYN_MODEL_PEDESTRIAN LITERAL1
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=SparkFun u-blox GNSS Arduino Library
version=2.2.21
version=2.2.22
author=SparkFun Electronics <[email protected]>
maintainer=SparkFun Electronics <sparkfun.com>
sentence=Library for I2C, Serial and SPI Communication with u-blox GNSS modules<br/><br/>
Expand Down
66 changes: 66 additions & 0 deletions src/SparkFun_u-blox_GNSS_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8207,6 +8207,70 @@ bool SFE_UBLOX_GNSS::resetOdometer(uint16_t maxWait)
return (sendCommand(&packetCfg, maxWait, true) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
}

// Enable / disable the odometer
bool SFE_UBLOX_GNSS::enableOdometer(bool enable, uint16_t maxWait)
{
packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_ODO;
packetCfg.len = 0;
packetCfg.startingSpot = 0;

// Ask module for the current odometer configuration. Loads into payloadCfg.
if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK
return (false);

if (enable)
payloadCfg[4] = payloadCfg[4] | UBX_CFG_ODO_USE_ODO;
else
payloadCfg[4] = payloadCfg[4] & ~UBX_CFG_ODO_USE_ODO;

return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
}

// Read the odometer configuration
bool SFE_UBLOX_GNSS::getOdometerConfig(uint8_t *flags, uint8_t *odoCfg, uint8_t *cogMaxSpeed, uint8_t *cogMaxPosAcc, uint8_t *velLpGain, uint8_t *cogLpGain, uint16_t maxWait)
{
packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_ODO;
packetCfg.len = 0;
packetCfg.startingSpot = 0;

// Ask module for the current odometer configuration. Loads into payloadCfg.
if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK
return (false);

*flags = payloadCfg[4];
*odoCfg = payloadCfg[5];
*cogMaxSpeed = payloadCfg[12];
*cogMaxPosAcc = payloadCfg[13];
*velLpGain = payloadCfg[16];
*cogLpGain = payloadCfg[17];

return true;
}

// Configure the odometer
bool SFE_UBLOX_GNSS::setOdometerConfig(uint8_t flags, uint8_t odoCfg, uint8_t cogMaxSpeed, uint8_t cogMaxPosAcc, uint8_t velLpGain, uint8_t cogLpGain, uint16_t maxWait)
{
packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_ODO;
packetCfg.len = 0;
packetCfg.startingSpot = 0;

// Ask module for the current odometer configuration. Loads into payloadCfg.
if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK
return (false);

payloadCfg[4] = flags;
payloadCfg[5] = odoCfg;
payloadCfg[12] = cogMaxSpeed;
payloadCfg[13] = cogMaxPosAcc;
payloadCfg[16] = velLpGain;
payloadCfg[17] = cogLpGain;

return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
}

// Enable/Disable individual GNSS systems using UBX-CFG-GNSS
bool SFE_UBLOX_GNSS::enableGNSS(bool enable, sfe_ublox_gnss_ids_e id, uint16_t maxWait)
{
Expand Down Expand Up @@ -17402,6 +17466,8 @@ int32_t SFE_UBLOX_GNSS::getAltitude(uint16_t maxWait)
// Get the current altitude in mm according to mean sea level
// Ellipsoid model: https://www.esri.com/news/arcuser/0703/geoid1of3.html
// Difference between Ellipsoid Model and Mean Sea Level: https://eos-gnss.com/elevation-for-beginners/
// Also see: https://portal.u-blox.com/s/question/0D52p00008HKDSkCAP/what-geoid-model-is-used-and-where-is-this-calculated
// and: https://cddis.nasa.gov/926/egm96/egm96.html on 10x10 degree grid
int32_t SFE_UBLOX_GNSS::getAltitudeMSL(uint16_t maxWait)
{
if (packetUBXNAVPVT == NULL)
Expand Down
Loading