diff --git a/README.md b/README.md
index 6934a52..db53b78 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,7 @@ v2.1 of the library adds support for u-blox AssistNowTM Assisted GNSS
This library is the new and improved version of the very popular SparkFun u-blox GNSS Arduino Library. v2.0 contains some big changes and improvements:
* Seamless support for "automatic" message delivery:
- * In v1.8, you could ask for the NAV PVT (Navigation Position Velocity Time) message to be delivered _automatically_, without polling. v2.0 adds automatic support for [**26 messages**](./Theory.md#auto-messages), covering the full range of: standard and High Precision position, velocity, attitude and time information; relative positioning; event capture with nanosecond time resolution; raw GNSS signal data including carrier phase; Sensor Fusion; and High Navigation Rate data.
+ * In v1.8, you could ask for the NAV PVT (Navigation Position Velocity Time) message to be delivered _automatically_, without polling. v2.0 adds automatic support for [**27 messages**](./Theory.md#auto-messages), covering the full range of: standard and High Precision position, velocity, attitude and time information; relative positioning; event capture with nanosecond time resolution; raw GNSS signal data including carrier phase; Sensor Fusion; and High Navigation Rate data.
* Don't see the message you really need? [Adding_New_Messages](./Adding_New_Messages.md) provides details on how to add "auto" support for your favourite message.
* Dynamic memory allocation with clearly-defined data storage structs for each message:
* There are no static 'global' variables to eat up your RAM. v2.0 automatically allocates memory for the automatic messages when they are enabled. You may find your total RAM use is lower with v2.0 than with v1.8.
diff --git a/examples/Callbacks/CallbackExample8_NAV_SVIN/CallbackExample8_NAV_SVIN.ino b/examples/Callbacks/CallbackExample8_NAV_SVIN/CallbackExample8_NAV_SVIN.ino
new file mode 100644
index 0000000..c8f0a25
--- /dev/null
+++ b/examples/Callbacks/CallbackExample8_NAV_SVIN/CallbackExample8_NAV_SVIN.ino
@@ -0,0 +1,127 @@
+/*
+ Configuring the GNSS to automatically send NAV SVIN reports over I2C and display them using a callback
+ By: Paul Clark
+ SparkFun Electronics
+ Date: April 4th, 2022
+ License: MIT. See license file for more information but you can
+ basically do whatever you want with this code.
+
+ This example shows how to configure the u-blox GNSS to send NAV SVIN reports automatically
+ and access the data via a callback. No more polling!
+
+ Feel like supporting open source hardware?
+ Buy a board from SparkFun!
+ ZED-F9P RTK2: https://www.sparkfun.com/products/15136
+
+ Hardware Connections:
+ Plug a Qwiic cable into the GPS 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)
+ Open the serial monitor at 115200 baud to see the output
+*/
+
+#include //Needed for I2C to GNSS
+
+#include //http://librarymanager/All#SparkFun_u-blox_GNSS
+SFE_UBLOX_GNSS myGNSS;
+
+// Callback: newNAVSVIN will be called when new NAV SVIN data arrives
+// See u-blox_structs.h for the full definition of UBX_NAV_SVIN_data_t
+// _____ You can use any name you like for the callback. Use the same name when you call setAutoNAVSVINcallbackPtr
+// / _____ This _must_ be UBX_NAV_SVIN_data_t
+// | / _____ You can use any name you like for the struct
+// | | /
+// | | |
+void newNAVSVIN(UBX_NAV_SVIN_data_t *ubxDataStruct)
+{
+ Serial.println();
+
+ Serial.print(F("Survey-in is "));
+ if (ubxDataStruct->active == 0)
+ Serial.print(F("not "));
+ Serial.println(F("in progress"));
+
+ Serial.print(F("Survey-in position is "));
+ if (ubxDataStruct->valid == 0)
+ Serial.print(F("not "));
+ Serial.println(F("valid"));
+
+ Serial.print(F("Survey-in observation time (s): "));
+ Serial.println(ubxDataStruct->dur);
+
+ Serial.print(F("ECEF position (cm): "));
+ Serial.print(ubxDataStruct->meanX);
+ Serial.print(F(" ("));
+ if (ubxDataStruct->meanXHP >= 0)
+ Serial.print(F("+"));
+ Serial.print((float)ubxDataStruct->meanXHP * 0.01); // Convert 0.1mm to cm
+ Serial.print(F("), "));
+ Serial.print(ubxDataStruct->meanY);
+ Serial.print(F(" ("));
+ if (ubxDataStruct->meanYHP >= 0)
+ Serial.print(F("+"));
+ Serial.print((float)ubxDataStruct->meanYHP * 0.01); // Convert 0.1mm to cm
+ Serial.print(F("), "));
+ Serial.print(ubxDataStruct->meanZ);
+ Serial.print(F(" ("));
+ if (ubxDataStruct->meanZHP >= 0)
+ Serial.print(F("+"));
+ Serial.print((float)ubxDataStruct->meanZHP * 0.01); // Convert 0.1mm to cm
+ Serial.println(F(")"));
+
+ Serial.print(F("Mean position accuracy (cm): "));
+ Serial.println((float)ubxDataStruct->meanAcc * 0.01); // Convert 0.1mm to cm
+}
+
+void setup()
+{
+ Serial.begin(115200);
+ while (!Serial); //Wait for user to open terminal
+ Serial.println(F("u-blox Base Station example"));
+
+ Wire.begin();
+
+ //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);
+ }
+
+ // 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.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
+ myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save the communications port settings to flash and BBR
+
+ // Set up the callback for NAV SVIN. This will enable SVIN messages at the navigation rate
+ myGNSS.setAutoNAVSVINcallbackPtr(&newNAVSVIN);
+
+ while (Serial.available()) Serial.read(); //Clear the serial buffer
+ Serial.println(F("Press any key to begin Survey-In"));
+}
+
+void loop()
+{
+ myGNSS.checkUblox(); //See if new data is available. Process bytes as they come in.
+ myGNSS.checkCallbacks(); //Process any waiting callbacks
+
+ if (Serial.available()) // Check if user has pressed a key
+ {
+ bool success = myGNSS.enableSurveyMode(60, 5.000); //Enable Survey in, 60 seconds, 5.0m
+ //bool success = myGNSS.enableSurveyModeFull(86400, 2.000); //Enable Survey in, 24 hours, 2.0m
+
+ Serial.println();
+
+ if (success)
+ {
+ Serial.println(F("Survey-In started!"));
+ }
+ else
+ {
+ Serial.println(F("Survey start failed!"));
+ }
+
+ while (Serial.available()) Serial.read(); //Clear the serial buffer
+ }
+}
diff --git a/keywords.txt b/keywords.txt
index 5e187b2..293d0ae 100644
--- a/keywords.txt
+++ b/keywords.txt
@@ -238,7 +238,6 @@ setAutoNAVPOSECEFrate KEYWORD2
setAutoNAVPOSECEFcallback KEYWORD2
setAutoNAVPOSECEFcallbackPtr KEYWORD2
assumeAutoNAVPOSECEF KEYWORD2
-initPacketUBXNAVPOSECEF KEYWORD2
flushNAVPOSECEF KEYWORD2
logNAVPOSECEF KEYWORD2
@@ -248,7 +247,6 @@ setAutoNAVSTATUSrate KEYWORD2
setAutoNAVSTATUScallback KEYWORD2
setAutoNAVSTATUScallbackPtr KEYWORD2
assumeAutoNAVSTATUS KEYWORD2
-initPacketUBXNAVSTATUS KEYWORD2
flushNAVSTATUS KEYWORD2
logNAVSTATUS KEYWORD2
@@ -258,7 +256,6 @@ setAutoDOPrate KEYWORD2
setAutoDOPcallback KEYWORD2
setAutoDOPcallbackPtr KEYWORD2
assumeAutoDOP KEYWORD2
-initPacketUBXNAVDOP KEYWORD2
flushDOP KEYWORD2
logNAVDOP KEYWORD2
@@ -269,7 +266,6 @@ setAutoNAVATTrate KEYWORD2
setAutoNAVATTcallback KEYWORD2
setAutoNAVATTcallbackPtr KEYWORD2
assumeAutoNAVATT KEYWORD2
-initPacketUBXNAVATT KEYWORD2
flushNAVATT KEYWORD2
logNAVATT KEYWORD2
@@ -279,7 +275,6 @@ setAutoPVTrate KEYWORD2
setAutoPVTcallback KEYWORD2
setAutoPVTcallbackPtr KEYWORD2
assumeAutoPVT KEYWORD2
-initPacketUBXNAVPVT KEYWORD2
flushPVT KEYWORD2
logNAVPVT KEYWORD2
@@ -289,7 +284,6 @@ setAutoNAVODOrate KEYWORD2
setAutoNAVODOcallback KEYWORD2
setAutoNAVODOcallbackPtr KEYWORD2
assumeAutoNAVODO KEYWORD2
-initPacketUBXNAVODO KEYWORD2
flushNAVODO KEYWORD2
logNAVODO KEYWORD2
@@ -299,7 +293,6 @@ setAutoNAVVELECEFrate KEYWORD2
setAutoNAVVELECEFcallback KEYWORD2
setAutoNAVVELECEFcallbackPtr KEYWORD2
assumeAutoNAVVELECEF KEYWORD2
-initPacketUBXNAVVELECEF KEYWORD2
flushNAVVELECEF KEYWORD2
logNAVVELECEF KEYWORD2
@@ -309,7 +302,6 @@ setAutoNAVVELNEDrate KEYWORD2
setAutoNAVVELNEDcallback KEYWORD2
setAutoNAVVELNEDcallbackPtr KEYWORD2
assumeAutoNAVVELNED KEYWORD2
-initPacketUBXNAVVELNED KEYWORD2
flushNAVVELNED KEYWORD2
logNAVVELNED KEYWORD2
@@ -319,7 +311,6 @@ setAutoNAVHPPOSECEFrate KEYWORD2
setAutoNAVHPPOSECEFcallback KEYWORD2
setAutoNAVHPPOSECEFcallbackPtr KEYWORD2
assumeAutoNAVHPPOSECEF KEYWORD2
-initPacketUBXNAVHPPOSECEF KEYWORD2
flushNAVHPPOSECEF KEYWORD2
logNAVHPPOSECEF KEYWORD2
@@ -329,7 +320,6 @@ setAutoHPPOSLLHrate KEYWORD2
setAutoHPPOSLLHcallback KEYWORD2
setAutoHPPOSLLHcallbackPtr KEYWORD2
assumeAutoHPPOSLLH KEYWORD2
-initPacketUBXNAVHPPOSLLH KEYWORD2
flushHPPOSLLH KEYWORD2
logNAVHPPOSLLH KEYWORD2
@@ -349,17 +339,20 @@ setAutoNAVCLOCKrate KEYWORD2
setAutoNAVCLOCKcallback KEYWORD2
setAutoNAVCLOCKcallbackPtr KEYWORD2
assumeAutoNAVCLOCK KEYWORD2
-initPacketUBXNAVCLOCK KEYWORD2
flushNAVCLOCK KEYWORD2
logNAVCLOCK KEYWORD2
getLeapSecondEvent KEYWORD2
getLeapIndicator KEYWORD2
getCurrentLeapSeconds KEYWORD2
-initPacketUBXNAVTIMELS KEYWORD2
getSurveyStatus KEYWORD2
-initPacketUBXNAVSVIN KEYWORD2
+setAutoNAVSVIN KEYWORD2
+setAutoNAVSVINrate KEYWORD2
+setAutoNAVSVINcallbackPtr KEYWORD2
+assumeAutoNAVSVIN KEYWORD2
+flushNAVSVIN KEYWORD2
+logNAVSVIN KEYWORD2
getNAVSAT KEYWORD2
setAutoNAVSAT KEYWORD2
@@ -367,7 +360,6 @@ setAutoNAVSATrate KEYWORD2
setAutoNAVSATcallback KEYWORD2
setAutoNAVSATcallbackPtr KEYWORD2
assumeAutoNAVSAT KEYWORD2
-initPacketUBXNAVSAT KEYWORD2
flushNAVSAT KEYWORD2
logNAVSAT KEYWORD2
@@ -377,7 +369,6 @@ setAutoRELPOSNEDrate KEYWORD2
setAutoRELPOSNEDcallback KEYWORD2
setAutoRELPOSNEDcallbackPtr KEYWORD2
assumeAutoRELPOSNED KEYWORD2
-initPacketUBXNAVRELPOSNED KEYWORD2
flushNAVRELPOSNED KEYWORD2
logNAVRELPOSNED KEYWORD2
@@ -387,7 +378,6 @@ setAutoAOPSTATUSrate KEYWORD2
setAutoAOPSTATUScallback KEYWORD2
setAutoAOPSTATUScallbackPtr KEYWORD2
assumeAutoAOPSTATUS KEYWORD2
-initPacketUBXAOPSTATUS KEYWORD2
flushAOPSTATUS KEYWORD2
logAOPSTATUS KEYWORD2
@@ -402,7 +392,6 @@ setAutoRXMSFRBXrate KEYWORD2
setAutoRXMSFRBXcallback KEYWORD2
setAutoRXMSFRBXcallbackPtr KEYWORD2
assumeAutoRXMSFRBX KEYWORD2
-initPacketUBXRXMSFRBX KEYWORD2
flushRXMSFRBX KEYWORD2
logRXMSFRBX KEYWORD2
@@ -412,7 +401,6 @@ setAutoRXMRAWXrate KEYWORD2
setAutoRXMRAWXcallback KEYWORD2
setAutoRXMRAWXcallbackPtr KEYWORD2
assumeAutoRXMRAWX KEYWORD2
-initPacketUBXRXMRAWX KEYWORD2
flushRXMRAWX KEYWORD2
logRXMRAWX KEYWORD2
@@ -422,7 +410,6 @@ setAutoTIMTM2rate KEYWORD2
setAutoTIMTM2callback KEYWORD2
setAutoTIMTM2callbackPtr KEYWORD2
assumeAutoTIMTM2 KEYWORD2
-initPacketUBXTIMTM2 KEYWORD2
flushTIMTM2 KEYWORD2
logTIMTM2 KEYWORD2
@@ -433,7 +420,6 @@ setAutoESFALGrate KEYWORD2
setAutoESFALGcallback KEYWORD2
setAutoESFALGcallbackPtr KEYWORD2
assumeAutoESFALG KEYWORD2
-initPacketUBXESFALG KEYWORD2
flushESFALG KEYWORD2
logESFALG KEYWORD2
@@ -444,7 +430,6 @@ setAutoESFSTATUSrate KEYWORD2
setAutoESFSTATUScallback KEYWORD2
setAutoESFSTATUScallbackPtr KEYWORD2
assumeAutoESFSTATUS KEYWORD2
-initPacketUBXESFSTATUS KEYWORD2
flushESFSTATUS KEYWORD2
logESFSTATUS KEYWORD2
@@ -455,7 +440,6 @@ setAutoESFINSrate KEYWORD2
setAutoESFINScallback KEYWORD2
setAutoESFINScallbackPtr KEYWORD2
assumeAutoESFINS KEYWORD2
-initPacketUBXESFINS KEYWORD2
flushESFINS KEYWORD2
logESFINS KEYWORD2
@@ -466,7 +450,6 @@ setAutoESFMEASrate KEYWORD2
setAutoESFMEAScallback KEYWORD2
setAutoESFMEAScallbackPtr KEYWORD2
assumeAutoESFMEAS KEYWORD2
-initPacketUBXESFMEAS KEYWORD2
flushESFMEAS KEYWORD2
logESFMEAS KEYWORD2
@@ -477,7 +460,6 @@ setAutoESFRAWrate KEYWORD2
setAutoESFRAWcallback KEYWORD2
setAutoESFRAWcallbackPtr KEYWORD2
assumeAutoESFRAW KEYWORD2
-initPacketUBXESFRAW KEYWORD2
flushESFRAW KEYWORD2
logESFRAW KEYWORD2
@@ -488,7 +470,6 @@ setAutoHNRATTrate KEYWORD2
setAutoHNRATTcallback KEYWORD2
setAutoHNRATTcallbackPtr KEYWORD2
assumeAutoHNRATT KEYWORD2
-initPacketUBXHNRATT KEYWORD2
flushHNRATT KEYWORD2
logHNRATT KEYWORD2
@@ -499,7 +480,6 @@ setAutoHNRINSrate KEYWORD2
setAutoHNRINScallback KEYWORD2
setAutoHNRINScallbackPtr KEYWORD2
assumeAutoHNRINS KEYWORD2
-initPacketUBXHNRINS KEYWORD2
flushHNRINS KEYWORD2
logHNRINS KEYWORD2
@@ -509,7 +489,6 @@ setAutoHNRPVTrate KEYWORD2
setAutoHNRPVTcallback KEYWORD2
setAutoHNRPVTcallbackPtr KEYWORD2
assumeAutoHNRPVT KEYWORD2
-initPacketUBXHNRPVT KEYWORD2
flushHNRPVT KEYWORD2
logHNRPVT KEYWORD2
diff --git a/library.properties b/library.properties
index 19524b0..e6b176c 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
name=SparkFun u-blox GNSS Arduino Library
-version=2.2.7
+version=2.2.8
author=SparkFun Electronics
maintainer=SparkFun Electronics
sentence=Library for I2C, Serial and SPI Communication with u-blox GNSS modules
diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp
index 1c42dad..2938b12 100644
--- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp
+++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp
@@ -3588,6 +3588,20 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg)
// Mark all datums as fresh (not read before)
packetUBXNAVSVIN->moduleQueried.moduleQueried.all = 0xFFFFFFFF;
+
+ // Check if we need to copy the data for the callback
+ if ((packetUBXNAVSVIN->callbackData != NULL) // If RAM has been allocated for the copy of the data
+ && (packetUBXNAVSVIN->automaticFlags.flags.bits.callbackCopyValid == false)) // AND the data is stale
+ {
+ memcpy(&packetUBXNAVSVIN->callbackData->version, &packetUBXNAVSVIN->data.version, sizeof(UBX_NAV_SVIN_data_t));
+ packetUBXNAVSVIN->automaticFlags.flags.bits.callbackCopyValid = true;
+ }
+
+ // Check if we need to copy the data into the file buffer
+ if (packetUBXNAVSVIN->automaticFlags.flags.bits.addToFileBuffer)
+ {
+ storePacket(msg);
+ }
}
}
else if (msg->id == UBX_NAV_SAT) // Note: length is variable
@@ -3735,7 +3749,7 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg)
// To prevent this, uncomment the line two lines below
if ((packetUBXRXMPMP != NULL) && (packetUBXRXMPMP->callbackData != NULL)
//&& (packetUBXRXMPMP->automaticFlags.flags.bits.callbackCopyValid == false) // <=== Uncomment this line to prevent new data from overwriting 'old'
- )
+ )
{
packetUBXRXMPMP->callbackData->version = extractByte(msg, 0);
packetUBXRXMPMP->callbackData->numBytesUserData = extractInt(msg, 2);
@@ -3772,7 +3786,7 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg)
// To prevent this, uncomment the line two lines below
if ((packetUBXRXMPMPmessage != NULL) && (packetUBXRXMPMPmessage->callbackData != NULL)
//&& (packetUBXRXMPMPmessage->automaticFlags.flags.bits.callbackCopyValid == false) // <=== Uncomment this line to prevent new data from overwriting 'old'
- )
+ )
{
packetUBXRXMPMPmessage->callbackData->sync1 = UBX_SYNCH_1;
packetUBXRXMPMPmessage->callbackData->sync2 = UBX_SYNCH_2;
@@ -3794,7 +3808,7 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg)
// Parse various byte fields into storage - but only if we have memory allocated for it
if ((packetUBXRXMCOR != NULL) && (packetUBXRXMCOR->callbackData != NULL)
//&& (packetUBXRXMCOR->automaticFlags.flags.bits.callbackCopyValid == false) // <=== Uncomment this line to prevent new data from overwriting 'old'
- )
+ )
{
packetUBXRXMCOR->callbackData->version = extractByte(msg, 0);
packetUBXRXMCOR->callbackData->ebno = extractByte(msg, 1);
@@ -5313,6 +5327,19 @@ void SFE_UBLOX_GNSS::checkCallbacks(void)
packetUBXNAVCLOCK->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale
}
+ if ((packetUBXNAVSVIN != NULL) // If RAM has been allocated for message storage
+ && (packetUBXNAVSVIN->callbackData != NULL) // If RAM has been allocated for the copy of the data
+ && (packetUBXNAVSVIN->automaticFlags.flags.bits.callbackCopyValid == true)) // If the copy of the data is valid
+ {
+ if (packetUBXNAVSVIN->callbackPointerPtr != NULL) // If the pointer to the callback has been defined
+ {
+ // if (_printDebug == true)
+ // _debugSerial->println(F("checkCallbacks: calling callbackPtr for NAV SVIN"));
+ packetUBXNAVSVIN->callbackPointerPtr(packetUBXNAVSVIN->callbackData); // Call the callback
+ }
+ packetUBXNAVSVIN->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale
+ }
+
if ((packetUBXNAVSAT != NULL) // If RAM has been allocated for message storage
&& (packetUBXNAVSAT->callbackData != NULL) // If RAM has been allocated for the copy of the data
&& (packetUBXNAVSAT->automaticFlags.flags.bits.callbackCopyValid == true)) // If the copy of the data is valid
@@ -5372,34 +5399,34 @@ void SFE_UBLOX_GNSS::checkCallbacks(void)
if ((packetUBXRXMPMP != NULL) // If RAM has been allocated for message storage
&& (packetUBXRXMPMP->callbackData != NULL) // If RAM has been allocated for the copy of the data
- && (packetUBXRXMPMP->callbackPointerPtr != NULL) // If the pointer to the callback has been defined
+ && (packetUBXRXMPMP->callbackPointerPtr != NULL) // If the pointer to the callback has been defined
&& (packetUBXRXMPMP->automaticFlags.flags.bits.callbackCopyValid == true)) // If the copy of the data is valid
{
// if (_printDebug == true)
// _debugSerial->println(F("checkCallbacks: calling callbackPtr for RXM PMP"));
- packetUBXRXMPMP->callbackPointerPtr(packetUBXRXMPMP->callbackData); // Call the callback
+ packetUBXRXMPMP->callbackPointerPtr(packetUBXRXMPMP->callbackData); // Call the callback
packetUBXRXMPMP->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale
}
if ((packetUBXRXMPMPmessage != NULL) // If RAM has been allocated for message storage
&& (packetUBXRXMPMPmessage->callbackData != NULL) // If RAM has been allocated for the copy of the data
- && (packetUBXRXMPMPmessage->callbackPointerPtr != NULL) // If the pointer to the callback has been defined
+ && (packetUBXRXMPMPmessage->callbackPointerPtr != NULL) // If the pointer to the callback has been defined
&& (packetUBXRXMPMPmessage->automaticFlags.flags.bits.callbackCopyValid == true)) // If the copy of the data is valid
{
// if (_printDebug == true)
// _debugSerial->println(F("checkCallbacks: calling callbackPtr for RXM PMP message"));
packetUBXRXMPMPmessage->callbackPointerPtr(packetUBXRXMPMPmessage->callbackData); // Call the callback
- packetUBXRXMPMPmessage->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale
+ packetUBXRXMPMPmessage->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale
}
if ((packetUBXRXMCOR != NULL) // If RAM has been allocated for message storage
&& (packetUBXRXMCOR->callbackData != NULL) // If RAM has been allocated for the copy of the data
- && (packetUBXRXMCOR->callbackPointerPtr != NULL) // If the pointer to the callback has been defined
+ && (packetUBXRXMCOR->callbackPointerPtr != NULL) // If the pointer to the callback has been defined
&& (packetUBXRXMCOR->automaticFlags.flags.bits.callbackCopyValid == true)) // If the copy of the data is valid
{
// if (_printDebug == true)
// _debugSerial->println(F("checkCallbacks: calling callbackPtr for RXM COR"));
- packetUBXRXMCOR->callbackPointerPtr(packetUBXRXMCOR->callbackData); // Call the callback
+ packetUBXRXMCOR->callbackPointerPtr(packetUBXRXMCOR->callbackData); // Call the callback
packetUBXRXMCOR->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale
}
@@ -8441,7 +8468,7 @@ bool SFE_UBLOX_GNSS::setDynamicSPARTNKey(uint8_t keyLengthBytes, uint16_t validF
}
if (ok)
- ok = setDynamicSPARTNKey(keyLengthBytes, validFromWno, validFromTow, (const uint8_t *)binaryKey);
+ ok = setDynamicSPARTNKey(keyLengthBytes, validFromWno, validFromTow, (const uint8_t *)binaryKey);
delete[] binaryKey; // Free the memory allocated for binaryKey
@@ -8590,7 +8617,7 @@ bool SFE_UBLOX_GNSS::setDynamicSPARTNKeys(uint8_t keyLengthBytes1, uint16_t vali
if (ok)
ok = setDynamicSPARTNKeys(keyLengthBytes1, validFromWno1, validFromTow1, (const uint8_t *)binaryKey1,
- keyLengthBytes2, validFromWno2, validFromTow2, (const uint8_t *)binaryKey2);
+ keyLengthBytes2, validFromWno2, validFromTow2, (const uint8_t *)binaryKey2);
delete[] binaryKey1; // Free the memory allocated for binaryKey1
delete[] binaryKey2; // Free the memory allocated for binaryKey2
@@ -11431,7 +11458,7 @@ bool SFE_UBLOX_GNSS::setAutoNAVCLOCK(bool enable, bool implicitUpdate, uint16_t
return setAutoNAVCLOCKrate(enable ? 1 : 0, implicitUpdate, maxWait);
}
-// Enable or disable automatic CLOCK attitude message generation by the GNSS. This changes the way getNAVCLOCK
+// Enable or disable automatic CLOCK message generation by the GNSS. This changes the way getNAVCLOCK
// works.
bool SFE_UBLOX_GNSS::setAutoNAVCLOCKrate(uint8_t rate, bool implicitUpdate, uint16_t maxWait)
{
@@ -11512,7 +11539,7 @@ bool SFE_UBLOX_GNSS::setAutoNAVCLOCKcallbackPtr(void (*callbackPointerPtr)(UBX_N
return (true);
}
-// In case no config access to the GNSS is possible and HNR attitude is send cyclically already
+// In case no config access to the GNSS is possible and NAV CLOCK is send cyclically already
// set config to suitable parameters
bool SFE_UBLOX_GNSS::assumeAutoNAVCLOCK(bool enabled, bool implicitUpdate)
{
@@ -11629,23 +11656,126 @@ bool SFE_UBLOX_GNSS::getSurveyStatus(uint16_t maxWait)
if (packetUBXNAVSVIN == NULL) // Abort if the RAM allocation failed
return (false);
- packetCfg.cls = UBX_CLASS_NAV;
- packetCfg.id = UBX_NAV_SVIN;
- packetCfg.len = 0;
+ if (packetUBXNAVSVIN->automaticFlags.flags.bits.automatic && packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate)
+ {
+ // The GPS is automatically reporting, we just check whether we got unread data
+ checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_SVIN);
+ return packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.all;
+ }
+ else if (packetUBXNAVSVIN->automaticFlags.flags.bits.automatic && !packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate)
+ {
+ // Someone else has to call checkUblox for us...
+ return (false);
+ }
+ else
+ {
+ // The GPS is not automatically reporting SVIN so we have to poll explicitly
+ packetCfg.cls = UBX_CLASS_NAV;
+ packetCfg.id = UBX_NAV_SVIN;
+ packetCfg.len = 0;
+ packetCfg.startingSpot = 0;
+
+ // The data is parsed as part of processing the response
+ sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait);
+
+ if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED)
+ return (true);
+
+ if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN)
+ {
+ return (true);
+ }
+
+ return (false);
+ }
+}
+
+// Enable or disable automatic SVIN message generation by the GNSS. This changes the way getSurveyStatus
+// works.
+bool SFE_UBLOX_GNSS::setAutoNAVSVIN(bool enable, uint16_t maxWait)
+{
+ return setAutoNAVSVINrate(enable ? 1 : 0, true, maxWait);
+}
+
+// Enable or disable automatic SVIN message generation by the GNSS. This changes the way getSurveyStatus
+// works.
+bool SFE_UBLOX_GNSS::setAutoNAVSVIN(bool enable, bool implicitUpdate, uint16_t maxWait)
+{
+ return setAutoNAVSVINrate(enable ? 1 : 0, implicitUpdate, maxWait);
+}
+
+// Enable or disable automatic SVIN message generation by the GNSS. This changes the way getSurveyStatus
+// works.
+bool SFE_UBLOX_GNSS::setAutoNAVSVINrate(uint8_t rate, bool implicitUpdate, uint16_t maxWait)
+{
+ if (packetUBXNAVSVIN == NULL)
+ initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the data
+ if (packetUBXNAVSVIN == NULL) // Only attempt this if RAM allocation was successful
+ return false;
+
+ if (rate > 127)
+ rate = 127;
+
+ packetCfg.cls = UBX_CLASS_CFG;
+ packetCfg.id = UBX_CFG_MSG;
+ packetCfg.len = 3;
packetCfg.startingSpot = 0;
+ payloadCfg[0] = UBX_CLASS_NAV;
+ payloadCfg[1] = UBX_NAV_SVIN;
+ payloadCfg[2] = rate; // rate relative to navigation freq.
- // The data is parsed as part of processing the response
- sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait);
+ bool ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
+ if (ok)
+ {
+ packetUBXNAVSVIN->automaticFlags.flags.bits.automatic = (rate > 0);
+ packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate = implicitUpdate;
+ }
+ packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale
+ return ok;
+}
- if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED)
- return (true);
+// Enable automatic navigation message generation by the GNSS.
+bool SFE_UBLOX_GNSS::setAutoNAVSVINcallbackPtr(void (*callbackPointerPtr)(UBX_NAV_SVIN_data_t *), uint16_t maxWait)
+{
+ // Enable auto messages. Set implicitUpdate to false as we expect the user to call checkUblox manually.
+ bool result = setAutoNAVSVIN(true, false, maxWait);
+ if (!result)
+ return (result); // Bail if setAuto failed
- if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN)
+ if (packetUBXNAVSVIN->callbackData == NULL) // Check if RAM has been allocated for the callback copy
{
- return (true);
+ packetUBXNAVSVIN->callbackData = new UBX_NAV_SVIN_data_t; // Allocate RAM for the main struct
}
- return (false);
+ if (packetUBXNAVSVIN->callbackData == NULL)
+ {
+#ifndef SFE_UBLOX_REDUCED_PROG_MEM
+ if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
+ _debugSerial->println(F("setAutoNAVSVINcallbackPtr: RAM alloc failed!"));
+#endif
+ return (false);
+ }
+
+ packetUBXNAVSVIN->callbackPointerPtr = callbackPointerPtr;
+ return (true);
+}
+
+// In case no config access to the GNSS is possible and SVIN is send cyclically already
+// set config to suitable parameters
+bool SFE_UBLOX_GNSS::assumeAutoNAVSVIN(bool enabled, bool implicitUpdate)
+{
+ if (packetUBXNAVSVIN == NULL)
+ initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the SVIN data
+ if (packetUBXNAVSVIN == NULL) // Bail if the RAM allocation failed
+ return (false);
+
+ bool changes = packetUBXNAVSVIN->automaticFlags.flags.bits.automatic != enabled || packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate != implicitUpdate;
+ if (changes)
+ {
+ packetUBXNAVSVIN->automaticFlags.flags.bits.automatic = enabled;
+ packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate = implicitUpdate;
+ }
+ return changes;
}
// PRIVATE: Allocate RAM for packetUBXNAVSVIN and initialize it
@@ -11661,13 +11791,28 @@ bool SFE_UBLOX_GNSS::initPacketUBXNAVSVIN()
return (false);
}
packetUBXNAVSVIN->automaticFlags.flags.all = 0;
- packetUBXNAVSVIN->callbackPointer = NULL;
packetUBXNAVSVIN->callbackPointerPtr = NULL;
packetUBXNAVSVIN->callbackData = NULL;
packetUBXNAVSVIN->moduleQueried.moduleQueried.all = 0;
return (true);
}
+// Mark all the data as read/stale
+void SFE_UBLOX_GNSS::flushNAVSVIN()
+{
+ if (packetUBXNAVSVIN == NULL)
+ return; // Bail if RAM has not been allocated (otherwise we could be writing anywhere!)
+ packetUBXNAVSVIN->moduleQueried.moduleQueried.all = 0; // Mark all datums as stale (read before)
+}
+
+// Log this data in file buffer
+void SFE_UBLOX_GNSS::logNAVSVIN(bool enabled)
+{
+ if (packetUBXNAVSVIN == NULL)
+ return; // Bail if RAM has not been allocated (otherwise we could be writing anywhere!)
+ packetUBXNAVSVIN->automaticFlags.flags.bits.addToFileBuffer = (uint8_t)enabled;
+}
+
// ***** NAV SAT automatic support
// Signal information
@@ -11727,7 +11872,7 @@ bool SFE_UBLOX_GNSS::setAutoNAVSAT(bool enable, bool implicitUpdate, uint16_t ma
return setAutoNAVSATrate(enable ? 1 : 0, implicitUpdate, maxWait);
}
-// Enable or disable automatic HNR attitude message generation by the GNSS. This changes the way getNAVSAT
+// Enable or disable automatic NAV SAT message generation by the GNSS. This changes the way getNAVSAT
// works.
bool SFE_UBLOX_GNSS::setAutoNAVSATrate(uint8_t rate, bool implicitUpdate, uint16_t maxWait)
{
@@ -11808,7 +11953,7 @@ bool SFE_UBLOX_GNSS::setAutoNAVSATcallbackPtr(void (*callbackPointerPtr)(UBX_NAV
return (true);
}
-// In case no config access to the GNSS is possible and HNR attitude is send cyclically already
+// In case no config access to the GNSS is possible and NAV SAT is send cyclically already
// set config to suitable parameters
bool SFE_UBLOX_GNSS::assumeAutoNAVSAT(bool enabled, bool implicitUpdate)
{
@@ -11924,7 +12069,7 @@ bool SFE_UBLOX_GNSS::setAutoRELPOSNED(bool enable, bool implicitUpdate, uint16_t
return setAutoRELPOSNEDrate(enable ? 1 : 0, implicitUpdate, maxWait);
}
-// Enable or disable automatic HNR attitude message generation by the GNSS. This changes the way getRELPOSNED
+// Enable or disable automatic RELPOSNED message generation by the GNSS. This changes the way getRELPOSNED
// works.
bool SFE_UBLOX_GNSS::setAutoRELPOSNEDrate(uint8_t rate, bool implicitUpdate, uint16_t maxWait)
{
@@ -12005,7 +12150,7 @@ bool SFE_UBLOX_GNSS::setAutoRELPOSNEDcallbackPtr(void (*callbackPointerPtr)(UBX_
return (true);
}
-// In case no config access to the GNSS is possible and HNR attitude is send cyclically already
+// In case no config access to the GNSS is possible and RELPOSNED is send cyclically already
// set config to suitable parameters
bool SFE_UBLOX_GNSS::assumeAutoRELPOSNED(bool enabled, bool implicitUpdate)
{
@@ -15833,6 +15978,15 @@ uint8_t SFE_UBLOX_GNSS::getNavigationFrequency(uint16_t maxWait)
uint16_t measurementRate = packetUBXCFGRATE->data.measRate;
+ if (measurementRate == 0)
+ {
+#ifndef SFE_UBLOX_REDUCED_PROG_MEM
+ if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
+ _debugSerial->println(F("getNavigationFrequency: zero measRate!"));
+#endif
+ return (0); // Avoid divide-by-zero error
+ }
+
measurementRate = 1000 / measurementRate; // This may return an int when it's a float, but I'd rather not return 4 bytes
return (measurementRate);
}
@@ -16232,16 +16386,16 @@ uint32_t SFE_UBLOX_GNSS::getUnixEpoch(uint16_t maxWait)
packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.min = false;
packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.sec = false;
packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false;
- uint32_t t = SFE_UBLOX_DAYS_FROM_1970_TO_2020; // Jan 1st 2020 as days from Jan 1st 1970
- t += (uint32_t)SFE_UBLOX_DAYS_SINCE_2020[packetUBXNAVPVT->data.year - 2020]; // Add on the number of days since 2020
+ uint32_t t = SFE_UBLOX_DAYS_FROM_1970_TO_2020; // Jan 1st 2020 as days from Jan 1st 1970
+ t += (uint32_t)SFE_UBLOX_DAYS_SINCE_2020[packetUBXNAVPVT->data.year - 2020]; // Add on the number of days since 2020
t += (uint32_t)SFE_UBLOX_DAYS_SINCE_MONTH[packetUBXNAVPVT->data.year % 4 == 0 ? 0 : 1][packetUBXNAVPVT->data.month - 1]; // Add on the number of days since Jan 1st
- t += (uint32_t)packetUBXNAVPVT->data.day - 1; // Add on the number of days since the 1st of the month
- t *= 24; // Convert to hours
- t += (uint32_t)packetUBXNAVPVT->data.hour; // Add on the hour
- t *= 60; // Convert to minutes
- t += (uint32_t)packetUBXNAVPVT->data.min; // Add on the minute
- t *= 60; // Convert to seconds
- t += (uint32_t)packetUBXNAVPVT->data.sec; // Add on the second
+ t += (uint32_t)packetUBXNAVPVT->data.day - 1; // Add on the number of days since the 1st of the month
+ t *= 24; // Convert to hours
+ t += (uint32_t)packetUBXNAVPVT->data.hour; // Add on the hour
+ t *= 60; // Convert to minutes
+ t += (uint32_t)packetUBXNAVPVT->data.min; // Add on the minute
+ t *= 60; // Convert to seconds
+ t += (uint32_t)packetUBXNAVPVT->data.sec; // Add on the second
return t;
}
@@ -16263,23 +16417,23 @@ uint32_t SFE_UBLOX_GNSS::getUnixEpoch(uint32_t µsecond, uint16_t maxWait)
packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.sec = false;
packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.nano = false;
packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false;
- uint32_t t = SFE_UBLOX_DAYS_FROM_1970_TO_2020; // Jan 1st 2020 as days from Jan 1st 1970
- t += (uint32_t)SFE_UBLOX_DAYS_SINCE_2020[packetUBXNAVPVT->data.year - 2020]; // Add on the number of days since 2020
+ uint32_t t = SFE_UBLOX_DAYS_FROM_1970_TO_2020; // Jan 1st 2020 as days from Jan 1st 1970
+ t += (uint32_t)SFE_UBLOX_DAYS_SINCE_2020[packetUBXNAVPVT->data.year - 2020]; // Add on the number of days since 2020
t += (uint32_t)SFE_UBLOX_DAYS_SINCE_MONTH[packetUBXNAVPVT->data.year % 4 == 0 ? 0 : 1][packetUBXNAVPVT->data.month - 1]; // Add on the number of days since Jan 1st
- t += (uint32_t)packetUBXNAVPVT->data.day - 1; // Add on the number of days since the 1st of the month
- t *= 24; // Convert to hours
- t += (uint32_t)packetUBXNAVPVT->data.hour; // Add on the hour
- t *= 60; // Convert to minutes
- t += (uint32_t)packetUBXNAVPVT->data.min; // Add on the minute
- t *= 60; // Convert to seconds
- t += (uint32_t)packetUBXNAVPVT->data.sec; // Add on the second
- int32_t us = packetUBXNAVPVT->data.nano / 1000; // Convert nanos to micros
- microsecond = (uint32_t)us; // Could be -ve!
+ t += (uint32_t)packetUBXNAVPVT->data.day - 1; // Add on the number of days since the 1st of the month
+ t *= 24; // Convert to hours
+ t += (uint32_t)packetUBXNAVPVT->data.hour; // Add on the hour
+ t *= 60; // Convert to minutes
+ t += (uint32_t)packetUBXNAVPVT->data.min; // Add on the minute
+ t *= 60; // Convert to seconds
+ t += (uint32_t)packetUBXNAVPVT->data.sec; // Add on the second
+ int32_t us = packetUBXNAVPVT->data.nano / 1000; // Convert nanos to micros
+ microsecond = (uint32_t)us; // Could be -ve!
// Adjust t if nano is negative
if (us < 0)
{
microsecond = (uint32_t)(us + 1000000); // Make nano +ve
- t--; // Decrement t by 1 second
+ t--; // Decrement t by 1 second
}
return t;
}
diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h
index dde932c..297d88c 100644
--- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h
+++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h
@@ -1110,11 +1110,17 @@ class SFE_UBLOX_GNSS
void flushNAVCLOCK(); // Mark all the data as read/stale
void logNAVCLOCK(bool enabled = true); // Log data to file buffer
- // Add "auto" support for NAV SVIN - to avoid needing 'global' storage
- bool getSurveyStatus(uint16_t maxWait); // Reads survey in status
+ bool getSurveyStatus(uint16_t maxWait = 2100); // NAV SVIN - Reads survey in status
+ bool setAutoNAVSVIN(bool enabled, uint16_t maxWait = defaultMaxWait); // Enable/disable automatic survey in reports at the navigation frequency
+ bool setAutoNAVSVIN(bool enabled, bool implicitUpdate, uint16_t maxWait = defaultMaxWait); // Enable/disable automatic survey in reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update
+ bool setAutoNAVSVINrate(uint8_t rate, bool implicitUpdate = true, uint16_t maxWait = defaultMaxWait); // Set the rate for automatic SVIN reports
+ bool setAutoNAVSVINcallbackPtr(void (*callbackPointerPtr)(UBX_NAV_SVIN_data_t *), uint16_t maxWait = defaultMaxWait); // Enable automatic SVIN reports at the navigation frequency. Data is accessed from the callback.
+ bool assumeAutoNAVSVIN(bool enabled, bool implicitUpdate = true); // In case no config access to the GPS is possible and survey in is send cyclically already
+ void flushNAVSVIN(); // Mark all the data as read/stale
+ void logNAVSVIN(bool enabled = true); // Log data to file buffer
// Add "auto" support for NAV TIMELS - to avoid needing 'global' storage
- bool getLeapSecondEvent(uint16_t maxWait); // Reads leap second event info
+ bool getLeapSecondEvent(uint16_t maxWait = defaultMaxWait); // Reads leap second event info
bool getNAVSAT(uint16_t maxWait = defaultMaxWait); // Query module for latest AssistNow Autonomous status and load global vars:. If autoNAVSAT is disabled, performs an explicit poll and waits, if enabled does not block. Returns true if new NAVSAT is available.
bool setAutoNAVSAT(bool enabled, uint16_t maxWait = defaultMaxWait); // Enable/disable automatic NAVSAT reports at the navigation frequency
diff --git a/src/u-blox_structs.h b/src/u-blox_structs.h
index 321bf53..105477f 100644
--- a/src/u-blox_structs.h
+++ b/src/u-blox_structs.h
@@ -1233,7 +1233,6 @@ typedef struct
ubxAutomaticFlags automaticFlags;
UBX_NAV_SVIN_data_t data;
UBX_NAV_SVIN_moduleQueried_t moduleQueried;
- void (*callbackPointer)(UBX_NAV_SVIN_data_t);
void (*callbackPointerPtr)(UBX_NAV_SVIN_data_t *);
UBX_NAV_SVIN_data_t *callbackData;
} UBX_NAV_SVIN_t;