diff --git a/examples/AssistNow/AssistNow_Online/Example5_AssistNowOnline_MQTT/Example5_AssistNowOnline_MQTT.ino b/examples/AssistNow/AssistNow_Online/Example5_AssistNowOnline_MQTT/Example5_AssistNowOnline_MQTT.ino new file mode 100644 index 0000000..99d9b78 --- /dev/null +++ b/examples/AssistNow/AssistNow_Online/Example5_AssistNowOnline_MQTT/Example5_AssistNowOnline_MQTT.ino @@ -0,0 +1,170 @@ +/* + Use ESP32 WiFi to get AssistNow Online (MGA) data from PointPerfect (broker) as a Client using MQTT + By: Paul Clark / SparkFun + Date: March 9th, 2022 + Based on original code by: u-blox AG / Michael Ammann + License: MIT. See license file for more information but you can + basically do whatever you want with this code. + + This example shows how to obtain AssistNow Online (MGA) data from a PointPerfect Broker over WiFi + and push it over I2C to a ZED-F9x. + It's confusing, but the Arduino is acting as a 'client' to the PointPerfect service. + + You will need to have a valid u-blox Thingstream account and have a PointPerfect Thing and payed plan. + To sign up, go to: https://portal.thingstream.io/app/location-services/things + + This is a proof of concept to show how to connect via MQTT to get AssistNow MGA data. + + For more information about MQTT, SPARTN and PointPerfect Correction Services + please see: https://www.u-blox.com/en/product/pointperfect + + Feel like supporting open source hardware? + Buy a board from SparkFun! + SparkFun Thing Plus - ESP32 WROOM: https://www.sparkfun.com/products/15663 + ZED-F9P RTK2: https://www.sparkfun.com/products/16481 + SparkFun GPS Breakout - ZOE-M8Q (Qwiic): https://www.sparkfun.com/products/15193 + + Hardware Connections: + Plug a Qwiic cable into the GNSS and a ESP32 Thing Plus + 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 +#include +#include // Click here to get the library: http://librarymanager/All#ArduinoMqttClient +#include "secrets.h" + +#include // Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS +SFE_UBLOX_GNSS myGNSS; + +//Global variables +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long lastReceived_ms = 0; //5 RTCM messages take approximately ~300ms to arrive at 115200bps +int maxTimeBeforeHangup_ms = 10000; //If we fail to get a complete RTCM frame after 10s, then disconnect from caster +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +void setup() +{ + Serial.begin(115200); + while (!Serial); + Serial.println(F("PointPerfect AssistNow testing")); + + Wire.begin(); //Start I2C + + if (myGNSS.begin() == false) //Connect to the Ublox module using Wire port + { + Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing.")); + while (1); + } + + Serial.println(F("u-blox module connected")); + myGNSS.setI2COutput(COM_TYPE_UBX); //Turn off NMEA noise + myGNSS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_SPARTN); + + myGNSS.setNavigationFrequency(1); //Set output in Hz. + + Serial.print(F("Connecting to local WiFi")); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print(F(".")); + } + Serial.println(); + + Serial.print(F("WiFi connected with IP: ")); + Serial.println(WiFi.localIP()); + + while (Serial.available()) Serial.read(); +} + +void loop() +{ + if (Serial.available()) + { + beginClient(); + while (Serial.available()) Serial.read(); //Empty buffer of any newline chars + } + + Serial.println(F("Press any key to start MQTT Client.")); + + delay(1000); +} + +WiFiClientSecure wifiClient = WiFiClientSecure(); +MqttClient mqttClient(wifiClient); + +void mqttMessageHandler(int messageSize) { + uint8_t mgaData[512 * 4]; //Most incoming data is around 500 bytes but may be larger + int mgaCount = 0; + Serial.print(F("Pushed data from ")); + Serial.print(mqttClient.messageTopic()); + Serial.println(F(" topic to ZED")); + while (mqttClient.available()) + { + char ch = mqttClient.read(); + //Serial.write(ch); //Pipe to serial port is fine but beware, it's a lot of binary data + mgaData[mgaCount++] = ch; + if (mgaCount == sizeof(mgaData)) + break; + } + + if (mgaCount > 0) + { + //Push MGA data to GNSS module over I2C + myGNSS.pushRawData(mgaData, mgaCount, false); + lastReceived_ms = millis(); + } +} + +//Connect to MQTT broker, receive MGA, and push to ZED module over I2C +void beginClient() +{ + Serial.println(F("Subscribing to Broker. Press key to stop")); + delay(10); //Wait for any serial to arrive + while (Serial.available()) Serial.read(); //Flush + + while (Serial.available() == 0) + { + //Connect if we are not already + if (wifiClient.connected() == false) + { + // Connect to AWS IoT + wifiClient.setCACert(AWS_CERT_CA); + wifiClient.setCertificate(AWS_CERT_CRT); + wifiClient.setPrivateKey(AWS_CERT_PRIVATE); + mqttClient.setId(MQTT_CLIENT_ID); + mqttClient.setKeepAliveInterval(60*1000); + mqttClient.setConnectionTimeout( 5*1000); + if (!mqttClient.connect(AWS_IOT_ENDPOINT, AWS_IOT_PORT)) { + Serial.print(F("MQTT connection failed! Error code = ")); + Serial.println(mqttClient.connectError()); + return; + } else { + Serial.println(F("You're connected to the PointPerfect MQTT broker: ")); + Serial.println(AWS_IOT_ENDPOINT); + // Subscribe to MQTT and register a callback + Serial.println(F("Subscribe to Topics")); + mqttClient.onMessage(mqttMessageHandler); + mqttClient.subscribe(MQTT_TOPIC_ASSISTNOW); + lastReceived_ms = millis(); + } //End attempt to connect + } //End connected == false + else { + mqttClient.poll(); + } + //Close socket if we don't have new data for 10s + if (millis() - lastReceived_ms > maxTimeBeforeHangup_ms) + { + Serial.println(F("Timeout. Disconnecting...")); + if (mqttClient.connected() == true) + mqttClient.stop(); + return; + } + + delay(10); + } + + Serial.println(F("User pressed a key")); + Serial.println(F("Disconnecting...")); + wifiClient.stop(); +} diff --git a/examples/AssistNow/AssistNow_Online/Example5_AssistNowOnline_MQTT/secrets.h b/examples/AssistNow/AssistNow_Online/Example5_AssistNowOnline_MQTT/secrets.h new file mode 100644 index 0000000..872c071 --- /dev/null +++ b/examples/AssistNow/AssistNow_Online/Example5_AssistNowOnline_MQTT/secrets.h @@ -0,0 +1,39 @@ +//Your WiFi credentials +const char ssid[] = ""; +const char password[] = ""; + +// Below infomation you can set after signing up with u-blox Thingstream portal +// and after add a new New PointPerfect Thing +// https://portal.thingstream.io/app/location-services/things +// in the new PointPerfect Thing you go to the credentials page and copy past the values and certificate into this. + +// -> Credentials -> Hostname +const char AWS_IOT_ENDPOINT[] = "pp.services.u-blox.com"; +const unsigned short AWS_IOT_PORT = 8883; +// -> Credentials -> AssistNow (MGA) topic +const char MQTT_TOPIC_ASSISTNOW[] = "/pp/ubx/mga"; + +// -> Credentials -> Client Id +static const char MQTT_CLIENT_ID[] = ""; + +// -> Credentials -> Amazon Root Certificate +static const char AWS_CERT_CA[] PROGMEM = R"EOF( +-----BEGIN CERTIFICATE----- + +-----END CERTIFICATE----- +)EOF"; + +// -> Credentials -> Client Certificate +static const char AWS_CERT_CRT[] PROGMEM = R"KEY( +-----BEGIN CERTIFICATE----- + +-----END CERTIFICATE----- +)KEY"; + +// Get this from Thingstream Portal +// -> Credentials -> Client Key +static const char AWS_CERT_PRIVATE[] PROGMEM = R"KEY( +-----BEGIN RSA PRIVATE KEY----- + +-----END RSA PRIVATE KEY----- +)KEY"; diff --git a/examples/Example30_NEO-D9S/Example30_NEO-D9S.ino b/examples/Example30_NEO-D9S/Example30_NEO-D9S.ino new file mode 100644 index 0000000..fa971d6 --- /dev/null +++ b/examples/Example30_NEO-D9S/Example30_NEO-D9S.ino @@ -0,0 +1,128 @@ +/* + NEO-D9S L-Band receiver example + By: SparkFun Electronics / Paul Clark + Date: March 7th, 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 display the NEO-D9S's received signal imbalance and magnitude, plus a summary of any received PMP data. + + Feel like supporting open source hardware? + Buy a board from SparkFun! + ZED-F9P RTK2: https://www.sparkfun.com/products/16481 + NEO-D9S: Coming soon! + + Hardware Connections: + Use a Qwiic cable to connect the NEO-D9S L-Band corection data receiver to your board + 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 //http://librarymanager/All#SparkFun_u-blox_GNSS +SFE_UBLOX_GNSS myLBand; // NEO-D9S + +const uint32_t myLBandFreq = 1556290000; // Uncomment this line to use the US SPARTN 1.8 service +//const uint32_t myLBandFreq = 1545260000; // Uncomment this line to use the EU SPARTN 1.8 service + +#define OK(ok) (ok ? F(" -> OK") : F(" -> ERROR!")) // Convert uint8_t into OK/ERROR + +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +// Callback: printRXMPMP will be called when new PMP data arrives +// See u-blox_structs.h for the full definition of UBX_RXM_PMP_data_t +// _____ You can use any name you like for the callback. Use the same name when you call setRXMPMPcallbackPtr +// / _____ This _must_ be UBX_RXM_PMP_data_t +// | / _____ You can use any name you like for the struct +// | | / +// | | | +void printRXMPMP(UBX_RXM_PMP_data_t *pmpData) +{ + Serial.println(F("New PMP data received:")); + + Serial.print(F("PMP message version: ")); + Serial.println(pmpData->version); + + Serial.print(F("numBytesUserData : ")); + Serial.println(pmpData->numBytesUserData); + + Serial.print(F("serviceIdentifier: ")); + Serial.println(pmpData->serviceIdentifier); + + Serial.print(F("uniqueWordBitErrors: ")); + Serial.println(pmpData->uniqueWordBitErrors); + + Serial.print(F("fecBits: ")); + Serial.println(pmpData->fecBits); + + Serial.print(F("ebno: ")); + Serial.println(pmpData->ebno); + + Serial.println(); +} + +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +void setup() +{ + Serial.begin(115200); + Serial.println(F("NEO-D9S Example")); + + Wire.begin(); //Start I2C + + //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + // Begin and configure the NEO-D9S L-Band receiver + + //myLBand.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + while (myLBand.begin(Wire, 0x43) == false) //Connect to the u-blox NEO-D9S using Wire port. The D9S default I2C address is 0x43 (not 0x42) + { + Serial.println(F("u-blox NEO-D9S not detected at default I2C address. Please check wiring.")); + delay(2000); + } + Serial.println(F("u-blox NEO-D9S connected")); + + uint8_t ok = myLBand.setVal32(UBLOX_CFG_PMP_CENTER_FREQUENCY, myLBandFreq); // Default 1539812500 Hz + if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_SEARCH_WINDOW, 2200); // Default 2200 Hz + if (ok) ok = myLBand.setVal8(UBLOX_CFG_PMP_USE_SERVICE_ID, 0); // Default 1 + if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_SERVICE_ID, 21845); // Default 50821 + if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_DATA_RATE, 2400); // Default 2400 bps + if (ok) ok = myLBand.setVal8(UBLOX_CFG_PMP_USE_DESCRAMBLER, 1); // Default 1 + if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_DESCRAMBLER_INIT, 26969); // Default 23560 + if (ok) ok = myLBand.setVal8(UBLOX_CFG_PMP_USE_PRESCRAMBLING, 0); // Default 0 + if (ok) ok = myLBand.setVal64(UBLOX_CFG_PMP_UNIQUE_WORD, 16238547128276412563ull); + if (ok) ok = myLBand.setVal(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 1); // Ensure UBX-RXM-PMP is enabled on the I2C port + if (ok) ok = myLBand.setVal(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART1, 1); // Output UBX-RXM-PMP on UART1 + if (ok) ok = myLBand.setVal(UBLOX_CFG_UART2OUTPROT_UBX, 1); // Enable UBX output on UART2 + if (ok) ok = myLBand.setVal(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2, 1); // Output UBX-RXM-PMP on UART2 + if (ok) ok = myLBand.setVal32(UBLOX_CFG_UART1_BAUDRATE, 38400); // match baudrate with ZED default + if (ok) ok = myLBand.setVal32(UBLOX_CFG_UART2_BAUDRATE, 38400); // match baudrate with ZED default + + Serial.print(F("L-Band: configuration ")); + Serial.println(OK(ok)); + + myLBand.softwareResetGNSSOnly(); // Do a restart + + myLBand.setRXMPMPcallbackPtr(&printRXMPMP); // Call printRXMPMP when new PMP data arrives +} + +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +void loop() +{ + myLBand.checkUblox(); // Check for the arrival of new PMP data and process it. + myLBand.checkCallbacks(); // Check if any LBand callbacks are waiting to be processed. + + UBX_MON_HW2_data_t hwStatus; // Create storage for the HW2 extended hardware status + if (myLBand.getHW2status(&hwStatus)) // Request the extended hardware status + { + // Print the signal imbalance and magnitude + Serial.print(F("Signal imbalance and magnitude: ofsI: ")); + Serial.print(hwStatus.ofsI); + Serial.print(F(" magI: ")); + Serial.print(hwStatus.magI); + Serial.print(F(" ofsQ: ")); + Serial.print(hwStatus.ofsQ); + Serial.print(F(" magQ: ")); + Serial.println(hwStatus.magQ); + } +} diff --git a/examples/ZED-F9P/Example18_PointPerfectClient/Example18_PointPerfectClient.ino b/examples/ZED-F9P/Example18_PointPerfectClient/Example18_PointPerfectClient.ino index b31cfa5..2edc5bb 100644 --- a/examples/ZED-F9P/Example18_PointPerfectClient/Example18_PointPerfectClient.ino +++ b/examples/ZED-F9P/Example18_PointPerfectClient/Example18_PointPerfectClient.ino @@ -138,6 +138,9 @@ void beginClient() wifiClient.setCACert(AWS_CERT_CA); wifiClient.setCertificate(AWS_CERT_CRT); wifiClient.setPrivateKey(AWS_CERT_PRIVATE); + mqttClient.setId(MQTT_CLIENT_ID); + mqttClient.setKeepAliveInterval(60*1000); + mqttClient.setConnectionTimeout( 5*1000); if (!mqttClient.connect(AWS_IOT_ENDPOINT, AWS_IOT_PORT)) { Serial.print(F("MQTT connection failed! Error code = ")); Serial.println(mqttClient.connectError()); diff --git a/examples/ZED-F9P/Example18_PointPerfectClient/secrets.h b/examples/ZED-F9P/Example18_PointPerfectClient/secrets.h index 4353c50..d206b1c 100644 --- a/examples/ZED-F9P/Example18_PointPerfectClient/secrets.h +++ b/examples/ZED-F9P/Example18_PointPerfectClient/secrets.h @@ -15,6 +15,9 @@ const char MQTT_TOPIC_KEY[] = "/pp/key/ip"; // -> Credentials -> IP correction topic for EU/US region const char MQTT_TOPIC_SPARTN[] = "/pp/ip/us"; // choice of {eu, us} +// -> Credentials -> Client Id +static const char MQTT_CLIENT_ID[] = ""; + // -> Credentials -> Amazon Root Certificate static const char AWS_CERT_CA[] PROGMEM = R"EOF( -----BEGIN CERTIFICATE----- diff --git a/examples/ZED-F9P/Example19_LBand_Corrections_with_NEO-D9S/Example19_LBand_Corrections_with_NEO-D9S.ino b/examples/ZED-F9P/Example19_LBand_Corrections_with_NEO-D9S/Example19_LBand_Corrections_with_NEO-D9S.ino index d012a16..a642ed7 100644 --- a/examples/ZED-F9P/Example19_LBand_Corrections_with_NEO-D9S/Example19_LBand_Corrections_with_NEO-D9S.ino +++ b/examples/ZED-F9P/Example19_LBand_Corrections_with_NEO-D9S/Example19_LBand_Corrections_with_NEO-D9S.ino @@ -187,6 +187,7 @@ void setup() if (ok) ok = myLBand.setVal64(UBLOX_CFG_PMP_UNIQUE_WORD, 16238547128276412563ull); if (ok) ok = myLBand.setVal(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 1); // Ensure UBX-RXM-PMP is enabled on the I2C port if (ok) ok = myLBand.setVal(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART1, 1); // Output UBX-RXM-PMP on UART1 + if (ok) ok = myLBand.setVal(UBLOX_CFG_UART2OUTPROT_UBX, 1); // Enable UBX output on UART2 if (ok) ok = myLBand.setVal(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2, 1); // Output UBX-RXM-PMP on UART2 if (ok) ok = myLBand.setVal32(UBLOX_CFG_UART1_BAUDRATE, 38400); // match baudrate with ZED default if (ok) ok = myLBand.setVal32(UBLOX_CFG_UART2_BAUDRATE, 38400); // match baudrate with ZED default diff --git a/keywords.txt b/keywords.txt index a281a07..9e34ac0 100644 --- a/keywords.txt +++ b/keywords.txt @@ -19,6 +19,7 @@ UBX_ESF_STATUS_sensorStatus_t KEYWORD1 UBX_CFG_ITFM_data_t KEYWORD1 UBX_MON_RF_data_t KEYWORD1 UBX_MON_HW_data_t KEYWORD1 +UBX_MON_HW2_data_t KEYWORD1 UBX_NAV_POSECEF_data_t KEYWORD1 UBX_NAV_STATUS_data_t KEYWORD1 @@ -195,6 +196,7 @@ setJammingConfiguration KEYWORD2 getRFinformation KEYWORD2 getHWstatus KEYWORD2 +getHW2status KEYWORD2 getAckAiding KEYWORD2 setAckAiding KEYWORD2 diff --git a/library.properties b/library.properties index c8350b1..56288d1 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SparkFun u-blox GNSS Arduino Library -version=2.2.5 +version=2.2.6 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 fb13a48..dd36b24 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -8232,6 +8232,32 @@ bool SFE_UBLOX_GNSS::getHWstatus(UBX_MON_HW_data_t *data, uint16_t maxWait) return (true); } +// Get the extended hardware status using UBX_MON_HW2 +bool SFE_UBLOX_GNSS::getHW2status(UBX_MON_HW2_data_t *data, uint16_t maxWait) +{ + if (data == NULL) // Check if the user forgot to include the data pointer + return (false); // Bail + + packetCfg.cls = UBX_CLASS_MON; + packetCfg.id = UBX_MON_HW2; + packetCfg.len = 0; + packetCfg.startingSpot = 0; + + if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK + return (false); + + // Extract the data + data->ofsI = extractSignedChar(&packetCfg, 0); + data->magI = extractByte(&packetCfg, 1); + data->ofsQ = extractSignedChar(&packetCfg, 2); + data->magQ = extractByte(&packetCfg, 3); + data->cfgSource = extractByte(&packetCfg, 4); + data->lowLevCfg = extractLong(&packetCfg, 8); // Low-level configuration (obsolete for protocol versions greater than 15.00) + data->postStatus = extractLong(&packetCfg, 20); + + return (true); +} + // UBX-CFG-NAVX5 - get/set the ackAiding byte. If ackAiding is 1, UBX-MGA-ACK messages will be sent by the module to acknowledge the MGA data uint8_t SFE_UBLOX_GNSS::getAckAiding(uint16_t maxWait) // Get the ackAiding byte - returns 255 if the sendCommand fails { diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index e81d7d0..45c4594 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h @@ -928,6 +928,9 @@ class SFE_UBLOX_GNSS // Hardware status (including jamming) bool getHWstatus(UBX_MON_HW_data_t *data = NULL, uint16_t maxWait = defaultMaxWait); // Get the hardware status using UBX_MON_HW + // Extended hardware status + bool getHW2status(UBX_MON_HW2_data_t *data = NULL, uint16_t maxWait = defaultMaxWait); // Get the extended hardware status using UBX_MON_HW2 + // UBX-CFG-NAVX5 - get/set the ackAiding byte. If ackAiding is 1, UBX-MGA-ACK messages will be sent by the module to acknowledge the MGA data uint8_t getAckAiding(uint16_t maxWait = defaultMaxWait); // Get the ackAiding byte - returns 255 if the sendCommand fails bool setAckAiding(uint8_t ackAiding, uint16_t maxWait = defaultMaxWait); // Set the ackAiding byte diff --git a/src/u-blox_structs.h b/src/u-blox_structs.h index 2a29822..3bef638 100644 --- a/src/u-blox_structs.h +++ b/src/u-blox_structs.h @@ -1734,6 +1734,23 @@ typedef struct uint8_t pullL; // Mask of pins value using the PIO pull low resistor } UBX_MON_HW_data_t; +// UBX-MON-HW2 (0x0A 0x0B): Extended hardware status +const uint16_t UBX_MON_HW2_LEN = 28; + +typedef struct +{ + int8_t ofsI; // Imbalance of I-part of complex signal, scaled (-128 = max. negative imbalance, 127 = max. positive imbalance) + uint8_t magI; // Magnitude of I-part of complex signal, scaled (0 = no signal, 255 = max. magnitude) + int8_t ofsQ; // Imbalance of Q-part of complex signal, scaled (-128 = max. negative imbalance, 127 = max. positive imbalance) + uint8_t magQ; // Magnitude of Q-part of complex signal, scaled (0 = no signal, 255 = max. magnitude) + uint8_t cfgSource; // Source of low-level configuration (114 = ROM, 111 = OTP, 112 = config pins, 102 = flash image) + uint8_t reserved0[3]; + uint32_t lowLevCfg; // Low-level configuration (obsolete for protocol versions greater than 15.00) + uint8_t reserved1[8]; + uint32_t postStatus; // POST status word + uint8_t reserved2[4]; // Reserved +} UBX_MON_HW2_data_t; + // UBX-MON-RF (0x0a 0x38): RF information const uint16_t UBX_MON_RF_MAX_BLOCKS = 2; // 0 = L1; 1 = L2 / L5 const uint16_t UBX_MON_RF_MAX_LEN = 4 + (24 * UBX_MON_RF_MAX_BLOCKS);