Add the new callback example

This commit is contained in:
PaulZC
2022-01-13 12:01:23 +00:00
parent a1814e32ab
commit a08198b27e
5 changed files with 140 additions and 6 deletions
@@ -18,7 +18,7 @@
The library includes a getLatestNMEAGNGGA function too. The library includes a getLatestNMEAGNGGA function too.
This example shows how to use both functions - and how to change the Talker ID so the GNGGA messages become GPGGA. This example shows how to use both functions - and how to change the Talker ID so the GNGGA messages become GPGGA.
This example turns off all sentences except for GPGGA. This example turns off all sentences except for GGA.
Feel like supporting open source hardware? Feel like supporting open source hardware?
Buy a board from SparkFun! Buy a board from SparkFun!
@@ -0,0 +1,117 @@
/*
Get the latest GPGGA / GNGGA NMEA sentence using callbacks
By: Paul Clark
SparkFun Electronics
Date: January 12th, 2021
License: MIT. See license file for more information but you can
basically do whatever you want with this code.
This example shows how to turn on/off the NMEA sentences being output over I2C.
It then demonstrates how to get the latest GPGGA or GNGGA message autonomously using callbacks.
If the module is using multiple GNSS constellations, the GGA message will be prefixed with Talker ID "GN" instead of "GP".
This example shows how to change the Talker ID so the GNGGA messages become GPGGA.
It also shows how to enable "high precision mode" to include extra decimal places in the GGA messages.
This example turns off all sentences except for GGA.
Feel like supporting open source hardware?
Buy a board from SparkFun!
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
NEO-M8P RTK: https://www.sparkfun.com/products/15005
SAM-M8Q: https://www.sparkfun.com/products/15106
Hardware Connections:
Plug a Qwiic cable into the GNSS and a RedBoard
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 <Wire.h> //Needed for I2C to GNSS
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS
SFE_UBLOX_GNSS myGNSS;
// Callback: printGPGGA will be called when new GPGGA NMEA data arrives
// See u-blox_structs.h for the full definition of NMEA_GGA_data_t
// _____ You can use any name you like for the callback. Use the same name when you call setNMEAGPGGAcallback
// / _____ This _must_ be NMEA_GGA_data_t
// | / _____ You can use any name you like for the struct
// | | /
// | | |
void printGPGGA(NMEA_GGA_data_t nmeaData)
{
Serial.print(F("\r\nGPGGA: Length: "));
Serial.print(nmeaData.length);
Serial.print(F("\tData: "));
Serial.print((const char *)nmeaData.nmea); // .nmea is printable (NULL-terminated) and already has \r\n on the end
}
// Callback: printGNGGA will be called if new GNGGA NMEA data arrives
// See u-blox_structs.h for the full definition of NMEA_GGA_data_t
// _____ You can use any name you like for the callback. Use the same name when you call setNMEAGNGGAcallback
// / _____ This _must_ be NMEA_GGA_data_t
// | / _____ You can use any name you like for the struct
// | | /
// | | |
void printGNGGA(NMEA_GGA_data_t nmeaData)
{
Serial.print(F("\r\nGNGGA: Length: "));
Serial.print(nmeaData.length);
Serial.print(F("\tData: "));
Serial.print((const char *)nmeaData.nmea); // .nmea is printable (NULL-terminated) and already has \r\n on the end
}
void setup()
{
Serial.begin(115200);
Serial.println(F("SparkFun u-blox GNSS Example"));
Wire.begin();
//myGNSS.enableDebugging(); // Uncomment this line to enable debug messages on Serial
if (myGNSS.begin() == false)
{
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
while (1)
;
}
// Disable or enable various NMEA sentences over the I2C interface
myGNSS.setI2COutput(COM_TYPE_NMEA | COM_TYPE_UBX); // Turn on both UBX and NMEA sentences on I2C. (Turn off RTCM and SPARTN)
myGNSS.disableNMEAMessage(UBX_NMEA_GLL, COM_PORT_I2C); // Several of these are on by default on ublox board so let's disable them
myGNSS.disableNMEAMessage(UBX_NMEA_GSA, COM_PORT_I2C);
myGNSS.disableNMEAMessage(UBX_NMEA_GSV, COM_PORT_I2C);
myGNSS.disableNMEAMessage(UBX_NMEA_RMC, COM_PORT_I2C);
myGNSS.disableNMEAMessage(UBX_NMEA_VTG, COM_PORT_I2C);
myGNSS.enableNMEAMessage(UBX_NMEA_GGA, COM_PORT_I2C); // Leave only GGA enabled at current navigation rate
// Set the Main Talker ID to "GP". The NMEA GGA messages will be GPGGA instead of GNGGA
myGNSS.setMainTalkerID(SFE_UBLOX_MAIN_TALKER_ID_GP);
//myGNSS.setMainTalkerID(SFE_UBLOX_MAIN_TALKER_ID_DEFAULT); // Uncomment this line to restore the default main talker ID
myGNSS.setHighPrecisionMode(true); // Enable High Precision Mode - include extra decimal places in the GGA messages
//myGNSS.saveConfiguration(VAL_CFG_SUBSEC_IOPORT | VAL_CFG_SUBSEC_MSGCONF); //Optional: Save only the ioPort and message settings to NVM
Serial.println(F("Messages configured"));
//myGNSS.setNMEAOutputPort(Serial); // Uncomment this line to echo all NMEA data to Serial for debugging
// Set up the callback for GPGGA
myGNSS.setNMEAGPGGAcallback(&printGPGGA);
// Set up the callback for GNGGA
myGNSS.setNMEAGNGGAcallback(&printGNGGA);
}
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.
Serial.print(".");
delay(50);
}
+20 -2
View File
@@ -1712,6 +1712,13 @@ void SFE_UBLOX_GNSS::process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t r
memset(nmeaPtr, 0, nmeaMaxLength); // Clear the working copy memset(nmeaPtr, 0, nmeaMaxLength); // Clear the working copy
memcpy(nmeaPtr, &nmeaAddressField[0], 6); // Copy the start character and address field into the working copy memcpy(nmeaPtr, &nmeaAddressField[0], 6); // Copy the start character and address field into the working copy
} }
else
{
// if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
// {
// _debugSerial->println(F("process: non-auto NMEA message"));
// }
}
// We've just received the end of the address field. Check if it is selected for logging // We've just received the end of the address field. Check if it is selected for logging
if (logThisNMEA()) if (logThisNMEA())
@@ -1804,7 +1811,7 @@ void SFE_UBLOX_GNSS::process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t r
nmeaAutomaticFlags *flagsPtr = getNMEAFlagsPtr(); // Get a pointer to the flags nmeaAutomaticFlags *flagsPtr = getNMEAFlagsPtr(); // Get a pointer to the flags
nmeaAutomaticFlags flagsCopy = *flagsPtr; nmeaAutomaticFlags flagsCopy = *flagsPtr;
flagsCopy.flags.bits.completeCopyValid = 1; // Set the complete copy valid flag flagsCopy.flags.bits.completeCopyValid = 1; // Set the complete copy valid flag
flagsCopy.flags.bits.completeCopyRead = 0; // Clear the complete copy read/stale flag flagsCopy.flags.bits.completeCopyRead = 0; // Clear the complete copy read flag
*flagsPtr = flagsCopy; // Update the flags *flagsPtr = flagsCopy; // Update the flags
// Callback // Callback
if (doesThisNMEAHaveCallback()) // Do we need to copy the data into the callback copy? if (doesThisNMEAHaveCallback()) // Do we need to copy the data into the callback copy?
@@ -4628,7 +4635,7 @@ void SFE_UBLOX_GNSS::checkCallbacks(void)
if ((storageNMEAGPGGA != NULL) // If RAM has been allocated for message storage if ((storageNMEAGPGGA != NULL) // If RAM has been allocated for message storage
&& (storageNMEAGPGGA->callbackCopy != NULL) // If RAM has been allocated for the copy of the data && (storageNMEAGPGGA->callbackCopy != NULL) // If RAM has been allocated for the copy of the data
&& (storageNMEAGPGGA->callbackPointer != NULL) // If the pointer to the callback has been defined && (storageNMEAGPGGA->callbackPointer != NULL) // If the pointer to the callback has been defined
&& (storageNMEAGPGGA->automaticFlags.flags.bits.callbackCopyValid == true)) // If the copy of the data is valid && (storageNMEAGPGGA->automaticFlags.flags.bits.callbackCopyValid == 1)) // If the copy of the data is valid
{ {
// if (_printDebug == true) // if (_printDebug == true)
// _debugSerial->println(F("checkCallbacks: calling callback for GPGGA")); // _debugSerial->println(F("checkCallbacks: calling callback for GPGGA"));
@@ -4636,6 +4643,17 @@ void SFE_UBLOX_GNSS::checkCallbacks(void)
storageNMEAGPGGA->automaticFlags.flags.bits.callbackCopyValid = 0; // Mark the data as stale storageNMEAGPGGA->automaticFlags.flags.bits.callbackCopyValid = 0; // Mark the data as stale
} }
if ((storageNMEAGNGGA != NULL) // If RAM has been allocated for message storage
&& (storageNMEAGNGGA->callbackCopy != NULL) // If RAM has been allocated for the copy of the data
&& (storageNMEAGNGGA->callbackPointer != NULL) // If the pointer to the callback has been defined
&& (storageNMEAGNGGA->automaticFlags.flags.bits.callbackCopyValid == 1)) // If the copy of the data is valid
{
// if (_printDebug == true)
// _debugSerial->println(F("checkCallbacks: calling callback for GNGGA"));
storageNMEAGNGGA->callbackPointer(*storageNMEAGNGGA->callbackCopy); // Call the callback
storageNMEAGNGGA->automaticFlags.flags.bits.callbackCopyValid = 0; // Mark the data as stale
}
checkCallbacksReentrant = false; checkCallbacksReentrant = false;
} }
+1 -1
View File
@@ -1345,7 +1345,7 @@ public:
uint8_t getLatestNMEAGPGGA(NMEA_GGA_data_t *data); // Return the most recent GPGGA: 0 = no data, 1 = stale data, 2 = fresh data uint8_t getLatestNMEAGPGGA(NMEA_GGA_data_t *data); // Return the most recent GPGGA: 0 = no data, 1 = stale data, 2 = fresh data
bool setNMEAGPGGAcallback(void (*callbackPointer)(NMEA_GGA_data_t)); //Enable a callback on the arrival of a GPGGA message bool setNMEAGPGGAcallback(void (*callbackPointer)(NMEA_GGA_data_t)); //Enable a callback on the arrival of a GPGGA message
uint8_t getLatestNMEAGNGGA(NMEA_GGA_data_t *data); // Return the most recent GNGGA: 0 = no data, 1 = stale data, 2 = fresh data uint8_t getLatestNMEAGNGGA(NMEA_GGA_data_t *data); // Return the most recent GNGGA: 0 = no data, 1 = stale data, 2 = fresh data
bool setNMEAGNGGAcallback(void (*callbackPointer)(NMEA_GGA_data_t)); //Enable a callback on the arrival of a GPGGA message bool setNMEAGNGGAcallback(void (*callbackPointer)(NMEA_GGA_data_t)); //Enable a callback on the arrival of a GNGGA message
// Functions to extract signed and unsigned 8/16/32-bit data from a ubxPacket // Functions to extract signed and unsigned 8/16/32-bit data from a ubxPacket
// From v2.0: These are public. The user can call these to extract data from custom packets // From v2.0: These are public. The user can call these to extract data from custom packets
+1 -2
View File
@@ -2242,7 +2242,7 @@ struct nmeaAutomaticFlags
uint8_t all; uint8_t all;
struct struct
{ {
uint8_t completeCopyValid : 1; // Is the copy of the data struct used by the get function valid/fresh? 0 = invalid/stale, 1 = valid/fresh uint8_t completeCopyValid : 1; // Is the copy of the data struct used by the get function valid/fresh? 0 = invalid, 1 = valid
uint8_t completeCopyRead : 1; // Has the complete copy been read? 0 = unread, 1 = read uint8_t completeCopyRead : 1; // Has the complete copy been read? 0 = unread, 1 = read
uint8_t callbackCopyValid : 1; // Is the copy of the data struct used by the callback valid/fresh? 0 = invalid/stale, 1 = valid/fresh uint8_t callbackCopyValid : 1; // Is the copy of the data struct used by the callback valid/fresh? 0 = invalid/stale, 1 = valid/fresh
} bits; } bits;
@@ -2280,5 +2280,4 @@ typedef struct
NMEA_GGA_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy NMEA_GGA_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy
} NMEA_GNGGA_t; } NMEA_GNGGA_t;
#endif #endif