/* By: Paul Clark SparkFun Electronics Date: December, 2020 License: MIT. See license file for more information but you can basically do whatever you want with this code. This example configures the External Sensor Fusion messages on the NEO-M8U and uses callbacks to process and display the ESF data automatically. No more polling! Please make sure your NEO-M8U is running UDR firmware >= 1.31. Please update using u-center if necessary: https://www.u-blox.com/en/product/neo-m8u-module#tab-documentation-resources Feel like supporting open source hardware? Buy a board from SparkFun! NEO-M8U: https://www.sparkfun.com/products/16329 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 115200 baud to see the output */ #include //Needed for I2C to GPS #include //http://librarymanager/All#SparkFun_u-blox_GNSS SFE_UBLOX_GPS myGPS; // Callback: printESFALGdata will be called when new ESF ALG data arrives // See u-blox_structs.h for the full definition of UBX_ESF_ALG_data_t // _____ You can use any name you like for the callback. Use the same name when you call setAutoESFALGcallback // / _____ This _must_ be UBX_ESF_ALG_data_t // | / _____ You can use any name you like for the struct // | | / // | | | void printESFALGdata(UBX_ESF_ALG_data_t ubxDataStruct) { Serial.println(); Serial.print(F("TOW: ")); // Print the Time Of Week unsigned long iTOW = ubxDataStruct.iTOW; // iTOW is in milliseconds Serial.print(iTOW); Serial.print(F(" (ms)")); Serial.print(F(" Roll: ")); // Print selected data Serial.print((float)ubxDataStruct.roll / 100.0, 2); // Convert roll to degrees Serial.print(F(" Pitch: ")); Serial.print((float)ubxDataStruct.pitch / 100.0, 2); // Convert pitch to degrees Serial.print(F(" Yaw: ")); Serial.print((float)ubxDataStruct.yaw / 100.0, 2); // Convert yaw to degrees Serial.println(F(" (Degrees)")); } // Callback: printESFINSdata will be called when new ESF INS data arrives // See u-blox_structs.h for the full definition of UBX_ESF_INS_data_t void printESFINSdata(UBX_ESF_INS_data_t ubxDataStruct) { Serial.print(F("xAccel: ")); // Print selected data Serial.print(ubxDataStruct.xAccel); Serial.print(F(" yAccel: ")); Serial.print(ubxDataStruct.yAccel); Serial.print(F(" zAccel: ")); Serial.print(ubxDataStruct.zAccel); Serial.println(F(" (m/s^2)")); } // 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 // and UBX_ESF_MEAS_sensorData_t void printESFMEASdata(UBX_ESF_MEAS_data_t ubxDataStruct) { Serial.println(); Serial.print(F("id: ")); // Print selected data Serial.print(ubxDataStruct.id); Serial.print(F(" numMeas: ")); Serial.println(ubxDataStruct.flags.bits.numMeas); for (uint8_t num = 0; num < ubxDataStruct.flags.bits.numMeas; num++) // For each sensor { Serial.print(F("Sensor ")); Serial.print(num); UBX_ESF_MEAS_sensorData_t sensorData; myGPS.getSensorFusionMeasurement(&sensorData, ubxDataStruct, num); // Extract the data for one sensor Serial.print(F(": Type: ")); Serial.print(sensorData.data.bits.dataType); Serial.print(F(" Data: ")); Serial.println(sensorData.data.bits.dataField); } } // Callback: printESFSTATUSdata will be called when new ESF STATUS data arrives // See u-blox_structs.h for the full definition of UBX_ESF_STATUS_data_t // and UBX_ESF_STATUS_sensorStatus_t void printESFSTATUSdata(UBX_ESF_STATUS_data_t ubxDataStruct) { Serial.print(F("fusionMode: ")); // Print selected data Serial.print(ubxDataStruct.fusionMode); Serial.print(F(" numSens: ")); Serial.println(ubxDataStruct.numSens); for (uint8_t num = 0; num < ubxDataStruct.numSens; num++) // For each sensor { Serial.print(F("Sensor ")); Serial.print(num); UBX_ESF_STATUS_sensorStatus_t sensorStatus; myGPS.getSensorFusionStatus(&sensorStatus, ubxDataStruct, num); // Extract the data for one sensor Serial.print(F(": Type: ")); Serial.print(sensorStatus.sensStatus1.bits.type); Serial.print(F(" Used: ")); Serial.print(sensorStatus.sensStatus1.bits.used); Serial.print(F(" Ready: ")); Serial.print(sensorStatus.sensStatus1.bits.ready); Serial.print(F(" Calib Status: ")); Serial.print(sensorStatus.sensStatus2.bits.calibStatus); Serial.print(F(" Noisy: ")); Serial.println(sensorStatus.faults.bits.noisyMeas); } } void setup() { Serial.begin(115200); while (!Serial); //Wait for user to open terminal Serial.println(F("SparkFun u-blox Example")); Wire.begin(); //myGPS.enableDebugging(); // Uncomment this line to enable debug messages on Serial if (myGPS.begin() == false) //Connect to the Ublox module using Wire port { Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing.")); while (1); } myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise) myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save (only) the communications port settings to flash and BBR myGPS.setNavigationFrequency(1); //Produce one solution per second myGPS.setHNRNavigationRate(1); //Set the High Navigation Rate to 1Hz myGPS.setI2CpollingWait(50); //Allow checkUblox to poll I2C data every 50ms to keep up with the ESF MEAS messages if (myGPS.setAutoESFALGcallback(&printESFALGdata) == true) // Enable automatic ESF ALG messages with callback to printESFALGdata Serial.println(F("setAutoESFALGcallback successful")); if (myGPS.setAutoESFINScallback(&printESFINSdata) == true) // Enable automatic ESF INS messages with callback to printESFINSdata Serial.println(F("setAutoESFINScallback successful")); if (myGPS.setAutoESFMEAScallback(&printESFMEASdata) == true) // Enable automatic ESF MEAS messages with callback to printESFMEASdata Serial.println(F("setAutoESFMEAScallback successful")); if (myGPS.setAutoESFSTATUScallback(&printESFSTATUSdata) == true) // Enable automatic ESF STATUS messages with callback to printESFSTATUSdata Serial.println(F("setAutoESFSTATUScallback successful")); } void loop() { myGPS.checkUblox(); // Check for the arrival of new data and process it. myGPS.checkCallbacks(); // Check if any callbacks are waiting to be processed. Serial.print("."); delay(25); }