v2.9
This commit is contained in:
@ -0,0 +1,161 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
#define NAV_RATE 20 // The new navigation rate in Hz (measurements per second)
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
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");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages
|
||||
|
||||
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)
|
||||
|
||||
// Let's configure the module's navigation rate as if we were using setNavigationFrequency
|
||||
|
||||
// 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_CFG; // This is the message Class
|
||||
customCfg.id = UBX_CFG_RATE; // 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)
|
||||
|
||||
// Now let's read the current navigation rate. The results will be loaded into customCfg.
|
||||
if (myGPS.sendCommand(&customCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK
|
||||
{
|
||||
Serial.println(F("sendCommand (poll / get) failed! Freezing..."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
// Referring to the message definition for UBX-CFG-RATE we see that the measurement rate
|
||||
// is stored in payload bytes 0 and 1 as a uint16_t in LSB-first (little endian) format
|
||||
|
||||
uint16_t rate = (customPayload[1] << 8) | customPayload[0]; // Extract the current rate (ms)
|
||||
float f_rate = 1000.0 / ((float)rate); // Convert the navigation rate to Hz (measurements per second)
|
||||
|
||||
// Print the current measurement rate
|
||||
Serial.print(F("The current measurement rate is: "));
|
||||
Serial.println(f_rate, 1);
|
||||
|
||||
// Let's change it
|
||||
rate = 1000 / NAV_RATE; // Load the new value into rate
|
||||
customPayload[0] = rate & 0xFF; // Store it in the payload
|
||||
customPayload[1] = rate >> 8;
|
||||
|
||||
// Print the new measurement rate
|
||||
Serial.print(F("The new measurement rate will be: "));
|
||||
Serial.println(NAV_RATE);
|
||||
|
||||
// We don't need to update customCfg.len as it will have been set to 6
|
||||
// when sendCommand read the data
|
||||
|
||||
// Now we write the custom packet back again to change the setting
|
||||
if (myGPS.sendCommand(&customCfg, maxWait) != SFE_UBLOX_STATUS_DATA_SENT) // This time we are only expecting an ACK
|
||||
{
|
||||
Serial.println(F("sendCommand (set) failed! Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("Navigation rate updated. Here we go..."));
|
||||
}
|
||||
|
||||
myGPS.setAutoPVT(true); // Enable AutoPVT. The module will generate measurements automatically without being polled.
|
||||
|
||||
//myGPS.saveConfigSelective(VAL_CFG_SUBSEC_NAVCONF); //Uncomment this line to save only the NAV settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query the module as fast as possible
|
||||
int32_t latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
int32_t longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Lon: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
int32_t altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.println(F(" (mm)"));
|
||||
}
|
Reference in New Issue
Block a user