Add the new callback example
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
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 turns off all sentences except for GPGGA.
|
||||
This example turns off all sentences except for GGA.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
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);
|
||||
}
|
||||
@@ -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
|
||||
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
|
||||
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 flagsCopy = *flagsPtr;
|
||||
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
|
||||
// Callback
|
||||
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
|
||||
&& (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->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)
|
||||
// _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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
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
|
||||
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
|
||||
// From v2.0: These are public. The user can call these to extract data from custom packets
|
||||
|
||||
@@ -2242,7 +2242,7 @@ struct nmeaAutomaticFlags
|
||||
uint8_t all;
|
||||
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 callbackCopyValid : 1; // Is the copy of the data struct used by the callback valid/fresh? 0 = invalid/stale, 1 = valid/fresh
|
||||
} bits;
|
||||
@@ -2280,5 +2280,4 @@ typedef struct
|
||||
NMEA_GGA_data_t *callbackCopy; // The callback gets its own preserved copy of the complete copy
|
||||
} NMEA_GNGGA_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user