diff --git a/examples/Example20_SendCustomCommand/Example20_1_GetModuleInfo_by_SendCustomCommand.ino b/examples/Example20_SendCustomCommand/Example20_1_GetModuleInfo_by_SendCustomCommand.ino new file mode 100644 index 0000000..149a175 --- /dev/null +++ b/examples/Example20_SendCustomCommand/Example20_1_GetModuleInfo_by_SendCustomCommand.ino @@ -0,0 +1,201 @@ +/* + Send Custom Command + By: Paul Clark (PaulZC) + Date: April 20th, 2020 + + License: MIT. See license file for more information but you can + basically do whatever you want with this code. + + This example shows how you can create and send a custom UBX packet + using the SparkFun u-blox library. + + Previously it was possible to create and send a custom packet + through the library but it would always appear to timeout as + some of the internal functions referred to the internal private + struct packetCfg. + The most recent version of the library allows sendCommand to + use a custom packet as if it were packetCfg and so: + - sendCommand will return a sfe_ublox_status_e enum as if + it had been called from within the library + - the custom packet will be updated with data returned by the module + (previously this was not possible from outside the library) + + 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 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 + +//#include //Needed for I2C to GPS + +#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS + +class SFE_UBLOX_GPS_ADD : public SFE_UBLOX_GPS +{ +public: + boolean getModuleInfo(uint16_t maxWait = 500); //Queries module, texts + + struct minfoStructure + { + char swVersion[30]; + char hwVersion[10]; + uint8_t extensionNo =0; + char extension[10][30]; + } minfo; +}; + +SFE_UBLOX_GPS_ADD myGPS; + +void setup() +{ + SoftwareSerial Serial2(2, 3); + uint32_t baud = 9600; + + Serial.begin(115200); // You may need to increase this for high navigation rates! + while (!Serial) + ; //Wait for user to open terminal + Serial.println("SparkFun Ublox Example"); + + Serial2.begin(baud); + Serial.print("Connecting GPS at 9600 baud"); + + while (!myGPS.begin(Serial2)) // Typically, default baud rate is 9600, But if any other rate, it's displayed and stopped. + { + Serial.println("... is failed."); + + if (baud == 38400) + { + baud = 57600; + } + else if (baud > 115200) + { + baud = 9600; + } + else + { + baud *= 2; + } + Serial.print("Connecting GPS at "); + Serial.print(baud); + Serial.print(" baud"); + Serial2.begin(baud); + } + Serial.println(" is success!"); + if (baud > 19200) + { + Serial.println("Change baud lower than 19200 first! Freezing.."); + while (1) + ; + } + myGPS.setAutoPVT(false); +// delay(200); + myGPS.enableDebugging(); + Serial.print("Polling module info "); + while (myGPS.getModuleInfo(1000) == false) + { + delay(500); + Serial.print("."); + } + Serial.println(); + Serial.println(); + Serial.println("Module Info : "); + Serial.print("Soft version: "); + Serial.println(myGPS.minfo.swVersion); + Serial.print("Hard version: "); + Serial.println(myGPS.minfo.hwVersion); + Serial.print("Extensions:"); + Serial.println(myGPS.minfo.extensionNo); + for (int i = 0; i < myGPS.minfo.extensionNo; i++) + { + Serial.print(" "); + Serial.println(myGPS.minfo.extension[i]); + } + Serial.println(); + Serial.println("Done!"); + +} + +void loop() +{ + +} + +boolean SFE_UBLOX_GPS_ADD::getModuleInfo(uint16_t maxWait) +{ + myGPS.minfo.hwVersion[0] = NULL; + myGPS.minfo.swVersion[0] = NULL; + for (int i = 0; i < 10; i++) + myGPS.minfo.extension[i][0] = NULL; + + // Let's create our custom packet + uint8_t customPayload[MAX_PAYLOAD_SIZE]; // This array holds the payload data bytes + + // The next line creates and initialises the packet information which wraps around the payload + ubxPacket customCfg = {0, 0, 0, 0, 0, customPayload, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED}; + + // The structure of ubxPacket is: + // uint8_t cls : The message Class + // uint8_t id : The message ID + // uint16_t len : Length of the payload. Does not include cls, id, or checksum bytes + // uint16_t counter : Keeps track of number of overall bytes received. Some responses are larger than 255 bytes. + // uint16_t startingSpot : The counter value needed to go past before we begin recording into payload array + // uint8_t *payload : The payload + // uint8_t checksumA : Given to us by the module. Checked against the rolling calculated A/B checksums. + // uint8_t checksumB + // sfe_ublox_packet_validity_e valid : Goes from NOT_DEFINED to VALID or NOT_VALID when checksum is checked + // sfe_ublox_packet_validity_e classAndIDmatch : Goes from NOT_DEFINED to VALID or NOT_VALID when the Class and ID match the requestedClass and requestedID + + // sendCommand will return: + // SFE_UBLOX_STATUS_DATA_RECEIVED if the data we requested was read / polled successfully + // SFE_UBLOX_STATUS_DATA_SENT if the data we sent was writted successfully (ACK'd) + // Other values indicate errors. Please see the sfe_ublox_status_e enum for further details. + + // Referring to the u-blox M8 Receiver Description and Protocol Specification we see that + // the navigation rate is configured using the UBX-CFG-RATE message. So let's load our + // custom packet with the correct information so we can read (poll / get) the current settings. + + customCfg.cls = UBX_CLASS_MON; // This is the message Class + customCfg.id = UBX_MON_VER; // This is the message ID + customCfg.len = 0; // Setting the len (length) to zero let's us poll the current settings + customCfg.startingSpot = 0; // Always set the startingSpot to zero (unless you really know what you are doing) + + // We also need to tell sendCommand how long it should wait for a reply +// uint16_t maxWait = 250; // Wait for up to 250ms (Serial may need a lot longer e.g. 1100) + + if (sendCommand(&customCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) + return (false); //If command send fails then bail + + uint16_t position = 0; + for (int i = 0; i < 30; i++) + { + minfo.swVersion[i] = customPayload[position]; + position++; + } + for (int i = 0; i < 10; i++) + { + minfo.hwVersion[i] = customPayload[position]; + position++; + } + + while (customCfg.len >= position + 30) + { + for (int i = 0; i < 30; i++) + { + minfo.extension[minfo.extensionNo][i] = customPayload[position]; + position++; + } + minfo.extensionNo++; + if(minfo.extensionNo>9) + break; + } + + return (true); //We failed +} \ No newline at end of file diff --git a/examples/Example8_GetProtocolVersion/Example8_1_GetModuleInfoOnUART.ino b/examples/Example8_GetProtocolVersion/Example8_1_GetModuleInfoOnUART.ino new file mode 100644 index 0000000..cf3b092 --- /dev/null +++ b/examples/Example8_GetProtocolVersion/Example8_1_GetModuleInfoOnUART.ino @@ -0,0 +1,95 @@ +/* + Reading the Information texts of a Ublox module + By: mayopan + https://github.com/mayopan + Date: May 4th, 2020 + License: MIT. See license file for more information but you can + basically do whatever you want with this code. + + This example shows how to get Ublox module information in text. + It's for UART connection to GPS. + Standard adruino board using ATmega328 like Uno, nano, mini has only one UART port. + So this example uses SoftwareSerial library that has limitation on the serial baud rate. + At 38400 or higher baud, the packets will be lost and you can't get data correctly. + If so, you have to change serial rate to lower one refer to example12. + If your board has multiple hardware UART port, use them instead of SoftwareSerial, of course! + + Hardware Connections: + Connect the U-Blox serial TX pin to Uno pin 2 + Connect the U-Blox serial RX pin to Uno pin 3 + Open the serial monitor at 115200 baud to see the output +*/ + +#include +#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS + +SFE_UBLOX_GPS myGPS; + +void setup() +{ + int32_t baud = 9600; + Serial.begin(115200); + while (!Serial); //Wait for user to open terminal + Serial.println("SparkFun Ublox Example"); + SoftwareSerial Serial2(2,3); //If your board has multiple UART ports, comment out this line to use hardware serial. + + Serial2.begin(baud); + Serial.print("Connecting GPS at 9600 baud"); + + while (!myGPS.begin(Serial2))// Typically, default baud rate is 9600, But if any other rate, it's displayed and stopped. + { + Serial.println("... is failed."); + + if (baud == 38400) + { + baud = 57600; + } + else if(baud > 115200) + { + baud = 9600; + } + else + { + baud *= 2; + } + Serial.print("Connecting GPS at "); + Serial.print(baud); + Serial.print(" baud"); + Serial2.begin(baud); + } + Serial.println(" is success!"); + if(baud > 19200) + { + Serial.println("Change baud lower than 38400 first! Freezing.."); + while(1) + ; + } + +// myGPS.setAutoPVT(false); + Serial.print("Polling module info "); + while (myGPS.getModuleInfo() == false) + { + delay(1000); + Serial.print("."); + } + Serial.println(); + Serial.println(); + Serial.println("Module Info : "); + Serial.print("Soft version: "); + Serial.println(myGPS.minfo.swVersion); + Serial.print("Hard version: "); + Serial.println(myGPS.minfo.hwVersion); + Serial.println("Extensions:"); + for (int i = 0; i < myGPS.minfo.extensionNo; i++) + { + Serial.print(" "); + Serial.println(myGPS.minfo.extension[i]); + } + Serial.println(); + Serial.println("Done!"); + } + +void loop() +{ + //Do nothing +} \ No newline at end of file diff --git a/src/SparkFun_Ublox_Arduino_Library.cpp b/src/SparkFun_Ublox_Arduino_Library.cpp index 56b64ae..1c7cc27 100644 --- a/src/SparkFun_Ublox_Arduino_Library.cpp +++ b/src/SparkFun_Ublox_Arduino_Library.cpp @@ -3081,6 +3081,44 @@ boolean SFE_UBLOX_GPS::getProtocolVersion(uint16_t maxWait) return (false); //We failed } +//Get the information of the Ublox module we're communicating with +//They are strings, so easy to read. Parsing is up to you! +boolean SFE_UBLOX_GPS::getModuleInfo(uint16_t maxWait) +{ + //Send packet with only CLS and ID, length of zero. This will cause the module to respond with the contents of that CLS/ID. + packetCfg.cls = UBX_CLASS_MON; + packetCfg.id = UBX_MON_VER; + packetCfg.len = 0; + packetCfg.startingSpot = 0; + + if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) + return (false); //If command send fails then bail + + int position = 0; + for (int i = 0; i < 30; i++) + { + minfo.swVersion[i] = payloadCfg[position]; + position++; + } + for (int i = 0; i < 10; i++) + { + minfo.hwVersion[i] = payloadCfg[position]; + position++; + } + + while (packetCfg.len >= position + 30) + { + for (int i = 0; i < 30; i++) + { + minfo.extension[minfo.extensionNo][i] = payloadCfg[position]; + position++; + } + minfo.extensionNo++; + } + + return (true); //We failed +} + //Mark all the PVT data as read/stale. This is handy to get data alignment after CRC failure void SFE_UBLOX_GPS::flushPVT() { diff --git a/src/SparkFun_Ublox_Arduino_Library.h b/src/SparkFun_Ublox_Arduino_Library.h index 97bc353..6e22e0d 100644 --- a/src/SparkFun_Ublox_Arduino_Library.h +++ b/src/SparkFun_Ublox_Arduino_Library.h @@ -609,6 +609,7 @@ class SFE_UBLOX_GPS uint8_t getProtocolVersionHigh(uint16_t maxWait = 500); //Returns the PROTVER XX.00 from UBX-MON-VER register uint8_t getProtocolVersionLow(uint16_t maxWait = 500); //Returns the PROTVER 00.XX from UBX-MON-VER register boolean getProtocolVersion(uint16_t maxWait = 500); //Queries module, loads low/high bytes + boolean getModuleInfo(uint16_t maxWait = 500); //Queries module, texts boolean getRELPOSNED(uint16_t maxWait = 1100); //Get Relative Positioning Information of the NED frame @@ -678,6 +679,15 @@ class SFE_UBLOX_GPS bool refObsMiss; } relPosInfo; + //Module infomation + struct minfoStructure + { + char swVersion[30]; + char hwVersion[10]; + uint8_t extensionNo; + char extension[10][30]; + } minfo; + //The major datums we want to globally store uint16_t gpsYear; uint8_t gpsMonth;