v2.9
This commit is contained in:
@ -0,0 +1,66 @@
|
||||
/*
|
||||
By: Elias Santistevan
|
||||
SparkFun Electronics
|
||||
Date: May, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
NEO-M8U: https://www.sparkfun.com/products/16329
|
||||
ZED-F9R: https://www.sparkfun.com/products/16344
|
||||
|
||||
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
|
||||
|
||||
To take advantage of the internal IMU of either the Dead Reckoning GPS
|
||||
boards (ZED-F9R, NEO-M8U), you must first calibrate it. This includes securing the GPS module
|
||||
to your vehicle so that it is stable within 2 degrees and that the frame of
|
||||
reference of the board is consistent with the picture outlined in the
|
||||
Receiver-Description-Prot-Spec Datasheet under Automotive/Untethered Dead
|
||||
Reckoning. You may also check either the ZED-F9R or NEO-M8U Hookup Guide for
|
||||
more information. After the board is secure, you'll need to put the module
|
||||
through certain conditions for proper calibration: acceleration, turning,
|
||||
stopping for a few minutes, getting to a speed over 30km/h all under a clear sky
|
||||
with good GNSS signal. This example simply looks at the
|
||||
"fusionMode" status which indicates whether the SparkFun Dead Reckoning is
|
||||
not-calibrated - 0, or calibrated - 1.
|
||||
*/
|
||||
|
||||
#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);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun Ublox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (myGPS.getEsfInfo()){
|
||||
Serial.print(F("Fusion Mode: "));
|
||||
Serial.println(myGPS.imuMeas.fusionMode);
|
||||
if (myGPS.imuMeas.fusionMode == 1)
|
||||
Serial.println(F("Sensor is calibrated!"));
|
||||
}
|
||||
|
||||
delay(250);
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
By: Elias Santistevan
|
||||
SparkFun Electronics
|
||||
Date: May, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
NEO-M8U: https://www.sparkfun.com/products/16329
|
||||
ZED-F9R: https://www.sparkfun.com/products/16344
|
||||
|
||||
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
|
||||
|
||||
After calibrating the module, also known as "Fusion Mode", you can get
|
||||
data directly from the IMU. This data is integrated directly into the GNSS
|
||||
output, but is provided by the module as well.
|
||||
|
||||
*/
|
||||
|
||||
#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);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun Ublox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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)
|
||||
|
||||
if (myGPS.getEsfInfo()){
|
||||
|
||||
Serial.print(F("Fusion Mode: "));
|
||||
Serial.println(myGPS.imuMeas.fusionMode);
|
||||
|
||||
if (myGPS.imuMeas.fusionMode == 1){
|
||||
Serial.println(F("Fusion Mode is Initialized!"));
|
||||
}
|
||||
else {
|
||||
Serial.println(F("Fusion Mode is either disabled or not initialized - Freezing!"));
|
||||
Serial.println(F("Please see Example 1 description at top for more information."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (myGPS.getEsfIns())
|
||||
{
|
||||
Serial.print(F("X: "));
|
||||
Serial.println(myGPS.imuMeas.xAngRate);
|
||||
Serial.print(F("Y: "));
|
||||
Serial.println(myGPS.imuMeas.yAngRate);
|
||||
Serial.print(F("Z: "));
|
||||
Serial.println(myGPS.imuMeas.zAngRate);
|
||||
Serial.print(F("X Acceleration: "));
|
||||
Serial.println(myGPS.imuMeas.xAccel);
|
||||
Serial.print(F("Y Acceleration: "));
|
||||
Serial.println(myGPS.imuMeas.yAccel);
|
||||
Serial.print(F("Z Acceleration: "));
|
||||
Serial.println(myGPS.imuMeas.zAccel);
|
||||
// These values also have "validity checks" that can be provided by the
|
||||
// ublox library, add "Vald" to values: e.g. xAngRateVald or xAccelVald.
|
||||
}
|
||||
|
||||
delay(250);
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
By: Elias Santistevan
|
||||
SparkFun Electronics
|
||||
Date: May, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
NEO-M8U: https://www.sparkfun.com/products/16329
|
||||
ZED-F9R: https://www.sparkfun.com/products/16344
|
||||
|
||||
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
|
||||
|
||||
After calibrating the module, also known as "Fusion Mode", you can get
|
||||
data directly from the IMU. This example code walks you through trouble
|
||||
shooting or identifying the different states of any individual
|
||||
"external" (which include internal) sensors you've hooked up (vehicle speed
|
||||
sensor) or the internal IMU used by the modules. You can see if the sensor is
|
||||
being used, if it's calibrated, ready, what data type it returns, the state
|
||||
of the measurement etc.
|
||||
|
||||
*/
|
||||
|
||||
#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);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun Ublox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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)
|
||||
|
||||
// GetEsfInfo also gets the number of sensors used by the ublox module, this
|
||||
// includes (in the case of the ZED-F9R) wheel tick input from the vehicle
|
||||
// speed sensor attached to the module.
|
||||
if (myGPS.getEsfInfo()){
|
||||
|
||||
Serial.print(F("Fusion Mode: "));
|
||||
Serial.println(myGPS.imuMeas.fusionMode);
|
||||
|
||||
if (myGPS.imuMeas.fusionMode == 1){
|
||||
Serial.println(F("Fusion Mode is Initialized!"));
|
||||
}
|
||||
else {
|
||||
Serial.println(F("Fusion Mode is either disabled or not initialized - Freezing!"));
|
||||
Serial.println(F("Please see Example 1 description at top for more information."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
for(int i=1; i<=myGPS.ubloxSen.numSens; i++){
|
||||
myGPS.getSensState(i); // Give the sensor you want to check on.
|
||||
Serial.print(F("Sensor Data Type: ")); //See ublox receiver description
|
||||
//or our hookup guide for information on the
|
||||
//return value.
|
||||
Serial.println(myGPS.ubloxSen.senType);
|
||||
Serial.print(F("Being Used: "));
|
||||
Serial.println(myGPS.ubloxSen.isUsed);
|
||||
Serial.print(F("Is Ready: "));
|
||||
Serial.println(myGPS.ubloxSen.isReady);
|
||||
Serial.print(F("Calibration Status: "));
|
||||
Serial.println(myGPS.ubloxSen.calibStatus);
|
||||
Serial.print(F("Time Status: "));
|
||||
Serial.println(myGPS.ubloxSen.timeStatus);
|
||||
Serial.print(F("Bad Measure: "));
|
||||
Serial.println(myGPS.ubloxSen.timeStatus);
|
||||
Serial.print(F("Bad Time Tag: "));
|
||||
Serial.println(myGPS.ubloxSen.badTag);
|
||||
Serial.print(F("Missed Measure : "));
|
||||
Serial.println(myGPS.ubloxSen.missMeas);
|
||||
Serial.print(F("Noisy Measure: "));
|
||||
Serial.println(myGPS.ubloxSen.noisyMeas);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
By: Elias Santistevan
|
||||
SparkFun Electronics
|
||||
Date: May, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
NEO-M8U: https://www.sparkfun.com/products/16329
|
||||
ZED-F9R: https://www.sparkfun.com/products/16344
|
||||
|
||||
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
|
||||
|
||||
After calibrating the module and securing it to your vehicle such that it's
|
||||
stable within 2 degrees, and the board is oriented correctly with regards to
|
||||
the vehicle's frame, you can now read the vehicle's "attitude". The attitude
|
||||
includes the vehicle's heading, pitch, and roll. You can also check the
|
||||
accuracy of those readings.
|
||||
|
||||
*/
|
||||
|
||||
#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);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun Ublox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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)
|
||||
|
||||
if (myGPS.getEsfInfo()){
|
||||
|
||||
Serial.print(F("Fusion Mode: "));
|
||||
Serial.println(myGPS.imuMeas.fusionMode);
|
||||
|
||||
if (myGPS.imuMeas.fusionMode == 1){
|
||||
Serial.println(F("Fusion Mode is Initialized!"));
|
||||
}
|
||||
else {
|
||||
Serial.println(F("Fusion Mode is either disabled or not initialized - Freezing!"));
|
||||
Serial.println(F("Please see Example 1 description at top for more information."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.getVehAtt(); // Give the sensor you want to check on.
|
||||
Serial.print(F("Roll: "));
|
||||
Serial.println(myGPS.vehAtt.roll);
|
||||
Serial.print(F("Pitch: "));
|
||||
Serial.println(myGPS.vehAtt.pitch);
|
||||
Serial.print(F("Heading: "));
|
||||
Serial.println(myGPS.vehAtt.heading);
|
||||
Serial.print(F("Roll Accuracy: "));
|
||||
Serial.println(myGPS.vehAtt.accRoll);
|
||||
Serial.print(F("Pitch Accuracy: "));
|
||||
Serial.println(myGPS.vehAtt.accPitch);
|
||||
Serial.print(F("Heading Accuracy: "));
|
||||
Serial.println(myGPS.vehAtt.accHeading);
|
||||
|
||||
delay(250);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
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 High Navigation Rate on the NEO-M8U and then
|
||||
polls and displays the attitude solution, vehicle dynamics information
|
||||
and high rate position, velocity and time.
|
||||
|
||||
This example polls the high rate data.
|
||||
(The next example uses "autoHNR" to receive the HNR data automatically.)
|
||||
|
||||
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 <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);
|
||||
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("Warning! u-blox GPS did not begin correctly."));
|
||||
Serial.println(F("(This may be because the I2C port is busy with HNR messages.)"));
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if (myGPS.setHNRNavigationRate(10) == true) //Set the High Navigation Rate to 10Hz
|
||||
Serial.println(F("setHNRNavigationRate was successful"));
|
||||
else
|
||||
Serial.println(F("setHNRNavigationRate was NOT successful"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Poll and print selected HNR data
|
||||
if (myGPS.getHNRAtt(125) == true) // Request HNR Att data using a 125ms timeout
|
||||
{
|
||||
Serial.print(F("Roll: "));
|
||||
Serial.print(myGPS.hnrAtt.roll);
|
||||
Serial.print(F(" Pitch: "));
|
||||
Serial.print(myGPS.hnrAtt.pitch);
|
||||
Serial.print(F(" Heading: "));
|
||||
Serial.println(myGPS.hnrAtt.heading);
|
||||
}
|
||||
if (myGPS.getHNRDyn(125) == true) // Request HNR Dyn data using a 125ms timeout
|
||||
{
|
||||
Serial.print(F("xAccel: "));
|
||||
Serial.print(myGPS.hnrVehDyn.xAccel);
|
||||
Serial.print(F(" yAccel: "));
|
||||
Serial.print(myGPS.hnrVehDyn.yAccel);
|
||||
Serial.print(F(" zAccel: "));
|
||||
Serial.println(myGPS.hnrVehDyn.zAccel);
|
||||
}
|
||||
if (myGPS.getHNRPVT(125) == true) // Request HNR PVT data using a 125ms timeout
|
||||
{
|
||||
Serial.print(F("ns: "));
|
||||
Serial.print(myGPS.hnrPVT.nano);
|
||||
Serial.print(F(" Lat: "));
|
||||
Serial.print(myGPS.hnrPVT.lat);
|
||||
Serial.print(F(" Lon: "));
|
||||
Serial.println(myGPS.hnrPVT.lon);
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
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 High Navigation Rate on the NEO-M8U and then
|
||||
reads and displays the attitude solution, vehicle dynamics information
|
||||
and high rate position, velocity and time.
|
||||
|
||||
This example uses "autoHNR" to receive the HNR data automatically.
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
boolean usingAutoHNRAtt = false;
|
||||
boolean usingAutoHNRDyn = false;
|
||||
boolean usingAutoHNRPVT = false;
|
||||
|
||||
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("Warning! u-blox GPS did not begin correctly."));
|
||||
Serial.println(F("(This may be because the I2C port is busy with HNR messages.)"));
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if (myGPS.setHNRNavigationRate(10) == true) //Set the High Navigation Rate to 10Hz
|
||||
Serial.println(F("setHNRNavigationRate was successful"));
|
||||
else
|
||||
Serial.println(F("setHNRNavigationRate was NOT successful"));
|
||||
|
||||
usingAutoHNRAtt = myGPS.setAutoHNRAtt(true); //Attempt to enable auto HNR attitude messages
|
||||
usingAutoHNRDyn = myGPS.setAutoHNRDyn(true); //Attempt to enable auto HNR vehicle dynamics messages
|
||||
usingAutoHNRPVT = myGPS.setAutoHNRPVT(true); //Attempt to enable auto HNR PVT messages
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (usingAutoHNRAtt && (myGPS.getHNRAtt() == true)) // If setAutoHNRAtt was successful and new data is available
|
||||
{
|
||||
Serial.print(F("Roll: ")); // Print selected data
|
||||
Serial.print(myGPS.hnrAtt.roll);
|
||||
Serial.print(F(" Pitch: "));
|
||||
Serial.print(myGPS.hnrAtt.pitch);
|
||||
Serial.print(F(" Heading: "));
|
||||
Serial.println(myGPS.hnrAtt.heading);
|
||||
}
|
||||
if (usingAutoHNRDyn && (myGPS.getHNRDyn() == true)) // If setAutoHNRDyn was successful and new data is available
|
||||
{
|
||||
Serial.print(F("xAccel: ")); // Print selected data
|
||||
Serial.print(myGPS.hnrVehDyn.xAccel);
|
||||
Serial.print(F(" yAccel: "));
|
||||
Serial.print(myGPS.hnrVehDyn.yAccel);
|
||||
Serial.print(F(" zAccel: "));
|
||||
Serial.println(myGPS.hnrVehDyn.zAccel);
|
||||
}
|
||||
if (usingAutoHNRPVT && (myGPS.getHNRPVT() == true)) // If setAutoHNRPVT was successful and new data is available
|
||||
{
|
||||
Serial.print(F("ns: ")); // Print selected data
|
||||
Serial.print(myGPS.hnrPVT.nano);
|
||||
Serial.print(F(" Lat: "));
|
||||
Serial.print(myGPS.hnrPVT.lat);
|
||||
Serial.print(F(" Lon: "));
|
||||
Serial.println(myGPS.hnrPVT.lon);
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
Reading two altitudes - Mean Sea Level and Ellipsode
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query a Ublox module for its lat/long/altitude.
|
||||
|
||||
getAltitude() reports mm above ellipsode model of the globe. There are some
|
||||
instances where altitude above Mean Sea Level is better. This example shows how
|
||||
to use getAltitudeMSL(). The difference varies but is ~20m.
|
||||
Ellipsoid model: https://www.esri.com/news/arcuser/0703/geoid1of3.html
|
||||
Difference between Ellipsoid Model and Mean Sea Level: https://eos-gnss.com/elevation-for-beginners/
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Tracks the passing of 2000ms (2 seconds)
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
long altitudeMSL = myGPS.getAltitudeMSL();
|
||||
Serial.print(F(" AltMSL: "));
|
||||
Serial.print(altitudeMSL);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
Send command to reset module over I2C
|
||||
By: Nathan Seidle
|
||||
Date: January 29rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to reset the U-Blox module to factory defaults over I2C.
|
||||
|
||||
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 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 <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
while (Serial.available()) Serial.read(); //Trash any incoming chars
|
||||
Serial.println("Press a key to reset module to factory defaults");
|
||||
while (Serial.available() == false) ; //Wait for user to send character
|
||||
|
||||
myGPS.factoryReset(); //Reset everything: baud rate, I2C address, update rate, everything.
|
||||
|
||||
if (myGPS.begin() == false) //Attempt to re-connect
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
Serial.println("Unit has now been factory reset. Freezing...");
|
||||
while(1);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
Test baud rate changes on serial, factory reset, and hard reset.
|
||||
By: Thorsten von Eicken
|
||||
Date: January 29rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to reset the U-Blox module to factory defaults over serial.
|
||||
|
||||
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:
|
||||
Connect the U-Blox serial port to Serial1
|
||||
If you're using an Uno or don't have a 2nd serial port (Serial1), consider using software serial
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
int state = 0; // steps through auto-baud, reset, etc states
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print("===== STATE ");
|
||||
Serial.println(state);
|
||||
switch (state) {
|
||||
case 0: // auto-baud connection, then switch to 38400 and save config
|
||||
do {
|
||||
Serial.println("GPS: trying 38400 baud");
|
||||
Serial1.begin(38400);
|
||||
if (myGPS.begin(Serial1)) break;
|
||||
|
||||
delay(100);
|
||||
Serial.println("GPS: trying 9600 baud");
|
||||
Serial1.begin(9600);
|
||||
if (myGPS.begin(Serial1)) {
|
||||
Serial.println("GPS: connected at 9600 baud, switching to 38400");
|
||||
myGPS.setSerialRate(38400);
|
||||
delay(100);
|
||||
} else {
|
||||
delay(2000); //Wait a bit before trying again to limit the Serial output flood
|
||||
}
|
||||
} while(1);
|
||||
myGPS.setUART1Output(COM_TYPE_UBX); //Set the UART port to output UBX only
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
Serial.println("GPS serial connected, saved config");
|
||||
state++;
|
||||
break;
|
||||
case 1: // hardReset, expect to see GPS back at 38400 baud
|
||||
Serial.println("Issuing hardReset (cold start)");
|
||||
myGPS.hardReset();
|
||||
delay(1000);
|
||||
Serial1.begin(38400);
|
||||
if (myGPS.begin(Serial1)) {
|
||||
Serial.println("Success.");
|
||||
state++;
|
||||
} else {
|
||||
Serial.println("*** GPS did not respond at 38400 baud, starting over.");
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 2: // factoryReset, expect to see GPS back at 9600 baud
|
||||
Serial.println("Issuing factoryReset");
|
||||
myGPS.factoryReset();
|
||||
delay(2000); // takes more than one second... a loop to resync would be best
|
||||
Serial1.begin(9600);
|
||||
if (myGPS.begin(Serial1)) {
|
||||
Serial.println("Success.");
|
||||
state++;
|
||||
} else {
|
||||
Serial.println("*** GPS did not come back at 9600 baud, starting over.");
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 3: // print version info
|
||||
Serial.print("GPS protocol version: ");
|
||||
Serial.print(myGPS.getProtocolVersionHigh());
|
||||
Serial.print('.');
|
||||
Serial.print(myGPS.getProtocolVersionLow());
|
||||
state = 0;
|
||||
}
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
Reading lat and long via UBX binary commands using UART @38400 baud - free from I2C
|
||||
By: Nathan Seidle, Adapted from Example3_GetPosition by Thorsten von Eicken
|
||||
SparkFun Electronics
|
||||
Date: January 28rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the library and U-Blox for serial port use as well as
|
||||
switching the module from the default 9600 baud to 38400.
|
||||
|
||||
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
|
||||
to something google maps understands simply divide the numbers by 10,000,000. We
|
||||
do this so that we don't have to use floating point numbers.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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:
|
||||
Connect the U-Blox serial TX pin to Uno pin 10
|
||||
Connect the U-Blox serial RX pin to Uno pin 11
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial mySerial(10, 11); // RX, TX. Pin 10 on Uno goes to TX pin on GPS module.
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount of I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
//Assume that the U-Blox GPS is running at 9600 baud (the default) or at 38400 baud.
|
||||
//Loop until we're in sync and then ensure it's at 38400 baud.
|
||||
do {
|
||||
Serial.println("GPS: trying 38400 baud");
|
||||
mySerial.begin(38400);
|
||||
if (myGPS.begin(mySerial) == true) break;
|
||||
|
||||
delay(100);
|
||||
Serial.println("GPS: trying 9600 baud");
|
||||
mySerial.begin(9600);
|
||||
if (myGPS.begin(mySerial) == true) {
|
||||
Serial.println("GPS: connected at 9600 baud, switching to 38400");
|
||||
myGPS.setSerialRate(38400);
|
||||
delay(100);
|
||||
} else {
|
||||
//myGPS.factoryReset();
|
||||
delay(2000); //Wait a bit before trying again to limit the Serial output
|
||||
}
|
||||
} while(1);
|
||||
Serial.println("GPS serial connected");
|
||||
|
||||
myGPS.setUART1Output(COM_TYPE_UBX); //Set the UART port to output UBX only
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
Configuring the GPS to automatically send position reports over I2C
|
||||
By: Nathan Seidle and Thorsten von Eicken
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the U-Blox GPS the send navigation reports automatically
|
||||
and retrieving the latest one via getPVT. This eliminates the blocking in getPVT while the GPS
|
||||
produces a fresh navigation solution at the expense of returning a slighly old solution.
|
||||
|
||||
This can be used over serial or over I2C, this example shows the I2C use. With serial the GPS
|
||||
simply outputs the UBX_NAV_PVT packet. With I2C it queues it into its internal I2C buffer (4KB in
|
||||
size?) where it can be retrieved in the next I2C poll.
|
||||
|
||||
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 <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);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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.setNavigationFrequency(2); //Produce two solutions per second
|
||||
myGPS.setAutoPVT(true); //Tell the GPS to "send" each solution
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Calling getPVT returns true if there actually is a fresh navigation solution available.
|
||||
// Start the reading only when valid LLH is available
|
||||
if (myGPS.getPVT() && (myGPS.getInvalidLlh() == false))
|
||||
{
|
||||
Serial.println();
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
int PDOP = myGPS.getPDOP();
|
||||
Serial.print(F(" PDOP: "));
|
||||
Serial.print(PDOP);
|
||||
Serial.print(F(" (10^-2)"));
|
||||
|
||||
int nedNorthVel = myGPS.getNedNorthVel();
|
||||
Serial.print(F(" VelN: "));
|
||||
Serial.print(nedNorthVel);
|
||||
Serial.print(F(" (mm/s)"));
|
||||
|
||||
int nedEastVel = myGPS.getNedEastVel();
|
||||
Serial.print(F(" VelE: "));
|
||||
Serial.print(nedEastVel);
|
||||
Serial.print(F(" (mm/s)"));
|
||||
|
||||
int nedDownVel = myGPS.getNedDownVel();
|
||||
Serial.print(F(" VelD: "));
|
||||
Serial.print(nedDownVel);
|
||||
Serial.print(F(" (mm/s)"));
|
||||
|
||||
int verticalAccEst = myGPS.getVerticalAccEst();
|
||||
Serial.print(F(" VAccEst: "));
|
||||
Serial.print(verticalAccEst);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
int horizontalAccEst = myGPS.getHorizontalAccEst();
|
||||
Serial.print(F(" HAccEst: "));
|
||||
Serial.print(horizontalAccEst);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
int speedAccEst = myGPS.getSpeedAccEst();
|
||||
Serial.print(F(" SpeedAccEst: "));
|
||||
Serial.print(speedAccEst);
|
||||
Serial.print(F(" (mm/s)"));
|
||||
|
||||
int headAccEst = myGPS.getHeadingAccEst();
|
||||
Serial.print(F(" HeadAccEst: "));
|
||||
Serial.print(headAccEst);
|
||||
Serial.print(F(" (degrees * 10^-5)"));
|
||||
|
||||
if (myGPS.getHeadVehValid() == true) {
|
||||
int headVeh = myGPS.getHeadVeh();
|
||||
Serial.print(F(" HeadVeh: "));
|
||||
Serial.print(headVeh);
|
||||
Serial.print(F(" (degrees * 10^-5)"));
|
||||
|
||||
int magDec = myGPS.getMagDec();
|
||||
Serial.print(F(" MagDec: "));
|
||||
Serial.print(magDec);
|
||||
Serial.print(F(" (degrees * 10^-2)"));
|
||||
|
||||
int magAcc = myGPS.getMagAcc();
|
||||
Serial.print(F(" MagAcc: "));
|
||||
Serial.print(magAcc);
|
||||
Serial.print(F(" (degrees * 10^-2)"));
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
} else {
|
||||
Serial.print(".");
|
||||
delay(50);
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
Configuring the GPS to automatically send position reports over I2C, with explicit data parsing calls
|
||||
By: Nathan Seidle Thorsten von Eicken and Felix Jirka
|
||||
SparkFun Electronics
|
||||
Date: July 1st, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the U-Blox GPS the send navigation reports automatically
|
||||
and retrieving the latest one via checkUblox when available.
|
||||
This eliminates the implicit update in getPVT when accessing data fields twice.
|
||||
Also this reduces the memory overhead of a separate buffer while introducing a slight error by inconsistencies because of the unsynchronized updates (on a multi core system).
|
||||
|
||||
This can be used over serial or over I2C, this example shows the I2C use. With serial the GPS
|
||||
simply outputs the UBX_NAV_PVT packet. With I2C it queues it into its internal I2C buffer (4KB in
|
||||
size?) where it can be retrieved in the next I2C poll.
|
||||
|
||||
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 <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);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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.setNavigationFrequency(2); //Produce two solutions per second
|
||||
myGPS.setAutoPVT(true, false); //Tell the GPS to "send" each solution and the lib not to update stale data implicitly
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
/*
|
||||
Calling getPVT would return false now (compare to previous example where it would return true), so we just use the data provided
|
||||
If you are using a threaded OS eg. FreeRTOS on an ESP32, the explicit mode of autoPVT allows you to use the data provided on both cores and inside multiple threads
|
||||
The data update in background creates an inconsistent state, but that should not cause issues for most applications as they usually won't change the GPS location significantly within a 2Hz - 5Hz update rate.
|
||||
Also you could oversample (10Hz - 20Hz) the data to smooth out such issues...
|
||||
*/
|
||||
void loop()
|
||||
{
|
||||
static uint16_t counter = 0;
|
||||
|
||||
if (counter % 10 == 0)
|
||||
{
|
||||
// update your AHRS filter here for a ~100Hz update rate
|
||||
// GPS data will be quasi static but data from your IMU will be changing
|
||||
}
|
||||
// debug output each half second
|
||||
if (counter % 500 == 0)
|
||||
{
|
||||
Serial.println();
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
// call checkUblox all 50ms to capture the gps data
|
||||
if (counter % 50 == 0)
|
||||
{
|
||||
myGPS.checkUblox();
|
||||
}
|
||||
delay(1);
|
||||
counter++;
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Reading lat and long via UBX binary commands using an RX-only UART
|
||||
By: Nathan Seidle, Adapted from Example11 by Felix Jirka
|
||||
SparkFun Electronics
|
||||
Date: July 2nd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the library for serial port use with a single wire connection using the assumeAutoPVT method.
|
||||
Saving your pins for other stuff :-)
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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
|
||||
|
||||
Preconditions:
|
||||
U-Blox module is configured to send cyclical PVT message
|
||||
Hardware Connections:
|
||||
Connect the U-Blox serial TX pin to Rx of Serial2 (default: GPIO16) on your ESP32
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example 17");
|
||||
|
||||
//Use any Serial port with at least a Rx Pin connected or a receive only version of SoftwareSerial here
|
||||
//Assume that the U-Blox GPS is running at 9600 baud (the default)
|
||||
Serial2.begin(9600);
|
||||
// no need to check return value as internal call to isConnected() will not succeed
|
||||
myGPS.begin(Serial2);
|
||||
|
||||
// tell lib, we are expecting the module to send PVT messages by itself to our Rx pin
|
||||
// you can set second parameter to "false" if you want to control the parsing and eviction of the data (need to call checkUblox cyclically)
|
||||
myGPS.assumeAutoPVT(true, true);
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// if implicit updates are allowed, this will trigger parsing the incoming messages
|
||||
// and be true once a PVT message has been parsed
|
||||
// In case you want to use explicit updates, wrap this in a timer and call checkUblox as often as needed, not to overflow your UART buffers
|
||||
if (myGPS.getPVT())
|
||||
{
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
else {
|
||||
Serial.println(F("Wait for GPS data"));
|
||||
delay(500);
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Reading lat and long via UBX binary commands using UART @38400 baud - free from I2C
|
||||
By: Nathan Seidle, Adapted from Example3_GetPosition by Thorsten von Eicken
|
||||
SparkFun Electronics
|
||||
Date: January 28rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the debug output from the library.
|
||||
Debug shows various packet and status outputs. These prints can be directed
|
||||
towards Serial (as in Serial.print) or any other port (Serial1, SerialUSB, etc).
|
||||
|
||||
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:
|
||||
Connect the U-Blox serial TX pin to Uno pin 10
|
||||
Connect the U-Blox serial RX pin to Uno pin 11
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
|
||||
myGPS.enableDebugging(); //Enable debug messages over Serial (default)
|
||||
//myGPS.enableDebugging(SerialUSB); //Enable debug messages over Serial USB
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
Serial.print(myGPS.getYear());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getMonth());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getDay());
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getHour());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getMinute());
|
||||
Serial.print(":");
|
||||
Serial.println(myGPS.getSecond());
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
Getting time and date using Ublox commands
|
||||
By: davidallenmann
|
||||
SparkFun Electronics
|
||||
Date: April 16th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query a Ublox module for the current time and date. We also
|
||||
turn off the NMEA output on the I2C port. This decreases the amount of I2C traffic
|
||||
dramatically.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
Serial.print(myGPS.getYear());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getMonth());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getDay());
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getHour());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getMinute());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getSecond());
|
||||
|
||||
Serial.print(" Time is ");
|
||||
if (myGPS.getTimeValid() == false)
|
||||
{
|
||||
Serial.print("not ");
|
||||
}
|
||||
Serial.print("valid Date is ");
|
||||
if (myGPS.getDateValid() == false)
|
||||
{
|
||||
Serial.print("not ");
|
||||
}
|
||||
Serial.print("valid");
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
Getting time and date using Ublox commands
|
||||
By: davidallenmann
|
||||
SparkFun Electronics
|
||||
Date: April 16th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query a Ublox module for the current time and date. We also
|
||||
turn off the NMEA output on the I2C port. This decreases the amount of I2C traffic
|
||||
dramatically.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(500000); //Increase serial speed to maximize
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000);
|
||||
|
||||
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.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
|
||||
//myGPS.enableDebugging(); //Enable debug messages over Serial (default)
|
||||
|
||||
myGPS.setNavigationFrequency(10); //Set output to 10 times a second
|
||||
byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
|
||||
Serial.print("Current update rate:");
|
||||
Serial.println(rate);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Calling getPVT returns true if there actually is a fresh navigation solution available.
|
||||
if (myGPS.getPVT())
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getYear());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getMonth());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getDay());
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getHour());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getMinute());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getSecond());
|
||||
Serial.print(".");
|
||||
Serial.print(myGPS.getNanosecond());
|
||||
|
||||
myGPS.flushPVT();
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
Getting time and date using Ublox commands
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: April 16th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to use the Millisecond and Nanosecond output as well as increase the
|
||||
I2C speed (100 to 400kHz), and serial output (115200 to 500kbps).
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(500000); //Increase serial speed to maximize
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000);
|
||||
|
||||
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.enableDebugging(); //Enable debug messages over Serial (default)
|
||||
|
||||
myGPS.setNavigationFrequency(10); //Set output to 10 times a second
|
||||
byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
|
||||
Serial.print("Current update rate:");
|
||||
Serial.println(rate);
|
||||
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
|
||||
pinMode(2, OUTPUT); //For debug capture
|
||||
digitalWrite(2, HIGH);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Calling getPVT returns true if there actually is a fresh navigation solution available.
|
||||
if (myGPS.getPVT())
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getYear());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getMonth());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getDay());
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getHour());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getMinute());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getSecond());
|
||||
Serial.print(".");
|
||||
//Pretty print leading zeros
|
||||
int mseconds = myGPS.getMillisecond();
|
||||
if (mseconds < 100)
|
||||
Serial.print("0");
|
||||
if (mseconds < 10)
|
||||
Serial.print("0");
|
||||
Serial.print(mseconds);
|
||||
|
||||
Serial.print(" nanoSeconds: ");
|
||||
Serial.print(myGPS.getNanosecond());
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
/*
|
||||
u-blox M8 geofence example
|
||||
|
||||
Written by Paul Clark (PaulZC)
|
||||
10th December 2019
|
||||
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example demonstrates how to use the addGeofence and getGeofenceState functions
|
||||
|
||||
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/15210
|
||||
ZOE-M8Q: https://www.sparkfun.com/products/15193
|
||||
|
||||
This example powers up the GPS and reads the fix.
|
||||
Once a valid 3D fix has been found, the code reads the latitude and longitude.
|
||||
The code then sets four geofences around that position with a radii of 5m, 10m, 15m and 20m with 95% confidence.
|
||||
The code then monitors the geofence status.
|
||||
The LED will be illuminated if you are inside the _combined_ geofence (i.e. within the 20m radius).
|
||||
|
||||
This code has been tested on the ZOE-M8Q.
|
||||
*/
|
||||
|
||||
#define LED LED_BUILTIN // Change this if your LED is on a different pin
|
||||
|
||||
#include <Wire.h> // Needed for I2C
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED, OUTPUT);
|
||||
|
||||
// Set up the I2C pins
|
||||
Wire.begin();
|
||||
|
||||
// Start the console serial port
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // Wait for the user to open the serial monitor
|
||||
delay(100);
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println(F("u-blox M8 geofence example"));
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
delay(1000); // Let the GPS power up
|
||||
|
||||
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.enableDebugging(); // Enable debug messages
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); // Limit I2C output to UBX (disable the NMEA noise)
|
||||
|
||||
Serial.println(F("Waiting for a 3D fix..."));
|
||||
|
||||
byte fixType = 0;
|
||||
|
||||
while (fixType < 3)
|
||||
{
|
||||
fixType = myGPS.getFixType(); // Get the fix type
|
||||
Serial.print(F("Fix: ")); // Print it
|
||||
Serial.print(fixType);
|
||||
if(fixType == 0) Serial.print(F(" = No fix"));
|
||||
else if(fixType == 1) Serial.print(F(" = Dead reckoning"));
|
||||
else if(fixType == 2) Serial.print(F(" = 2D"));
|
||||
else if(fixType == 3) Serial.print(F(" = 3D"));
|
||||
else if(fixType == 4) Serial.print(F(" = GNSS + Dead reckoning"));
|
||||
else if(fixType == 5) Serial.print(F(" = Time only"));
|
||||
Serial.println();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println(F("3D fix found!"));
|
||||
|
||||
long latitude = myGPS.getLatitude(); // Get the latitude in degrees * 10^-7
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude(); // Get the longitude in degrees * 10^-7
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.println(longitude);
|
||||
|
||||
uint32_t radius = 500; // Set the radius to 5m (radius is in m * 10^-2 i.e. cm)
|
||||
|
||||
byte confidence = 2; // Set the confidence level: 0=none, 1=68%, 2=95%, 3=99.7%, 4=99.99%
|
||||
|
||||
// Call clearGeofences() to clear all existing geofences.
|
||||
Serial.print(F("Clearing any existing geofences. clearGeofences returned: "));
|
||||
Serial.println(myGPS.clearGeofences());
|
||||
|
||||
// It is possible to define up to four geofences.
|
||||
// Call addGeofence up to four times to define them.
|
||||
Serial.println(F("Setting the geofences:"));
|
||||
|
||||
Serial.print(F("addGeofence for geofence 1 returned: "));
|
||||
Serial.println(myGPS.addGeofence(latitude, longitude, radius, confidence));
|
||||
|
||||
radius = 1000; // 10m
|
||||
Serial.print(F("addGeofence for geofence 2 returned: "));
|
||||
Serial.println(myGPS.addGeofence(latitude, longitude, radius, confidence));
|
||||
|
||||
radius = 1500; // 15m
|
||||
Serial.print(F("addGeofence for geofence 3 returned: "));
|
||||
Serial.println(myGPS.addGeofence(latitude, longitude, radius, confidence));
|
||||
|
||||
radius = 2000; // 20m
|
||||
Serial.print(F("addGeofence for geofence 4 returned: "));
|
||||
Serial.println(myGPS.addGeofence(latitude, longitude, radius, confidence));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
geofenceState currentGeofenceState; // Create storage for the geofence state
|
||||
|
||||
boolean result = myGPS.getGeofenceState(currentGeofenceState);
|
||||
|
||||
Serial.print(F("getGeofenceState returned: ")); // Print the combined state
|
||||
Serial.print(result); // Get the geofence state
|
||||
|
||||
if (!result) // If getGeofenceState did not return true
|
||||
{
|
||||
Serial.println(F(".")); // Tidy up
|
||||
return; // and go round the loop again
|
||||
}
|
||||
|
||||
Serial.print(F(". status is: ")); // Print the status
|
||||
Serial.print(currentGeofenceState.status);
|
||||
|
||||
Serial.print(F(". numFences is: ")); // Print the numFences
|
||||
Serial.print(currentGeofenceState.numFences);
|
||||
|
||||
Serial.print(F(". combState is: ")); // Print the combined state
|
||||
Serial.print(currentGeofenceState.combState);
|
||||
|
||||
if (currentGeofenceState.combState == 0)
|
||||
{
|
||||
Serial.print(F(" = Unknown"));
|
||||
digitalWrite(LED, LOW);
|
||||
}
|
||||
if (currentGeofenceState.combState == 1)
|
||||
{
|
||||
Serial.print(F(" = Inside"));
|
||||
digitalWrite(LED, HIGH);
|
||||
}
|
||||
else if (currentGeofenceState.combState == 2)
|
||||
{
|
||||
Serial.print(F(" = Outside"));
|
||||
digitalWrite(LED, LOW);
|
||||
}
|
||||
|
||||
Serial.print(F(". The individual states are: ")); // Print the state of each geofence
|
||||
for(int i = 0; i < currentGeofenceState.numFences; i++)
|
||||
{
|
||||
if (i > 0) Serial.print(F(","));
|
||||
Serial.print(currentGeofenceState.states[i]);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
/*
|
||||
Power Save Mode
|
||||
By: Paul Clark (PaulZC)
|
||||
Date: April 22nd, 2020
|
||||
|
||||
Based extensively on Example3_GetPosition
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to put the Ublox module into power save mode and then
|
||||
query its lat/long/altitude. We also turn off the NMEA output on the I2C port.
|
||||
This decreases the amount of I2C traffic dramatically.
|
||||
|
||||
** When it is able to ** the module will reduce its current draw.
|
||||
For the ZOE-M8Q with a passive antenna, you should see the current drop
|
||||
from (approx.) 25-28mA to (approx.) 9mA when power save mode kicks in.
|
||||
|
||||
Note: this will fail on the ZED (protocol version >= 27) as UBX-CFG-RXM is not supported
|
||||
|
||||
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
|
||||
to something google maps understands simply divide the numbers by 10,000,000. We
|
||||
do this so that we don't have to use floating point numbers.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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.enableDebugging(); // Uncomment this line to enable debug messages
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
//myGPS.saveConfiguration(); //Uncomment this line to save the current settings to flash and BBR
|
||||
|
||||
Serial.println("Power save example.");
|
||||
Serial.println("1) Enable power saving");
|
||||
Serial.println("2) Disable power saving");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (Serial.available())
|
||||
{
|
||||
byte incoming = Serial.read();
|
||||
|
||||
if (incoming == '1')
|
||||
{
|
||||
// Put the GNSS into power save mode
|
||||
// (If you want to disable power save mode, call myGPS.powerSaveMode(false) instead)
|
||||
// This will fail on the ZED (protocol version >= 27) as UBX-CFG-RXM is not supported
|
||||
if (myGPS.powerSaveMode()) // Defaults to true
|
||||
Serial.println(F("Power Save Mode enabled."));
|
||||
else
|
||||
Serial.println(F("***!!! Power Save Mode FAILED !!!***"));
|
||||
}
|
||||
else if (incoming == '2')
|
||||
{
|
||||
//Go to normal power mode (not power saving mode)
|
||||
if (myGPS.powerSaveMode(false))
|
||||
Serial.println(F("Power Save Mode disabled."));
|
||||
else
|
||||
Serial.println(F("***!!! Power Save Disable FAILED !!!***"));
|
||||
}
|
||||
|
||||
// Read and print the new low power mode
|
||||
uint8_t lowPowerMode = myGPS.getPowerSaveMode();
|
||||
if (lowPowerMode == 255)
|
||||
{
|
||||
Serial.println(F("***!!! getPowerSaveMode FAILED !!!***"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("The low power mode is: "));
|
||||
Serial.print(lowPowerMode);
|
||||
if (lowPowerMode == 0)
|
||||
{
|
||||
Serial.println(F(" (Continuous)"));
|
||||
}
|
||||
else if (lowPowerMode == 1)
|
||||
{
|
||||
Serial.println(F(" (Power Save)"));
|
||||
}
|
||||
else if (lowPowerMode == 4)
|
||||
{
|
||||
Serial.println(F(" (Continuous)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F(" (Unknown!)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Query module every 10 seconds so it is easier to monitor the current draw
|
||||
if (millis() - lastTime > 10000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
byte fixType = myGPS.getFixType(); // Get the fix type
|
||||
Serial.print(F("Fix: "));
|
||||
Serial.print(fixType);
|
||||
if (fixType == 0)
|
||||
Serial.print(F("(No fix)"));
|
||||
else if (fixType == 1)
|
||||
Serial.print(F("(Dead reckoning)"));
|
||||
else if (fixType == 2)
|
||||
Serial.print(F("(2D)"));
|
||||
else if (fixType == 3)
|
||||
Serial.print(F("(3D)"));
|
||||
else if (fixType == 4)
|
||||
Serial.print(F("(GNSS + Dead reckoning)"));
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F(" Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
Set Dynamic Model
|
||||
By: Paul Clark (PaulZC)
|
||||
Date: April 22nd, 2020
|
||||
|
||||
Based extensively on Example3_GetPosition
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to change the Ublox module's dynamic platform model and then
|
||||
query its lat/long/altitude. We also turn off the NMEA output on the I2C port.
|
||||
This decreases the amount of I2C traffic dramatically.
|
||||
|
||||
Possible values for the dynamic model are: PORTABLE, STATIONARY, PEDESTRIAN, AUTOMOTIVE,
|
||||
SEA, AIRBORNE1g, AIRBORNE2g, AIRBORNE4g, WRIST, BIKE
|
||||
|
||||
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
|
||||
to something google maps understands simply divide the numbers by 10,000,000. We
|
||||
do this so that we don't have to use floating point numbers.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println(F("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)
|
||||
|
||||
// If we are going to change the dynamic platform model, let's do it here.
|
||||
// Possible values are:
|
||||
// PORTABLE, STATIONARY, PEDESTRIAN, AUTOMOTIVE, SEA, AIRBORNE1g, AIRBORNE2g, AIRBORNE4g, WRIST, BIKE
|
||||
|
||||
if (myGPS.setDynamicModel(DYN_MODEL_PORTABLE) == false) // Set the dynamic model to PORTABLE
|
||||
{
|
||||
Serial.println(F("***!!! Warning: setDynamicModel failed !!!***"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("Dynamic platform model changed successfully!"));
|
||||
}
|
||||
|
||||
// Let's read the new dynamic model to see if it worked
|
||||
uint8_t newDynamicModel = myGPS.getDynamicModel();
|
||||
if (newDynamicModel == 255)
|
||||
{
|
||||
Serial.println(F("***!!! Warning: getDynamicModel failed !!!***"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("The new dynamic model is: "));
|
||||
Serial.println(newDynamicModel);
|
||||
}
|
||||
|
||||
//myGPS.saveConfigSelective(VAL_CFG_SUBSEC_NAVCONF); //Uncomment this line to save only the NAV settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
Read NMEA sentences over I2C using Ublox module SAM-M8Q, NEO-M8P, ZED-F9P, etc
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: August 22nd, 2018
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example reads the NMEA setences from the Ublox module over I2c and outputs
|
||||
them to the serial port
|
||||
|
||||
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 <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);
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false)
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
//This will pipe all NMEA sentences to the serial port so we can see them
|
||||
myGPS.setNMEAOutputPort(Serial);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
|
||||
|
||||
delay(250); //Don't pound too hard on the I2C bus
|
||||
}
|
@ -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)"));
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
/*
|
||||
Module Info - extracts and prints the full module information from UBX_MON_VER
|
||||
using a custom command.
|
||||
By: @mayopan
|
||||
Date: May 9th, 2020
|
||||
|
||||
Based on:
|
||||
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.
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#define MAX_PAYLOAD_SIZE 384 // Override MAX_PAYLOAD_SIZE for getModuleInfo which can return up to 348 bytes
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
|
||||
// Extend the class for getModuleInfo
|
||||
class SFE_UBLOX_GPS_ADD : public SFE_UBLOX_GPS
|
||||
{
|
||||
public:
|
||||
boolean getModuleInfo(uint16_t maxWait = 1100); //Queries module, texts
|
||||
|
||||
struct minfoStructure // Structure to hold the module info (uses 341 bytes of RAM)
|
||||
{
|
||||
char swVersion[30];
|
||||
char hwVersion[10];
|
||||
uint8_t extensionNo = 0;
|
||||
char extension[10][30];
|
||||
} minfo;
|
||||
};
|
||||
|
||||
SFE_UBLOX_GPS_ADD 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(F("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)
|
||||
|
||||
Serial.print(F("Polling module info"));
|
||||
if (myGPS.getModuleInfo(1100) == false) // Try to get the module info
|
||||
{
|
||||
Serial.print(F("getModuleInfo failed! Freezing..."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println(F("Module Info : "));
|
||||
Serial.print(F("Soft version: "));
|
||||
Serial.println(myGPS.minfo.swVersion);
|
||||
Serial.print(F("Hard version: "));
|
||||
Serial.println(myGPS.minfo.hwVersion);
|
||||
Serial.print(F("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(F("Done!"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
boolean SFE_UBLOX_GPS_ADD::getModuleInfo(uint16_t maxWait)
|
||||
{
|
||||
myGPS.minfo.hwVersion[0] = 0;
|
||||
myGPS.minfo.swVersion[0] = 0;
|
||||
for (int i = 0; i < 10; i++)
|
||||
myGPS.minfo.extension[i][0] = 0;
|
||||
myGPS.minfo.extensionNo = 0;
|
||||
|
||||
// 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 module information can be read using the UBX-MON-VER message. So let's load our
|
||||
// custom packet with the correct information so we can read (poll / get) the module information.
|
||||
|
||||
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)
|
||||
|
||||
// Now let's send the command. The module info is returned in customPayload
|
||||
|
||||
if (sendCommand(&customCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED)
|
||||
return (false); //If command send fails then bail
|
||||
|
||||
// Now let's extract the module info from customPayload
|
||||
|
||||
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); //Success!
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Powering off a ublox GPS module
|
||||
By: bjorn
|
||||
unsurv.org
|
||||
Date: July 20th, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows you how to turn off the ublox module to lower the power consumption.
|
||||
There are two functions: one just specifies a duration in milliseconds the other also specifies a pin on the GPS device to wake it up with.
|
||||
By driving a voltage from LOW to HIGH or HIGH to LOW on the chosen module pin you wake the device back up.
|
||||
Note: Doing so on the INT0 pin when using the regular powerOff(durationInMs) function will wake the device anyway. (tested on SAM-M8Q)
|
||||
Note: While powered off, you should not query the device for data or it might wake up. This can be used to wake the device but is not recommended.
|
||||
Works best when also putting your microcontroller to sleep.
|
||||
|
||||
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.
|
||||
To force the device to wake up you need to connect to a pin (for example INT0) seperately on the module.
|
||||
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 "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
|
||||
// define a digital pin capable of driving HIGH and LOW
|
||||
#define WAKEUP_PIN 5
|
||||
|
||||
// Possible GNSS interrupt pins for powerOffWithInterrupt are:
|
||||
// VAL_RXM_PMREQ_WAKEUPSOURCE_UARTRX = uartrx
|
||||
// VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0 = extint0 (default)
|
||||
// VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT1 = extint1
|
||||
// VAL_RXM_PMREQ_WAKEUPSOURCE_SPICS = spics
|
||||
// These values can be or'd (|) together to enable interrupts on multiple pins
|
||||
|
||||
void wakeUp() {
|
||||
|
||||
Serial.print("-- waking up module via pin " + String(WAKEUP_PIN));
|
||||
Serial.println(" on your microcontroller --");
|
||||
|
||||
digitalWrite(WAKEUP_PIN, LOW);
|
||||
delay(1000);
|
||||
digitalWrite(WAKEUP_PIN, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(WAKEUP_PIN, LOW);
|
||||
}
|
||||
|
||||
|
||||
void setup() {
|
||||
|
||||
pinMode(WAKEUP_PIN, OUTPUT);
|
||||
digitalWrite(WAKEUP_PIN, LOW);
|
||||
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // 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);
|
||||
}
|
||||
|
||||
// Powering off for 20s, you should see the power consumption drop.
|
||||
Serial.println("-- Powering off module for 20s --");
|
||||
|
||||
myGPS.powerOff(20000);
|
||||
//myGPS.powerOffWithInterrupt(20000, VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0);
|
||||
|
||||
delay(10000);
|
||||
|
||||
// After 10 seconds wake the device via the specified pin on your microcontroller and module.
|
||||
wakeUp();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//Do nothing
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
Read NMEA sentences over I2C using Ublox module SAM-M8Q, NEO-M8P, etc
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: August 22nd, 2018
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example reads the NMEA characters over I2C and pipes them to MicroNMEA
|
||||
This example will output your current long/lat and satellites in view
|
||||
|
||||
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
|
||||
|
||||
For more MicroNMEA info see https://github.com/stevemarple/MicroNMEA
|
||||
|
||||
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
|
||||
Go outside! Wait ~25 seconds and you should see your lat/long
|
||||
*/
|
||||
|
||||
#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;
|
||||
|
||||
#include <MicroNMEA.h> //http://librarymanager/All#MicroNMEA
|
||||
char nmeaBuffer[100];
|
||||
MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer));
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false)
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
|
||||
|
||||
if(nmea.isValid() == true)
|
||||
{
|
||||
long latitude_mdeg = nmea.getLatitude();
|
||||
long longitude_mdeg = nmea.getLongitude();
|
||||
|
||||
Serial.print("Latitude (deg): ");
|
||||
Serial.println(latitude_mdeg / 1000000., 6);
|
||||
Serial.print("Longitude (deg): ");
|
||||
Serial.println(longitude_mdeg / 1000000., 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("No Fix - ");
|
||||
Serial.print("Num. satellites: ");
|
||||
Serial.println(nmea.getNumSatellites());
|
||||
}
|
||||
|
||||
delay(250); //Don't pound too hard on the I2C bus
|
||||
}
|
||||
|
||||
//This function gets called from the SparkFun Ublox Arduino Library
|
||||
//As each NMEA character comes in you can specify what to do with it
|
||||
//Useful for passing to other libraries like tinyGPS, MicroNMEA, or even
|
||||
//a buffer, radio, etc.
|
||||
void SFE_UBLOX_GPS::processNMEA(char incoming)
|
||||
{
|
||||
//Take the incoming char from the Ublox I2C port and pass it on to the MicroNMEA lib
|
||||
//for sentence cracking
|
||||
nmea.process(incoming);
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
Reading lat and long via UBX binary commands - no more NMEA parsing!
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query a Ublox module for its lat/long/altitude. We also
|
||||
turn off the NMEA output on the I2C port. This decreases the amount of I2C traffic
|
||||
dramatically.
|
||||
|
||||
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
|
||||
to something google maps understands simply divide the numbers by 10,000,000. We
|
||||
do this so that we don't have to use floating point numbers.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
Get fix type and RTK fix type if available
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query a Ublox module for fix type and RTK fix type.
|
||||
The fix type is as follows:
|
||||
0 = no fix
|
||||
1 = dead reckoning (requires external sensors)
|
||||
2 = 2D (not quite enough satellites in view)
|
||||
3 = 3D (the standard fix)
|
||||
4 = GNSS + dead reckoning (requires external sensors)
|
||||
5 = Time fix only
|
||||
|
||||
Additionally, if we are doing RTK, we can figure out if we have a floating
|
||||
RTK solution or if we have been able to resolve a fixec solution (better precision).
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000); //Optional. Increase I2C clock speed to 400kHz.
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
|
||||
byte fixType = myGPS.getFixType();
|
||||
Serial.print(F(" Fix: "));
|
||||
if(fixType == 0) Serial.print(F("No fix"));
|
||||
else if(fixType == 1) Serial.print(F("Dead reckoning"));
|
||||
else if(fixType == 2) Serial.print(F("2D"));
|
||||
else if(fixType == 3) Serial.print(F("3D"));
|
||||
else if(fixType == 4) Serial.print(F("GNSS+Dead reckoning"));
|
||||
|
||||
byte RTK = myGPS.getCarrierSolutionType();
|
||||
Serial.print(" RTK: ");
|
||||
Serial.print(RTK);
|
||||
if (RTK == 1) Serial.print(F("High precision float fix!"));
|
||||
if (RTK == 2) Serial.print(F("High precision fix!"));
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
Get Speed/Heading and dilution of precision via UBX binary commands - no more NMEA parsing!
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query a Ublox module for its lat/long/altitude.
|
||||
|
||||
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
|
||||
to something google maps understands simply divide the numbers by 1,000,000. We
|
||||
do this so that we don't have to use floating point numbers.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
|
||||
long speed = myGPS.getGroundSpeed();
|
||||
Serial.print(F(" Speed: "));
|
||||
Serial.print(speed);
|
||||
Serial.print(F(" (mm/s)"));
|
||||
|
||||
long heading = myGPS.getHeading();
|
||||
Serial.print(F(" Heading: "));
|
||||
Serial.print(heading);
|
||||
Serial.print(F(" (degrees * 10^-5)"));
|
||||
|
||||
int pDOP = myGPS.getPDOP();
|
||||
Serial.print(F(" pDOP: "));
|
||||
Serial.print(pDOP / 100.0, 2);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Turn on/off various NMEA sentences.
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
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 UART1. We use the I2C interface on the Ublox module for configuration
|
||||
but you won't see any output from this sketch. You'll need to hook up
|
||||
a Serial Basic or other USB to Serial device to UART1 on your Ublox module
|
||||
to see the output.
|
||||
|
||||
This example turns off all sentences except for the GPGGA and GPVTG sentences.
|
||||
|
||||
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 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
|
||||
Hookup a Serial Basic (https://www.sparkfun.com/products/15096) to UART1 on the Ublox module. Open a terminal at 57600bps
|
||||
and see GPGGA and GPVTG sentences.
|
||||
*/
|
||||
#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;
|
||||
|
||||
unsigned long lastGPSSend = 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200); // Serial debug output over USB visible from Arduino IDE
|
||||
Serial.println("Example showing how to enable/disable certain NMEA sentences");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false)
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
//Disable or enable various NMEA sentences over the UART1 interface
|
||||
myGPS.disableNMEAMessage(UBX_NMEA_GLL, COM_PORT_UART1); //Several of these are on by default on virgin ublox board so let's disable them
|
||||
myGPS.disableNMEAMessage(UBX_NMEA_GSA, COM_PORT_UART1);
|
||||
myGPS.disableNMEAMessage(UBX_NMEA_GSV, COM_PORT_UART1);
|
||||
myGPS.disableNMEAMessage(UBX_NMEA_RMC, COM_PORT_UART1);
|
||||
myGPS.enableNMEAMessage(UBX_NMEA_GGA, COM_PORT_UART1); //Only leaving GGA/VTG enabled at current navigation rate
|
||||
myGPS.enableNMEAMessage(UBX_NMEA_VTG, COM_PORT_UART1);
|
||||
|
||||
//Here's the advanced configure method
|
||||
//Some of the other examples in this library enable the PVT message so let's disable it
|
||||
myGPS.configureMessage(UBX_CLASS_NAV, UBX_NAV_PVT, COM_PORT_UART1, 0); //Message Class, ID, and port we want to configure, sendRate of 0 (disable).
|
||||
|
||||
myGPS.setUART1Output(COM_TYPE_NMEA); //Turn off UBX and RTCM sentences on the UART1 interface
|
||||
|
||||
myGPS.setSerialRate(57600); //Set UART1 to 57600bps.
|
||||
|
||||
myGPS.saveConfiguration(); //Save these settings to NVM
|
||||
|
||||
Serial.println(F("Messages configured. NMEA now being output over the UART1 port on the Ublox module at 57600bps."));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (millis() - lastGPSSend > 200)
|
||||
{
|
||||
myGPS.checkUblox(); //See if new data is available, but we don't want to get NMEA here. Go check UART1.
|
||||
lastGPSSend = millis();
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
Set update rate to 10Hz
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to increase the output of the module from 1Hz to 4Hz.
|
||||
The max output rate various from model to model. RTFM! But you cannot do harm
|
||||
to the module.
|
||||
|
||||
We also disable NMEA output on the I2C bus and use only UBX. This dramatically
|
||||
decreases the amount of data that needs to be transmitted.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
long startTime = 0; //Used to calc the actual update rate.
|
||||
long updateCount = 0; //Used to calc the actual update rate.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000);
|
||||
|
||||
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.setNavigationFrequency(10); //Set output to 10 times a second
|
||||
|
||||
byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
|
||||
Serial.print("Current update rate:");
|
||||
Serial.println(rate);
|
||||
|
||||
startTime = millis();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available. This is defined
|
||||
//by the update freq.
|
||||
if (millis() - lastTime > 25)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
|
||||
updateCount++;
|
||||
|
||||
//Calculate the actual update rate based on the sketch start time and the
|
||||
//number of updates we've received.
|
||||
Serial.print(F(" Rate: "));
|
||||
Serial.print( updateCount / ((millis() - startTime) / 1000.0), 2);
|
||||
Serial.print(F("Hz"));
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Reading the protocol version of a Ublox module
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query a Ublox module for its protocol version.
|
||||
|
||||
Various modules have various protocol version. We've seen v18 up to v27. Depending
|
||||
on the protocol version there are different commands available. This is a handy
|
||||
way to predict which commands will or won't work.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Serial.print(F("Version: "));
|
||||
byte versionHigh = myGPS.getProtocolVersionHigh();
|
||||
Serial.print(versionHigh);
|
||||
Serial.print(".");
|
||||
byte versionLow = myGPS.getProtocolVersionLow();
|
||||
Serial.print(versionLow);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Do nothing
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
Change the I2C address of a Ublox module using I2C
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to change the I2C address of a Ublox module
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Tracks the passing of 2000ms (2 seconds)
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
byte oldAddress = 0x42; //The default address for Ublox modules is 0x42
|
||||
byte newAddress = 0x3F; //Address you want to change to. Valid is 0x08 to 0x77.
|
||||
|
||||
while (Serial.available()) Serial.read(); //Trash any incoming chars
|
||||
Serial.print("Press a key to change address to 0x");
|
||||
Serial.println(newAddress, HEX);
|
||||
while (Serial.available() == false) ; //Wait for user to send character
|
||||
|
||||
if (myGPS.begin(Wire, oldAddress) == true) //Connect to the Ublox module using Wire port and the old address
|
||||
{
|
||||
Serial.print("GPS found at address 0x");
|
||||
Serial.println(oldAddress, HEX);
|
||||
|
||||
myGPS.setI2CAddress(newAddress); //Change I2C address of this device
|
||||
//Device's I2C address is stored to memory and loaded on each power-on
|
||||
|
||||
if (myGPS.begin(Wire, newAddress) == true)
|
||||
{
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
|
||||
Serial.print("Address successfully changed to 0x");
|
||||
Serial.println(newAddress, HEX);
|
||||
Serial.print("Now load another example sketch using .begin(Wire, 0x");
|
||||
Serial.print(newAddress, HEX);
|
||||
Serial.println(") to use this GPS module");
|
||||
Serial.println("Freezing...");
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
//Something went wrong, begin looking for the I2C device
|
||||
Serial.println("Address change failed. Beginning an I2C scan.");
|
||||
|
||||
Wire.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
byte address;
|
||||
int nDevices;
|
||||
|
||||
Serial.println("Scanning...");
|
||||
|
||||
nDevices = 0;
|
||||
for (address = 1; address < 127; address++ )
|
||||
{
|
||||
Wire.beginTransmission(address);
|
||||
byte error = Wire.endTransmission();
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
Serial.print("I2C device found at address 0x");
|
||||
if (address < 16)
|
||||
Serial.print("0");
|
||||
Serial.print(address, HEX);
|
||||
Serial.println(" !");
|
||||
|
||||
nDevices++;
|
||||
}
|
||||
else if (error == 4)
|
||||
{
|
||||
Serial.print("Unknown error at address 0x");
|
||||
if (address < 16)
|
||||
Serial.print("0");
|
||||
Serial.println(address, HEX);
|
||||
}
|
||||
}
|
||||
|
||||
if (nDevices == 0)
|
||||
Serial.println("No I2C devices found\n");
|
||||
else
|
||||
Serial.println("done\n");
|
||||
|
||||
delay(5000); // wait 5 seconds for next scan
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
Send UBX binary commands to enable RTCM sentences on Ublox NEO-M8P module
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: September 7th, 2018
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example sends the command to enable the four RTCM messages needed for RTK. This
|
||||
is the first part of a larger tutorial and example to setup an RTK base station.
|
||||
These commands are only accepted by the NEO-M8P module.
|
||||
|
||||
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 <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);
|
||||
while(!Serial); //Wait for user to open terminal
|
||||
Serial.println("Ublox RTCM Enable Example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
while(Serial.available()) Serial.read(); //Clear any latent chars in serial buffer
|
||||
Serial.println("Press any key to send commands to enable RTCM 3.x");
|
||||
while(Serial.available() == 0) ; //Wait for user to press a key
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
|
||||
boolean response = true;
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_I2C, 1); //Enable message 1005 to output through I2C port, message every second
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1077, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1087, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_I2C, 10); //Enable message every 10 seconds
|
||||
|
||||
if (response == true)
|
||||
{
|
||||
Serial.println("RTCM messages enabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("RTCM failed to enable. Are you sure you have an NEO-M8P?");
|
||||
while(1); //Freeze
|
||||
}
|
||||
|
||||
//RTCM is now enabled but we haven't done a 'survey-in'
|
||||
//See example 4 for the full Base RTK setup
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
|
||||
|
||||
delay(250); //Don't pound too hard on the I2C bus
|
||||
}
|
@ -0,0 +1,153 @@
|
||||
/*
|
||||
Send UBX binary commands to enable RTCM sentences on Ublox NEO-M8P-2 module
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: September 7th, 2018
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example does all steps to configure and enable a NEO-M8P-2 as a base station:
|
||||
Begin Survey-In
|
||||
Once we've achieved 2m accuracy and 300s have passed, survey is complete
|
||||
Enable four RTCM messages
|
||||
Begin outputting RTCM bytes
|
||||
|
||||
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 <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);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("Ublox NEO-M8P-2 base station example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
|
||||
|
||||
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.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
|
||||
while (Serial.available()) Serial.read(); //Clear any latent chars in serial buffer
|
||||
Serial.println("Press any key to send commands to begin Survey-In");
|
||||
while (Serial.available() == 0) ; //Wait for user to press a key
|
||||
|
||||
boolean response;
|
||||
|
||||
//Check if Survey is in Progress before initiating one
|
||||
response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (request can take a long time)
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println("Failed to get Survey In status");
|
||||
while (1); //Freeze
|
||||
}
|
||||
|
||||
if (myGPS.svin.active == true)
|
||||
{
|
||||
Serial.print("Survey already in progress.");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Start survey
|
||||
response = myGPS.enableSurveyMode(300, 2.000); //Enable Survey in, 300 seconds, 2.0m
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println("Survey start failed");
|
||||
while (1);
|
||||
}
|
||||
Serial.println("Survey started. This will run until 300s has passed and less than 2m accuracy is achieved.");
|
||||
}
|
||||
|
||||
while(Serial.available()) Serial.read(); //Clear buffer
|
||||
|
||||
//Begin waiting for survey to complete
|
||||
while (myGPS.svin.valid == false)
|
||||
{
|
||||
if(Serial.available())
|
||||
{
|
||||
byte incoming = Serial.read();
|
||||
if(incoming == 'x')
|
||||
{
|
||||
//Stop survey mode
|
||||
response = myGPS.disableSurveyMode(); //Disable survey
|
||||
Serial.println("Survey stopped");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (req can take a long time)
|
||||
if (response == true)
|
||||
{
|
||||
Serial.print("Press x to end survey - ");
|
||||
Serial.print("Time elapsed: ");
|
||||
Serial.print((String)myGPS.svin.observationTime);
|
||||
|
||||
Serial.print(" Accuracy: ");
|
||||
Serial.print((String)myGPS.svin.meanAccuracy);
|
||||
Serial.println();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("SVIN request failed");
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
Serial.println("Survey valid!");
|
||||
|
||||
response = true;
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_I2C, 1); //Enable message 1005 to output through I2C port, message every second
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1077, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1087, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_I2C, 10); //Enable message every 10 seconds
|
||||
|
||||
if (response == true)
|
||||
{
|
||||
Serial.println("RTCM messages enabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("RTCM failed to enable. Are you sure you have an NEO-M8P?");
|
||||
while (1); //Freeze
|
||||
}
|
||||
|
||||
Serial.println("Base survey complete! RTCM now broadcasting.");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
|
||||
|
||||
delay(250); //Don't pound too hard on the I2C bus
|
||||
}
|
||||
|
||||
//This function gets called from the SparkFun Ublox Arduino Library.
|
||||
//As each RTCM byte comes in you can specify what to do with it
|
||||
//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
|
||||
void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
|
||||
{
|
||||
//Let's just pretty-print the HEX values for now
|
||||
if (myGPS.rtcmFrameCounter % 16 == 0) Serial.println();
|
||||
Serial.print(" ");
|
||||
if (incoming < 0x10) Serial.print("0");
|
||||
Serial.print(incoming, HEX);
|
||||
}
|
@ -0,0 +1,185 @@
|
||||
/*
|
||||
Send UBX binary commands to enable RTCM sentences on Ublox NEO-M8P-2 module
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: September 7th, 2018
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example does all steps to configure and enable a NEO-M8P-2 as a base station:
|
||||
Begin Survey-In
|
||||
Once we've achieved 2m accuracy and 300s have passed, survey is complete
|
||||
Enable four RTCM messages
|
||||
Begin outputting RTCM bytes
|
||||
|
||||
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
|
||||
Plug a SerLCD onto the Qwiic bus
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Watch the output on the LCD or open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#define STAT_LED 13
|
||||
|
||||
#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;
|
||||
|
||||
#include <SerLCD.h> //Click here to get the library: http://librarymanager/All#SparkFun_SerLCD
|
||||
SerLCD lcd; // Initialize the library with default I2C address 0x72
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("Ublox GPS I2C Test");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
pinMode(STAT_LED, OUTPUT);
|
||||
digitalWrite(STAT_LED, LOW);
|
||||
|
||||
lcd.begin(Wire); //Set up the LCD for Serial communication at 9600bps
|
||||
lcd.setBacklight(0x4B0082); //indigo, a kind of dark purplish blue
|
||||
lcd.clear();
|
||||
lcd.print(F("LCD Ready"));
|
||||
|
||||
myGPS.begin(Wire);
|
||||
if (myGPS.isConnected() == false)
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("No GPS detected"));
|
||||
while (1);
|
||||
}
|
||||
|
||||
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
|
||||
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("GPS Detected");
|
||||
|
||||
//Check if Survey is in Progress before initiating one
|
||||
boolean response;
|
||||
response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (request can take a long time)
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println(F("Failed to get Survey In status"));
|
||||
while (1); //Freeze
|
||||
}
|
||||
|
||||
if (myGPS.svin.active == true)
|
||||
{
|
||||
Serial.print(F("Survey already in progress."));
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("Survey already going"));
|
||||
}
|
||||
else
|
||||
{
|
||||
//Start survey
|
||||
response = myGPS.enableSurveyMode(300, 2.000); //Enable Survey in, 300 seconds, 2.0m
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println(F("Survey start failed"));
|
||||
lcd.setCursor(0, 3);
|
||||
lcd.print(F("Survey start failed"));
|
||||
while (1);
|
||||
}
|
||||
Serial.println(F("Survey started. This will run until 300s has passed and less than 2m accuracy is achieved."));
|
||||
}
|
||||
|
||||
while (Serial.available()) Serial.read(); //Clear buffer
|
||||
|
||||
lcd.clear();
|
||||
lcd.print(F("Survey in progress"));
|
||||
|
||||
//Begin waiting for survey to complete
|
||||
while (myGPS.svin.valid == false)
|
||||
{
|
||||
if (Serial.available())
|
||||
{
|
||||
byte incoming = Serial.read();
|
||||
if (incoming == 'x')
|
||||
{
|
||||
//Stop survey mode
|
||||
response = myGPS.disableSurveyMode(); //Disable survey
|
||||
Serial.println(F("Survey stopped"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (req can take a long time)
|
||||
if (response == true)
|
||||
{
|
||||
Serial.print(F("Press x to end survey - "));
|
||||
Serial.print(F("Time elapsed: "));
|
||||
Serial.print((String)myGPS.svin.observationTime);
|
||||
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("Elapsed: "));
|
||||
lcd.print((String)myGPS.svin.observationTime);
|
||||
|
||||
Serial.print(F(" Accuracy: "));
|
||||
Serial.print((String)myGPS.svin.meanAccuracy);
|
||||
Serial.println();
|
||||
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("Accuracy: "));
|
||||
lcd.print((String)myGPS.svin.meanAccuracy);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("SVIN request failed"));
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
Serial.println(F("Survey valid!"));
|
||||
|
||||
response = true;
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, UBX_RTCM_I2C_PORT, 1); //Enable message 1005 to output through I2C port, message every second
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1077, UBX_RTCM_I2C_PORT, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1087, UBX_RTCM_I2C_PORT, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, UBX_RTCM_I2C_PORT, 10); //Enable message every 10 seconds
|
||||
|
||||
if (response == true)
|
||||
{
|
||||
Serial.println(F("RTCM messages enabled"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("RTCM failed to enable. Are you sure you have an NEO-M8P?"));
|
||||
while (1); //Freeze
|
||||
}
|
||||
|
||||
Serial.println(F("Base survey complete! RTCM now broadcasting."));
|
||||
lcd.clear();
|
||||
lcd.print(F("Transmitting RTCM"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
|
||||
|
||||
//Do anything you want. Call checkUblox() every second. NEO-M8P-2 has TX buffer of 4k bytes.
|
||||
|
||||
delay(250); //Don't pound too hard on the I2C bus
|
||||
}
|
||||
|
||||
//This function gets called from the SparkFun Ublox Arduino Library.
|
||||
//As each RTCM byte comes in you can specify what to do with it
|
||||
//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
|
||||
void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
|
||||
{
|
||||
//Let's just pretty-print the HEX values for now
|
||||
if (myGPS.rtcmFrameCounter % 16 == 0) Serial.println();
|
||||
Serial.print(" ");
|
||||
if (incoming < 0x10) Serial.print("0");
|
||||
Serial.print(incoming, HEX);
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
Reading lat, long and UTC time via UBX binary commands - no more NMEA parsing!
|
||||
By: Paul Clark and Nathan Seidle
|
||||
Using the library modifications provided by @blazczak and @geeksville
|
||||
|
||||
SparkFun Electronics
|
||||
Date: June 16th, 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 query a Ublox module for its lat/long/altitude. We also
|
||||
turn off the NMEA output on the I2C port. This decreases the amount of I2C traffic
|
||||
dramatically.
|
||||
|
||||
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
|
||||
to something google maps understands simply divide the numbers by 10,000,000. We
|
||||
do this so that we don't have to use floating point numbers.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library_Series_6_7.h"
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
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)
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
Serial.print(F(" Time: "));
|
||||
|
||||
byte Hour = myGPS.getHour();
|
||||
if (Hour < 10)
|
||||
{
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
Serial.print(Hour);
|
||||
Serial.print(F(":"));
|
||||
|
||||
byte Minute = myGPS.getMinute();
|
||||
if (Minute < 10)
|
||||
{
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
Serial.print(Minute);
|
||||
Serial.print(F(":"));
|
||||
|
||||
byte Second = myGPS.getSecond();
|
||||
if (Second < 10)
|
||||
{
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
Serial.print(Second);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,932 @@
|
||||
/*
|
||||
This is a library written for the Ublox ZED-F9P and NEO-M8P-2
|
||||
|
||||
Updated: June 16th, 2020
|
||||
|
||||
This copy includes changes by @blazczak and @geeksville to
|
||||
provide support for the older series 6 and 7 modules.
|
||||
|
||||
Disclaimer: SparkFun has not verified this copy of the library on either series 6 or 7.
|
||||
It should work, it looks like it will work, but we have no way of confirming this.
|
||||
We cannot guarantee that it will work reliably in your application.
|
||||
|
||||
Do you like this library? Help support SparkFun. Buy a board!
|
||||
https://www.sparkfun.com/products/15136
|
||||
https://www.sparkfun.com/products/15005
|
||||
https://www.sparkfun.com/products/15733
|
||||
https://www.sparkfun.com/products/15193
|
||||
https://www.sparkfun.com/products/15210
|
||||
|
||||
Original library written by Nathan Seidle @ SparkFun Electronics, September 6th, 2018
|
||||
|
||||
This library handles configuring and handling the responses
|
||||
from a Ublox GPS module. Works with most modules from Ublox including
|
||||
the Zed-F9P, NEO-M8P-2, NEO-M9N, ZOE-M8Q, SAM-M8Q, and many others.
|
||||
|
||||
https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library
|
||||
|
||||
Development environment specifics:
|
||||
Arduino IDE 1.8.5
|
||||
|
||||
SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT).
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2016 SparkFun Electronics
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to
|
||||
do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SPARKFUN_UBLOX_ARDUINO_LIBRARY_H
|
||||
#define SPARKFUN_UBLOX_ARDUINO_LIBRARY_H
|
||||
|
||||
#if (ARDUINO >= 100)
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include <Wire.h>
|
||||
|
||||
//Platform specific configurations
|
||||
|
||||
//Define the size of the I2C buffer based on the platform the user has
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
|
||||
|
||||
//I2C_BUFFER_LENGTH is defined in Wire.H
|
||||
#define I2C_BUFFER_LENGTH BUFFER_LENGTH
|
||||
|
||||
#elif defined(__SAMD21G18A__)
|
||||
|
||||
//SAMD21 uses RingBuffer.h
|
||||
#define I2C_BUFFER_LENGTH SERIAL_BUFFER_SIZE
|
||||
|
||||
//#elif __MK20DX256__
|
||||
//Teensy
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef I2C_BUFFER_LENGTH
|
||||
|
||||
//The catch-all default is 32
|
||||
#define I2C_BUFFER_LENGTH 32
|
||||
//#define I2C_BUFFER_LENGTH 16 //For testing on Artemis
|
||||
|
||||
#endif
|
||||
|
||||
// Define Serial for SparkFun SAMD based boards.
|
||||
// Boards like the RedBoard Turbo use SerialUSB (not Serial).
|
||||
// But other boards like the SAMD51 Thing Plus use Serial (not SerialUSB).
|
||||
// The next nine lines let the code compile cleanly on as many SAMD boards as possible.
|
||||
#if defined(ARDUINO_ARCH_SAMD) // Is this a SAMD board?
|
||||
#if defined(USB_VID) // Is the USB Vendor ID defined?
|
||||
#if (USB_VID == 0x1B4F) // Is this a SparkFun board?
|
||||
#if !defined(ARDUINO_SAMD51_THING_PLUS) // If it is not a SAMD51 Thing Plus
|
||||
#define Serial SerialUSB // Define Serial as SerialUSB
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
//Define a digital pin to aid checksum failure capture and analysis
|
||||
//Leave set to -1 if not needed
|
||||
const int checksumFailurePin = -1;
|
||||
|
||||
// Global Status Returns
|
||||
typedef enum
|
||||
{
|
||||
SFE_UBLOX_STATUS_SUCCESS,
|
||||
SFE_UBLOX_STATUS_FAIL,
|
||||
SFE_UBLOX_STATUS_CRC_FAIL,
|
||||
SFE_UBLOX_STATUS_TIMEOUT,
|
||||
SFE_UBLOX_STATUS_COMMAND_NACK, // Indicates that the command was unrecognised, invalid or that the module is too busy to respond
|
||||
SFE_UBLOX_STATUS_OUT_OF_RANGE,
|
||||
SFE_UBLOX_STATUS_INVALID_ARG,
|
||||
SFE_UBLOX_STATUS_INVALID_OPERATION,
|
||||
SFE_UBLOX_STATUS_MEM_ERR,
|
||||
SFE_UBLOX_STATUS_HW_ERR,
|
||||
SFE_UBLOX_STATUS_DATA_SENT, // This indicates that a 'set' was successful
|
||||
SFE_UBLOX_STATUS_DATA_RECEIVED, // This indicates that a 'get' (poll) was successful
|
||||
SFE_UBLOX_STATUS_I2C_COMM_FAILURE,
|
||||
SFE_UBLOX_STATUS_DATA_OVERWRITTEN // This is an error - the data was valid but has been or _is being_ overwritten by another packet
|
||||
} sfe_ublox_status_e;
|
||||
|
||||
// ubxPacket validity
|
||||
typedef enum
|
||||
{
|
||||
SFE_UBLOX_PACKET_VALIDITY_NOT_VALID,
|
||||
SFE_UBLOX_PACKET_VALIDITY_VALID,
|
||||
SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED,
|
||||
SFE_UBLOX_PACKET_NOTACKNOWLEDGED // This indicates that we received a NACK
|
||||
} sfe_ublox_packet_validity_e;
|
||||
|
||||
// Identify which packet buffer is in use:
|
||||
// packetCfg (or a custom packet), packetAck or packetBuf
|
||||
typedef enum
|
||||
{
|
||||
SFE_UBLOX_PACKET_PACKETCFG,
|
||||
SFE_UBLOX_PACKET_PACKETACK,
|
||||
SFE_UBLOX_PACKET_PACKETBUF
|
||||
} sfe_ublox_packet_buffer_e;
|
||||
|
||||
//Registers
|
||||
const uint8_t UBX_SYNCH_1 = 0xB5;
|
||||
const uint8_t UBX_SYNCH_2 = 0x62;
|
||||
|
||||
//The following are UBX Class IDs. Descriptions taken from ZED-F9P Interface Description Document page 32, NEO-M8P Interface Description page 145
|
||||
const uint8_t UBX_CLASS_NAV = 0x01; //Navigation Results Messages: Position, Speed, Time, Acceleration, Heading, DOP, SVs used
|
||||
const uint8_t UBX_CLASS_RXM = 0x02; //Receiver Manager Messages: Satellite Status, RTC Status
|
||||
const uint8_t UBX_CLASS_INF = 0x04; //Information Messages: Printf-Style Messages, with IDs such as Error, Warning, Notice
|
||||
const uint8_t UBX_CLASS_ACK = 0x05; //Ack/Nak Messages: Acknowledge or Reject messages to UBX-CFG input messages
|
||||
const uint8_t UBX_CLASS_CFG = 0x06; //Configuration Input Messages: Configure the receiver.
|
||||
const uint8_t UBX_CLASS_UPD = 0x09; //Firmware Update Messages: Memory/Flash erase/write, Reboot, Flash identification, etc.
|
||||
const uint8_t UBX_CLASS_MON = 0x0A; //Monitoring Messages: Communication Status, CPU Load, Stack Usage, Task Status
|
||||
const uint8_t UBX_CLASS_AID = 0x0B; //(NEO-M8P ONLY!!!) AssistNow Aiding Messages: Ephemeris, Almanac, other A-GPS data input
|
||||
const uint8_t UBX_CLASS_TIM = 0x0D; //Timing Messages: Time Pulse Output, Time Mark Results
|
||||
const uint8_t UBX_CLASS_ESF = 0x10; //(NEO-M8P ONLY!!!) External Sensor Fusion Messages: External Sensor Measurements and Status Information
|
||||
const uint8_t UBX_CLASS_MGA = 0x13; //Multiple GNSS Assistance Messages: Assistance data for various GNSS
|
||||
const uint8_t UBX_CLASS_LOG = 0x21; //Logging Messages: Log creation, deletion, info and retrieval
|
||||
const uint8_t UBX_CLASS_SEC = 0x27; //Security Feature Messages
|
||||
const uint8_t UBX_CLASS_HNR = 0x28; //(NEO-M8P ONLY!!!) High Rate Navigation Results Messages: High rate time, position speed, heading
|
||||
const uint8_t UBX_CLASS_NMEA = 0xF0; //NMEA Strings: standard NMEA strings
|
||||
|
||||
//The following are used for configuration. Descriptions are from the ZED-F9P Interface Description pg 33-34 and NEO-M9N Interface Description pg 47-48
|
||||
const uint8_t UBX_CFG_ANT = 0x13; //Antenna Control Settings. Used to configure the antenna control settings
|
||||
const uint8_t UBX_CFG_BATCH = 0x93; //Get/set data batching configuration.
|
||||
const uint8_t UBX_CFG_CFG = 0x09; //Clear, Save, and Load Configurations. Used to save current configuration
|
||||
const uint8_t UBX_CFG_DAT = 0x06; //Set User-defined Datum or The currently defined Datum
|
||||
const uint8_t UBX_CFG_DGNSS = 0x70; //DGNSS configuration
|
||||
const uint8_t UBX_CFG_GEOFENCE = 0x69; //Geofencing configuration. Used to configure a geofence
|
||||
const uint8_t UBX_CFG_GNSS = 0x3E; //GNSS system configuration
|
||||
const uint8_t UBX_CFG_INF = 0x02; //Depending on packet length, either: poll configuration for one protocol, or information message configuration
|
||||
const uint8_t UBX_CFG_ITFM = 0x39; //Jamming/Interference Monitor configuration
|
||||
const uint8_t UBX_CFG_LOGFILTER = 0x47; //Data Logger Configuration
|
||||
const uint8_t UBX_CFG_MSG = 0x01; //Poll a message configuration, or Set Message Rate(s), or Set Message Rate
|
||||
const uint8_t UBX_CFG_NAV5 = 0x24; //Navigation Engine Settings. Used to configure the navigation engine including the dynamic model.
|
||||
const uint8_t UBX_CFG_NAVX5 = 0x23; //Navigation Engine Expert Settings
|
||||
const uint8_t UBX_CFG_NMEA = 0x17; //Extended NMEA protocol configuration V1
|
||||
const uint8_t UBX_CFG_ODO = 0x1E; //Odometer, Low-speed COG Engine Settings
|
||||
const uint8_t UBX_CFG_PM2 = 0x3B; //Extended power management configuration
|
||||
const uint8_t UBX_CFG_PMS = 0x86; //Power mode setup
|
||||
const uint8_t UBX_CFG_PRT = 0x00; //Used to configure port specifics. Polls the configuration for one I/O Port, or Port configuration for UART ports, or Port configuration for USB port, or Port configuration for SPI port, or Port configuration for DDC port
|
||||
const uint8_t UBX_CFG_PWR = 0x57; //Put receiver in a defined power state
|
||||
const uint8_t UBX_CFG_RATE = 0x08; //Navigation/Measurement Rate Settings. Used to set port baud rates.
|
||||
const uint8_t UBX_CFG_RINV = 0x34; //Contents of Remote Inventory
|
||||
const uint8_t UBX_CFG_RST = 0x04; //Reset Receiver / Clear Backup Data Structures. Used to reset device.
|
||||
const uint8_t UBX_CFG_RXM = 0x11; //RXM configuration
|
||||
const uint8_t UBX_CFG_SBAS = 0x16; //SBAS configuration
|
||||
const uint8_t UBX_CFG_TMODE3 = 0x71; //Time Mode Settings 3. Used to enable Survey In Mode
|
||||
const uint8_t UBX_CFG_TP5 = 0x31; //Time Pulse Parameters
|
||||
const uint8_t UBX_CFG_USB = 0x1B; //USB Configuration
|
||||
const uint8_t UBX_CFG_VALDEL = 0x8C; //Used for config of higher version Ublox modules (ie protocol v27 and above). Deletes values corresponding to provided keys/ provided keys with a transaction
|
||||
const uint8_t UBX_CFG_VALGET = 0x8B; //Used for config of higher version Ublox modules (ie protocol v27 and above). Configuration Items
|
||||
const uint8_t UBX_CFG_VALSET = 0x8A; //Used for config of higher version Ublox modules (ie protocol v27 and above). Sets values corresponding to provided key-value pairs/ provided key-value pairs within a transaction.
|
||||
|
||||
//The following are used to enable NMEA messages. Descriptions come from the NMEA messages overview in the ZED-F9P Interface Description
|
||||
const uint8_t UBX_NMEA_MSB = 0xF0; //All NMEA enable commands have 0xF0 as MSB
|
||||
const uint8_t UBX_NMEA_DTM = 0x0A; //GxDTM (datum reference)
|
||||
const uint8_t UBX_NMEA_GAQ = 0x45; //GxGAQ (poll a standard message (if the current talker ID is GA))
|
||||
const uint8_t UBX_NMEA_GBQ = 0x44; //GxGBQ (poll a standard message (if the current Talker ID is GB))
|
||||
const uint8_t UBX_NMEA_GBS = 0x09; //GxGBS (GNSS satellite fault detection)
|
||||
const uint8_t UBX_NMEA_GGA = 0x00; //GxGGA (Global positioning system fix data)
|
||||
const uint8_t UBX_NMEA_GLL = 0x01; //GxGLL (latitude and long, whith time of position fix and status)
|
||||
const uint8_t UBX_NMEA_GLQ = 0x43; //GxGLQ (poll a standard message (if the current Talker ID is GL))
|
||||
const uint8_t UBX_NMEA_GNQ = 0x42; //GxGNQ (poll a standard message (if the current Talker ID is GN))
|
||||
const uint8_t UBX_NMEA_GNS = 0x0D; //GxGNS (GNSS fix data)
|
||||
const uint8_t UBX_NMEA_GPQ = 0x040; //GxGPQ (poll a standard message (if the current Talker ID is GP))
|
||||
const uint8_t UBX_NMEA_GRS = 0x06; //GxGRS (GNSS range residuals)
|
||||
const uint8_t UBX_NMEA_GSA = 0x02; //GxGSA (GNSS DOP and Active satellites)
|
||||
const uint8_t UBX_NMEA_GST = 0x07; //GxGST (GNSS Pseudo Range Error Statistics)
|
||||
const uint8_t UBX_NMEA_GSV = 0x03; //GxGSV (GNSS satellites in view)
|
||||
const uint8_t UBX_NMEA_RMC = 0x04; //GxRMC (Recommended minimum data)
|
||||
const uint8_t UBX_NMEA_TXT = 0x41; //GxTXT (text transmission)
|
||||
const uint8_t UBX_NMEA_VLW = 0x0F; //GxVLW (dual ground/water distance)
|
||||
const uint8_t UBX_NMEA_VTG = 0x05; //GxVTG (course over ground and Ground speed)
|
||||
const uint8_t UBX_NMEA_ZDA = 0x08; //GxZDA (Time and Date)
|
||||
|
||||
//The following are used to configure the NMEA protocol main talker ID and GSV talker ID
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_NOTOVERRIDDEN = 0x00; //main talker ID is system dependent
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_GP = 0x01; //main talker ID is GPS
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_GL = 0x02; //main talker ID is GLONASS
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_GN = 0x03; //main talker ID is combined receiver
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_GA = 0x04; //main talker ID is Galileo
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_GB = 0x05; //main talker ID is BeiDou
|
||||
const uint8_t UBX_NMEA_GSVTALKERID_GNSS = 0x00; //GNSS specific Talker ID (as defined by NMEA)
|
||||
const uint8_t UBX_NMEA_GSVTALKERID_MAIN = 0x01; //use the main Talker ID
|
||||
|
||||
//The following are used to configure INF UBX messages (information messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 34)
|
||||
const uint8_t UBX_INF_CLASS = 0x04; //All INF messages have 0x04 as the class
|
||||
const uint8_t UBX_INF_DEBUG = 0x04; //ASCII output with debug contents
|
||||
const uint8_t UBX_INF_ERROR = 0x00; //ASCII output with error contents
|
||||
const uint8_t UBX_INF_NOTICE = 0x02; //ASCII output with informational contents
|
||||
const uint8_t UBX_INF_TEST = 0x03; //ASCII output with test contents
|
||||
const uint8_t UBX_INF_WARNING = 0x01; //ASCII output with warning contents
|
||||
|
||||
//The following are used to configure LOG UBX messages (loggings messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 34)
|
||||
const uint8_t UBX_LOG_CREATE = 0x07; //Create Log File
|
||||
const uint8_t UBX_LOG_ERASE = 0x03; //Erase Logged Data
|
||||
const uint8_t UBX_LOG_FINDTIME = 0x0E; //Find index of a log entry based on a given time, or response to FINDTIME requested
|
||||
const uint8_t UBX_LOG_INFO = 0x08; //Poll for log information, or Log information
|
||||
const uint8_t UBX_LOG_RETRIEVEPOSEXTRA = 0x0F; //Odometer log entry
|
||||
const uint8_t UBX_LOG_RETRIEVEPOS = 0x0B; //Position fix log entry
|
||||
const uint8_t UBX_LOG_RETRIEVESTRING = 0x0D; //Byte string log entry
|
||||
const uint8_t UBX_LOG_RETRIEVE = 0x09; //Request log data
|
||||
const uint8_t UBX_LOG_STRING = 0x04; //Store arbitrary string on on-board flash
|
||||
|
||||
//The following are used to configure MGA UBX messages (Multiple GNSS Assistance Messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 34)
|
||||
const uint8_t UBX_MGA_ACK_DATA0 = 0x60; //Multiple GNSS Acknowledge message
|
||||
const uint8_t UBX_MGA_BDS_EPH = 0x03; //BDS Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_BDS_ALM = 0x03; //BDS Almanac Assistance
|
||||
const uint8_t UBX_MGA_BDS_HEALTH = 0x03; //BDS Health Assistance
|
||||
const uint8_t UBX_MGA_BDS_UTC = 0x03; //BDS UTC Assistance
|
||||
const uint8_t UBX_MGA_BDS_IONO = 0x03; //BDS Ionospheric Assistance
|
||||
const uint8_t UBX_MGA_DBD = 0x80; //Either: Poll the Navigation Database, or Navigation Database Dump Entry
|
||||
const uint8_t UBX_MGA_GAL_EPH = 0x02; //Galileo Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_GAL_ALM = 0x02; //Galileo Almanac Assitance
|
||||
const uint8_t UBX_MGA_GAL_TIMOFFSET = 0x02; //Galileo GPS time offset assistance
|
||||
const uint8_t UBX_MGA_GAL_UTC = 0x02; //Galileo UTC Assistance
|
||||
const uint8_t UBX_MGA_GLO_EPH = 0x06; //GLONASS Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_GLO_ALM = 0x06; //GLONASS Almanac Assistance
|
||||
const uint8_t UBX_MGA_GLO_TIMEOFFSET = 0x06; //GLONASS Auxiliary Time Offset Assistance
|
||||
const uint8_t UBX_MGA_GPS_EPH = 0x00; //GPS Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_GPS_ALM = 0x00; //GPS Almanac Assistance
|
||||
const uint8_t UBX_MGA_GPS_HEALTH = 0x00; //GPS Health Assistance
|
||||
const uint8_t UBX_MGA_GPS_UTC = 0x00; //GPS UTC Assistance
|
||||
const uint8_t UBX_MGA_GPS_IONO = 0x00; //GPS Ionosphere Assistance
|
||||
const uint8_t UBX_MGA_INI_POS_XYZ = 0x40; //Initial Position Assistance
|
||||
const uint8_t UBX_MGA_INI_POS_LLH = 0x40; //Initial Position Assitance
|
||||
const uint8_t UBX_MGA_INI_TIME_UTC = 0x40; //Initial Time Assistance
|
||||
const uint8_t UBX_MGA_INI_TIME_GNSS = 0x40; //Initial Time Assistance
|
||||
const uint8_t UBX_MGA_INI_CLKD = 0x40; //Initial Clock Drift Assitance
|
||||
const uint8_t UBX_MGA_INI_FREQ = 0x40; //Initial Frequency Assistance
|
||||
const uint8_t UBX_MGA_INI_EOP = 0x40; //Earth Orientation Parameters Assistance
|
||||
const uint8_t UBX_MGA_QZSS_EPH = 0x05; //QZSS Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_QZSS_ALM = 0x05; //QZSS Almanac Assistance
|
||||
const uint8_t UBX_MGA_QZAA_HEALTH = 0x05; //QZSS Health Assistance
|
||||
|
||||
//The following are used to configure the MON UBX messages (monitoring messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 35)
|
||||
const uint8_t UBX_MON_COMMS = 0x36; //Comm port information
|
||||
const uint8_t UBX_MON_GNSS = 0x28; //Information message major GNSS selection
|
||||
const uint8_t UBX_MON_HW2 = 0x0B; //Extended Hardware Status
|
||||
const uint8_t UBX_MON_HW3 = 0x37; //HW I/O pin information
|
||||
const uint8_t UBX_MON_HW = 0x09; //Hardware Status
|
||||
const uint8_t UBX_MON_IO = 0x02; //I/O Subsystem Status
|
||||
const uint8_t UBX_MON_MSGPP = 0x06; //Message Parse and Process Status
|
||||
const uint8_t UBX_MON_PATCH = 0x27; //Output information about installed patches
|
||||
const uint8_t UBX_MON_RF = 0x38; //RF information
|
||||
const uint8_t UBX_MON_RXBUF = 0x07; //Receiver Buffer Status
|
||||
const uint8_t UBX_MON_RXR = 0x21; //Receiver Status Information
|
||||
const uint8_t UBX_MON_TXBUF = 0x08; //Transmitter Buffer Status. Used for query tx buffer size/state.
|
||||
const uint8_t UBX_MON_VER = 0x04; //Receiver/Software Version. Used for obtaining Protocol Version.
|
||||
|
||||
//The following are used to configure the NAV UBX messages (navigation results messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 35-36)
|
||||
const uint8_t UBX_NAV_ATT = 0x05; //Vehicle "Attitude" Solution
|
||||
const uint8_t UBX_NAV_CLOCK = 0x22; //Clock Solution
|
||||
const uint8_t UBX_NAV_DOP = 0x04; //Dilution of precision
|
||||
const uint8_t UBX_NAV_EOE = 0x61; //End of Epoch
|
||||
const uint8_t UBX_NAV_GEOFENCE = 0x39; //Geofencing status. Used to poll the geofence status
|
||||
const uint8_t UBX_NAV_HPPOSECEF = 0x13; //High Precision Position Solution in ECEF. Used to find our positional accuracy (high precision).
|
||||
const uint8_t UBX_NAV_HPPOSLLH = 0x14; //High Precision Geodetic Position Solution. Used for obtaining lat/long/alt in high precision
|
||||
const uint8_t UBX_NAV_ODO = 0x09; //Odometer Solution
|
||||
const uint8_t UBX_NAV_ORB = 0x34; //GNSS Orbit Database Info
|
||||
const uint8_t UBX_NAV_POSECEF = 0x01; //Position Solution in ECEF
|
||||
const uint8_t UBX_NAV_POSLLH = 0x02; //Geodetic Position Solution
|
||||
const uint8_t UBX_NAV_PVT = 0x07; //All the things! Position, velocity, time, PDOP, height, h/v accuracies, number of satellites. Navigation Position Velocity Time Solution.
|
||||
const uint8_t UBX_NAV_RELPOSNED = 0x3C; //Relative Positioning Information in NED frame
|
||||
const uint8_t UBX_NAV_RESETODO = 0x10; //Reset odometer
|
||||
const uint8_t UBX_NAV_SAT = 0x35; //Satellite Information
|
||||
const uint8_t UBX_NAV_SIG = 0x43; //Signal Information
|
||||
const uint8_t UBX_NAV_STATUS = 0x03; //Receiver Navigation Status
|
||||
const uint8_t UBX_NAV_SVIN = 0x3B; //Survey-in data. Used for checking Survey In status
|
||||
const uint8_t UBX_NAV_TIMEBDS = 0x24; //BDS Time Solution
|
||||
const uint8_t UBX_NAV_TIMEGAL = 0x25; //Galileo Time Solution
|
||||
const uint8_t UBX_NAV_TIMEGLO = 0x23; //GLO Time Solution
|
||||
const uint8_t UBX_NAV_TIMEGPS = 0x20; //GPS Time Solution
|
||||
const uint8_t UBX_NAV_TIMELS = 0x26; //Leap second event information
|
||||
const uint8_t UBX_NAV_TIMEUTC = 0x21; //UTC Time Solution
|
||||
const uint8_t UBX_NAV_VELECEF = 0x11; //Velocity Solution in ECEF
|
||||
const uint8_t UBX_NAV_VELNED = 0x12; //Velocity Solution in NED
|
||||
|
||||
//The following are used to configure the RXM UBX messages (receiver manager messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 36)
|
||||
const uint8_t UBX_RXM_MEASX = 0x14; //Satellite Measurements for RRLP
|
||||
const uint8_t UBX_RXM_PMREQ = 0x41; //Requests a Power Management task (two differenent packet sizes)
|
||||
const uint8_t UBX_RXM_RAWX = 0x15; //Multi-GNSS Raw Measurement Data
|
||||
const uint8_t UBX_RXM_RLM = 0x59; //Galileo SAR Short-RLM report (two different packet sizes)
|
||||
const uint8_t UBX_RXM_RTCM = 0x32; //RTCM input status
|
||||
const uint8_t UBX_RXM_SFRBX = 0x13; //Boradcast Navigation Data Subframe
|
||||
|
||||
//The following are used to configure the SEC UBX messages (security feature messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 36)
|
||||
const uint8_t UBX_SEC_UNIQID = 0x03; //Unique chip ID
|
||||
|
||||
//The following are used to configure the TIM UBX messages (timing messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 36)
|
||||
const uint8_t UBX_TIM_TM2 = 0x03; //Time mark data
|
||||
const uint8_t UBX_TIM_TP = 0x01; //Time Pulse Timedata
|
||||
const uint8_t UBX_TIM_VRFY = 0x06; //Sourced Time Verification
|
||||
|
||||
//The following are used to configure the UPD UBX messages (firmware update messages). Descriptions from UBX messages overview (ZED-F9P Interface Description Document page 36)
|
||||
const uint8_t UBX_UPD_SOS = 0x14; //Poll Backup Fil Restore Status, Create Backup File in Flash, Clear Backup File in Flash, Backup File Creation Acknowledge, System Restored from Backup
|
||||
|
||||
//The following are used to enable RTCM messages
|
||||
const uint8_t UBX_RTCM_MSB = 0xF5; //All RTCM enable commands have 0xF5 as MSB
|
||||
const uint8_t UBX_RTCM_1005 = 0x05; //Stationary RTK reference ARP
|
||||
const uint8_t UBX_RTCM_1074 = 0x4A; //GPS MSM4
|
||||
const uint8_t UBX_RTCM_1077 = 0x4D; //GPS MSM7
|
||||
const uint8_t UBX_RTCM_1084 = 0x54; //GLONASS MSM4
|
||||
const uint8_t UBX_RTCM_1087 = 0x57; //GLONASS MSM7
|
||||
const uint8_t UBX_RTCM_1094 = 0x5E; //Galileo MSM4
|
||||
const uint8_t UBX_RTCM_1097 = 0x61; //Galileo MSM7
|
||||
const uint8_t UBX_RTCM_1124 = 0x7C; //BeiDou MSM4
|
||||
const uint8_t UBX_RTCM_1127 = 0x7F; //BeiDou MSM7
|
||||
const uint8_t UBX_RTCM_1230 = 0xE6; //GLONASS code-phase biases, set to once every 10 seconds
|
||||
const uint8_t UBX_RTCM_4072_0 = 0xFE; //Reference station PVT (ublox proprietary RTCM message)
|
||||
const uint8_t UBX_RTCM_4072_1 = 0xFD; //Additional reference station information (ublox proprietary RTCM message)
|
||||
|
||||
const uint8_t UBX_ACK_NACK = 0x00;
|
||||
const uint8_t UBX_ACK_ACK = 0x01;
|
||||
const uint8_t UBX_ACK_NONE = 0x02; //Not a real value
|
||||
|
||||
// The following constants are used to get External Sensor Measurements and Status
|
||||
// Information.
|
||||
const uint8_t UBX_ESF_MEAS = 0x02;
|
||||
const uint8_t UBX_ESF_RAW = 0x03;
|
||||
const uint8_t UBX_ESF_STATUS = 0x10;
|
||||
const uint8_t UBX_ESF_INS = 0x15; //36 bytes
|
||||
|
||||
const uint8_t SVIN_MODE_DISABLE = 0x00;
|
||||
const uint8_t SVIN_MODE_ENABLE = 0x01;
|
||||
|
||||
//The following consts are used to configure the various ports and streams for those ports. See -CFG-PRT.
|
||||
const uint8_t COM_PORT_I2C = 0;
|
||||
const uint8_t COM_PORT_UART1 = 1;
|
||||
const uint8_t COM_PORT_UART2 = 2;
|
||||
const uint8_t COM_PORT_USB = 3;
|
||||
const uint8_t COM_PORT_SPI = 4;
|
||||
|
||||
const uint8_t COM_TYPE_UBX = (1 << 0);
|
||||
const uint8_t COM_TYPE_NMEA = (1 << 1);
|
||||
const uint8_t COM_TYPE_RTCM3 = (1 << 5);
|
||||
|
||||
//The following consts are used to generate KEY values for the advanced protocol functions of VELGET/SET/DEL
|
||||
const uint8_t VAL_SIZE_1 = 0x01; //One bit
|
||||
const uint8_t VAL_SIZE_8 = 0x02; //One byte
|
||||
const uint8_t VAL_SIZE_16 = 0x03; //Two bytes
|
||||
const uint8_t VAL_SIZE_32 = 0x04; //Four bytes
|
||||
const uint8_t VAL_SIZE_64 = 0x05; //Eight bytes
|
||||
|
||||
//These are the Bitfield layers definitions for the UBX-CFG-VALSET message (not to be confused with Bitfield deviceMask in UBX-CFG-CFG)
|
||||
const uint8_t VAL_LAYER_RAM = (1 << 0);
|
||||
const uint8_t VAL_LAYER_BBR = (1 << 1);
|
||||
const uint8_t VAL_LAYER_FLASH = (1 << 2);
|
||||
|
||||
//Below are various Groups, IDs, and sizes for various settings
|
||||
//These can be used to call getVal/setVal/delVal
|
||||
const uint8_t VAL_GROUP_I2COUTPROT = 0x72;
|
||||
const uint8_t VAL_GROUP_I2COUTPROT_SIZE = VAL_SIZE_1; //All fields in I2C group are currently 1 bit
|
||||
|
||||
const uint8_t VAL_ID_I2COUTPROT_UBX = 0x01;
|
||||
const uint8_t VAL_ID_I2COUTPROT_NMEA = 0x02;
|
||||
const uint8_t VAL_ID_I2COUTPROT_RTCM3 = 0x03;
|
||||
|
||||
const uint8_t VAL_GROUP_I2C = 0x51;
|
||||
const uint8_t VAL_GROUP_I2C_SIZE = VAL_SIZE_8; //All fields in I2C group are currently 1 byte
|
||||
|
||||
const uint8_t VAL_ID_I2C_ADDRESS = 0x01;
|
||||
|
||||
// Configuration Sub-Section mask definitions for saveConfigSelective (UBX-CFG-CFG)
|
||||
const uint32_t VAL_CFG_SUBSEC_IOPORT = 0x00000001; // ioPort - communications port settings (causes IO system reset!)
|
||||
const uint32_t VAL_CFG_SUBSEC_MSGCONF = 0x00000002; // msgConf - message configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_INFMSG = 0x00000004; // infMsg - INF message configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_NAVCONF = 0x00000008; // navConf - navigation configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_RXMCONF = 0x00000010; // rxmConf - receiver manager configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_SENCONF = 0x00000100; // senConf - sensor interface configuration (requires protocol 19+)
|
||||
const uint32_t VAL_CFG_SUBSEC_RINVCONF = 0x00000200; // rinvConf - remove inventory configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_ANTCONF = 0x00000400; // antConf - antenna configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_LOGCONF = 0x00000800; // logConf - logging configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_FTSCONF = 0x00001000; // ftsConf - FTS configuration (FTS products only)
|
||||
|
||||
enum dynModel // Possible values for the dynamic platform model, which provide more accuract position output for the situation. Description extracted from ZED-F9P Integration Manual
|
||||
{
|
||||
DYN_MODEL_PORTABLE = 0, //Applications with low acceleration, e.g. portable devices. Suitable for most situations.
|
||||
// 1 is not defined
|
||||
DYN_MODEL_STATIONARY = 2, //Used in timing applications (antenna must be stationary) or other stationary applications. Velocity restricted to 0 m/s. Zero dynamics assumed.
|
||||
DYN_MODEL_PEDESTRIAN, //Applications with low acceleration and speed, e.g. how a pedestrian would move. Low acceleration assumed.
|
||||
DYN_MODEL_AUTOMOTIVE, //Used for applications with equivalent dynamics to those of a passenger car. Low vertical acceleration assumed
|
||||
DYN_MODEL_SEA, //Recommended for applications at sea, with zero vertical velocity. Zero vertical velocity assumed. Sea level assumed.
|
||||
DYN_MODEL_AIRBORNE1g, //Airborne <1g acceleration. Used for applications with a higher dynamic range and greater vertical acceleration than a passenger car. No 2D position fixes supported.
|
||||
DYN_MODEL_AIRBORNE2g, //Airborne <2g acceleration. Recommended for typical airborne environments. No 2D position fixes supported.
|
||||
DYN_MODEL_AIRBORNE4g, //Airborne <4g acceleration. Only recommended for extremely dynamic environments. No 2D position fixes supported.
|
||||
DYN_MODEL_WRIST, // Not supported in protocol versions less than 18. Only recommended for wrist worn applications. Receiver will filter out arm motion.
|
||||
DYN_MODEL_BIKE, // Supported in protocol versions 19.2
|
||||
};
|
||||
|
||||
#ifndef MAX_PAYLOAD_SIZE
|
||||
|
||||
#define MAX_PAYLOAD_SIZE 256 //We need ~220 bytes for getProtocolVersion on most ublox modules
|
||||
//#define MAX_PAYLOAD_SIZE 768 //Worst case: UBX_CFG_VALSET packet with 64 keyIDs each with 64 bit values
|
||||
|
||||
#endif
|
||||
|
||||
//-=-=-=-=- UBX binary specific variables
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cls;
|
||||
uint8_t 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;
|
||||
uint8_t checksumA; //Given to us from 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
|
||||
} ubxPacket;
|
||||
|
||||
// Struct to hold the results returned by getGeofenceState (returned by UBX-NAV-GEOFENCE)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t status; // Geofencing status: 0 - Geofencing not available or not reliable; 1 - Geofencing active
|
||||
uint8_t numFences; // Number of geofences
|
||||
uint8_t combState; // Combined (logical OR) state of all geofences: 0 - Unknown; 1 - Inside; 2 - Outside
|
||||
uint8_t states[4]; // Geofence states: 0 - Unknown; 1 - Inside; 2 - Outside
|
||||
} geofenceState;
|
||||
|
||||
// Struct to hold the current geofence parameters
|
||||
typedef struct
|
||||
{
|
||||
uint8_t numFences; // Number of active geofences
|
||||
int32_t lats[4]; // Latitudes of geofences (in degrees * 10^-7)
|
||||
int32_t longs[4]; // Longitudes of geofences (in degrees * 10^-7)
|
||||
uint32_t rads[4]; // Radii of geofences (in m * 10^-2)
|
||||
} geofenceParams;
|
||||
|
||||
class SFE_UBLOX_GPS
|
||||
{
|
||||
public:
|
||||
SFE_UBLOX_GPS(void);
|
||||
|
||||
// A default of 250ms for maxWait seems fine for I2C but is not enough for SerialUSB.
|
||||
// If you know you are only going to be using I2C / Qwiic communication, you can
|
||||
// safely reduce defaultMaxWait to 250.
|
||||
#ifndef defaultMaxWait // Let's allow the user to define their own value if they want to
|
||||
#define defaultMaxWait 1100
|
||||
#endif
|
||||
|
||||
//By default use the default I2C address, and use Wire port
|
||||
boolean begin(TwoWire &wirePort = Wire, uint8_t deviceAddress = 0x42); //Returns true if module is detected
|
||||
//serialPort needs to be perviously initialized to correct baud rate
|
||||
boolean begin(Stream &serialPort); //Returns true if module is detected
|
||||
|
||||
//Returns true if device answers on _gpsI2Caddress address or via Serial
|
||||
//maxWait is only used for Serial
|
||||
boolean isConnected(uint16_t maxWait = 1100);
|
||||
|
||||
//Changed in V1.8.1: provides backward compatibility for the examples that call checkUblox directly
|
||||
//Will default to using packetCfg to look for explicit autoPVT packets so they get processed correctly by processUBX
|
||||
boolean checkUblox(uint8_t requestedClass = UBX_CLASS_NAV, uint8_t requestedID = UBX_NAV_PVT); //Checks module with user selected commType
|
||||
|
||||
boolean checkUbloxI2C(ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); //Method for I2C polling of data, passing any new bytes to process()
|
||||
boolean checkUbloxSerial(ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); //Method for serial polling of data, passing any new bytes to process()
|
||||
|
||||
void process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); //Processes NMEA and UBX binary sentences one byte at a time
|
||||
void processUBX(uint8_t incoming, ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); //Given a character, file it away into the uxb packet structure
|
||||
void processRTCMframe(uint8_t incoming); //Monitor the incoming bytes for start and length bytes
|
||||
void processRTCM(uint8_t incoming) __attribute__((weak)); //Given rtcm byte, do something with it. User can overwrite if desired to pipe bytes to radio, internet, etc.
|
||||
|
||||
void processUBXpacket(ubxPacket *msg); //Once a packet has been received and validated, identify this packet's class/id and update internal flags
|
||||
void processNMEA(char incoming) __attribute__((weak)); //Given a NMEA character, do something with it. User can overwrite if desired to use something like tinyGPS or MicroNMEA libraries
|
||||
|
||||
void calcChecksum(ubxPacket *msg); //Sets the checksumA and checksumB of a given messages
|
||||
sfe_ublox_status_e sendCommand(ubxPacket *outgoingUBX, uint16_t maxWait = defaultMaxWait); //Given a packet and payload, send everything including CRC bytes, return true if we got a response
|
||||
sfe_ublox_status_e sendI2cCommand(ubxPacket *outgoingUBX, uint16_t maxWait = 250);
|
||||
void sendSerialCommand(ubxPacket *outgoingUBX);
|
||||
|
||||
void printPacket(ubxPacket *packet); //Useful for debugging
|
||||
|
||||
void factoryReset(); //Send factory reset sequence (i.e. load "default" configuration and perform hardReset)
|
||||
void hardReset(); //Perform a reset leading to a cold start (zero info start-up)
|
||||
|
||||
boolean setI2CAddress(uint8_t deviceAddress, uint16_t maxTime = 250); //Changes the I2C address of the Ublox module
|
||||
void setSerialRate(uint32_t baudrate, uint8_t uartPort = COM_PORT_UART1, uint16_t maxTime = defaultMaxWait); //Changes the serial baud rate of the Ublox module, uartPort should be COM_PORT_UART1/2
|
||||
void setNMEAOutputPort(Stream &nmeaOutputPort); //Sets the internal variable for the port to direct NMEA characters to
|
||||
|
||||
boolean setNavigationFrequency(uint8_t navFreq, uint16_t maxWait = defaultMaxWait); //Set the number of nav solutions sent per second
|
||||
uint8_t getNavigationFrequency(uint16_t maxWait = defaultMaxWait); //Get the number of nav solutions sent per second currently being output by module
|
||||
boolean saveConfiguration(uint16_t maxWait = defaultMaxWait); //Save current configuration to flash and BBR (battery backed RAM)
|
||||
boolean factoryDefault(uint16_t maxWait = defaultMaxWait); //Reset module to factory defaults
|
||||
boolean saveConfigSelective(uint32_t configMask, uint16_t maxWait = defaultMaxWait); //Save the selected configuration sub-sections to flash and BBR (battery backed RAM)
|
||||
|
||||
sfe_ublox_status_e waitForACKResponse(ubxPacket *outgoingUBX, uint8_t requestedClass, uint8_t requestedID, uint16_t maxTime = defaultMaxWait); //Poll the module until a config packet and an ACK is received
|
||||
sfe_ublox_status_e waitForNoACKResponse(ubxPacket *outgoingUBX, uint8_t requestedClass, uint8_t requestedID, uint16_t maxTime = defaultMaxWait); //Poll the module until a config packet is received
|
||||
|
||||
// getPVT will only return data once in each navigation cycle. By default, that is once per second.
|
||||
// Therefore we should set getPVTmaxWait to slightly longer than that.
|
||||
// If you change the navigation frequency to (e.g.) 4Hz using setNavigationFrequency(4)
|
||||
// then you should use a shorter maxWait for getPVT. 300msec would be about right: getPVT(300)
|
||||
// The same is true for getHPPOSLLH.
|
||||
#define getPVTmaxWait 1100 // Default maxWait for getPVT and all functions which call it
|
||||
#define getHPPOSLLHmaxWait 1100 // Default maxWait for getHPPOSLLH and all functions which call it
|
||||
|
||||
boolean assumeAutoPVT(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and PVT is send cyclically already
|
||||
boolean setAutoPVT(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic PVT reports at the navigation frequency
|
||||
boolean getPVT(uint16_t maxWait = getPVTmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Returns true if new PVT is available.
|
||||
boolean getTimeData(uint16_t maxWait = getPVTmaxWait); //Query module for latest time data. Calls getPVT or getTIMEUTC depending on which module is attached.
|
||||
boolean getPositionData(uint16_t maxWait = getPVTmaxWait); //Query module for latest position data. Calls getPVT or getPOSLLH depending on which module is attached.
|
||||
boolean getTIMEUTC(uint16_t maxWait = getPVTmaxWait); //Query module for current time (for use with older chip series). Returns true if new data is available.
|
||||
boolean getPOSLLH(uint16_t maxWait = getPVTmaxWait); //Query module for current position (for use with older chip series). Returns true if new data is available.
|
||||
|
||||
boolean setAutoPVT(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic PVT reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update
|
||||
boolean getHPPOSLLH(uint16_t maxWait = getHPPOSLLHmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Returns true if new PVT is available.
|
||||
void flushPVT(); //Mark all the PVT data as read/stale. This is handy to get data alignment after CRC failure
|
||||
|
||||
int32_t getLatitude(uint16_t maxWait = getPVTmaxWait); //Returns the current latitude in degrees * 10^-7. Auto selects between HighPrecision and Regular depending on ability of module.
|
||||
int32_t getLongitude(uint16_t maxWait = getPVTmaxWait); //Returns the current longitude in degrees * 10-7. Auto selects between HighPrecision and Regular depending on ability of module.
|
||||
int32_t getAltitude(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above ellipsoid
|
||||
int32_t getAltitudeMSL(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above mean sea level
|
||||
uint8_t getSIV(uint16_t maxWait = getPVTmaxWait); //Returns number of sats used in fix
|
||||
uint8_t getFixType(uint16_t maxWait = getPVTmaxWait); //Returns the type of fix: 0=no, 3=3D, 4=GNSS+Deadreckoning
|
||||
uint8_t getCarrierSolutionType(uint16_t maxWait = getPVTmaxWait); //Returns RTK solution: 0=no, 1=float solution, 2=fixed solution
|
||||
int32_t getGroundSpeed(uint16_t maxWait = getPVTmaxWait); //Returns speed in mm/s
|
||||
int32_t getHeading(uint16_t maxWait = getPVTmaxWait); //Returns heading in degrees * 10^-7
|
||||
uint16_t getPDOP(uint16_t maxWait = getPVTmaxWait); //Returns positional dillution of precision * 10^-2 (dimensionless)
|
||||
uint16_t getYear(uint16_t maxWait = getPVTmaxWait);
|
||||
uint8_t getMonth(uint16_t maxWait = getPVTmaxWait);
|
||||
uint8_t getDay(uint16_t maxWait = getPVTmaxWait);
|
||||
uint8_t getHour(uint16_t maxWait = getPVTmaxWait);
|
||||
uint8_t getMinute(uint16_t maxWait = getPVTmaxWait);
|
||||
uint8_t getSecond(uint16_t maxWait = getPVTmaxWait);
|
||||
uint16_t getMillisecond(uint16_t maxWait = getPVTmaxWait);
|
||||
int32_t getNanosecond(uint16_t maxWait = getPVTmaxWait);
|
||||
uint32_t getTimeOfWeek(uint16_t maxWait = getPVTmaxWait);
|
||||
|
||||
int32_t getHighResLatitude(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int8_t getHighResLatitudeHp(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int32_t getHighResLongitude(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int8_t getHighResLongitudeHp(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int32_t getElipsoid(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int8_t getElipsoidHp(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int32_t getMeanSeaLevel(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int8_t getMeanSeaLevelHp(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int32_t getGeoidSeparation(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
uint32_t getHorizontalAccuracy(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
uint32_t getVerticalAccuracy(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
|
||||
//Port configurations
|
||||
boolean setPortOutput(uint8_t portID, uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure a given port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
boolean setPortInput(uint8_t portID, uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure a given port to input UBX, NMEA, RTCM3 or a combination thereof
|
||||
boolean getPortSettings(uint8_t portID, uint16_t maxWait = defaultMaxWait); //Returns the current protocol bits in the UBX-CFG-PRT command for a given port
|
||||
|
||||
boolean setI2COutput(uint8_t comSettings, uint16_t maxWait = 250); //Configure I2C port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
boolean setUART1Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART1 port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
boolean setUART2Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART2 port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
boolean setUSBOutput(uint8_t comSettings, uint16_t maxWait = 250); //Configure USB port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
boolean setSPIOutput(uint8_t comSettings, uint16_t maxWait = 250); //Configure SPI port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
|
||||
//Functions to turn on/off message types for a given port ID (see COM_PORT_I2C, etc above)
|
||||
boolean configureMessage(uint8_t msgClass, uint8_t msgID, uint8_t portID, uint8_t sendRate, uint16_t maxWait = defaultMaxWait);
|
||||
boolean enableMessage(uint8_t msgClass, uint8_t msgID, uint8_t portID, uint8_t sendRate = 1, uint16_t maxWait = defaultMaxWait);
|
||||
boolean disableMessage(uint8_t msgClass, uint8_t msgID, uint8_t portID, uint16_t maxWait = defaultMaxWait);
|
||||
boolean enableNMEAMessage(uint8_t msgID, uint8_t portID, uint8_t sendRate = 1, uint16_t maxWait = defaultMaxWait);
|
||||
boolean disableNMEAMessage(uint8_t msgID, uint8_t portID, uint16_t maxWait = defaultMaxWait);
|
||||
boolean enableRTCMmessage(uint8_t messageNumber, uint8_t portID, uint8_t sendRate, uint16_t maxWait = defaultMaxWait); //Given a message number turns on a message ID for output over given PortID
|
||||
boolean disableRTCMmessage(uint8_t messageNumber, uint8_t portID, uint16_t maxWait = defaultMaxWait); //Turn off given RTCM message from a given port
|
||||
|
||||
//General configuration (used only on protocol v27 and higher - ie, ZED-F9P)
|
||||
//It is probably safe to assume that users of the ZED-F9P will be using I2C / Qwiic.
|
||||
//If they are using Serial then the higher baud rate will also help. So let's leave maxWait set to 250ms.
|
||||
uint8_t getVal8(uint16_t group, uint16_t id, uint8_t size, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Returns the value at a given group/id/size location
|
||||
uint8_t getVal8(uint32_t keyID, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Returns the value at a given group/id/size location
|
||||
uint8_t setVal(uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Sets the 16-bit value at a given group/id/size location
|
||||
uint8_t setVal8(uint32_t keyID, uint8_t value, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Sets the 8-bit value at a given group/id/size location
|
||||
uint8_t setVal16(uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Sets the 16-bit value at a given group/id/size location
|
||||
uint8_t setVal32(uint32_t keyID, uint32_t value, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Sets the 32-bit value at a given group/id/size location
|
||||
uint8_t newCfgValset8(uint32_t keyID, uint8_t value, uint8_t layer = VAL_LAYER_BBR); //Define a new UBX-CFG-VALSET with the given KeyID and 8-bit value
|
||||
uint8_t newCfgValset16(uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_BBR); //Define a new UBX-CFG-VALSET with the given KeyID and 16-bit value
|
||||
uint8_t newCfgValset32(uint32_t keyID, uint32_t value, uint8_t layer = VAL_LAYER_BBR); //Define a new UBX-CFG-VALSET with the given KeyID and 32-bit value
|
||||
uint8_t addCfgValset8(uint32_t keyID, uint8_t value); //Add a new KeyID and 8-bit value to an existing UBX-CFG-VALSET ubxPacket
|
||||
uint8_t addCfgValset16(uint32_t keyID, uint16_t value); //Add a new KeyID and 16-bit value to an existing UBX-CFG-VALSET ubxPacket
|
||||
uint8_t addCfgValset32(uint32_t keyID, uint32_t value); //Add a new KeyID and 32-bit value to an existing UBX-CFG-VALSET ubxPacket
|
||||
uint8_t sendCfgValset8(uint32_t keyID, uint8_t value, uint16_t maxWait = 250); //Add the final KeyID and 8-bit value to an existing UBX-CFG-VALSET ubxPacket and send it
|
||||
uint8_t sendCfgValset16(uint32_t keyID, uint16_t value, uint16_t maxWait = 250); //Add the final KeyID and 16-bit value to an existing UBX-CFG-VALSET ubxPacket and send it
|
||||
uint8_t sendCfgValset32(uint32_t keyID, uint32_t value, uint16_t maxWait = 250); //Add the final KeyID and 32-bit value to an existing UBX-CFG-VALSET ubxPacket and send it
|
||||
|
||||
//Functions used for RTK and base station setup
|
||||
//It is probably safe to assume that users of the RTK will be using I2C / Qwiic. So let's leave maxWait set to 250ms.
|
||||
boolean getSurveyMode(uint16_t maxWait = 250); //Get the current TimeMode3 settings
|
||||
boolean setSurveyMode(uint8_t mode, uint16_t observationTime, float requiredAccuracy, uint16_t maxWait = 250); //Control survey in mode
|
||||
boolean enableSurveyMode(uint16_t observationTime, float requiredAccuracy, uint16_t maxWait = 250); //Begin Survey-In for NEO-M8P
|
||||
boolean disableSurveyMode(uint16_t maxWait = 250); //Stop Survey-In mode
|
||||
|
||||
boolean getSurveyStatus(uint16_t maxWait); //Reads survey in status and sets the global variables
|
||||
|
||||
uint32_t getPositionAccuracy(uint16_t maxWait = 1100); //Returns the 3D accuracy of the current high-precision fix, in mm. Supported on NEO-M8P, ZED-F9P,
|
||||
|
||||
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 getRELPOSNED(uint16_t maxWait = 1100); //Get Relative Positioning Information of the NED frame
|
||||
|
||||
void enableDebugging(Stream &debugPort = Serial, boolean printLimitedDebug = false); //Given a port to print to, enable debug messages. Default to all, not limited.
|
||||
void disableDebugging(void); //Turn off debug statements
|
||||
void debugPrint(char *message); //Safely print debug statements
|
||||
void debugPrintln(char *message); //Safely print debug statements
|
||||
const char *statusString(sfe_ublox_status_e stat); //Pretty print the return value
|
||||
|
||||
//Support for geofences
|
||||
boolean addGeofence(int32_t latitude, int32_t longitude, uint32_t radius, byte confidence = 0, byte pinPolarity = 0, byte pin = 0, uint16_t maxWait = 1100); // Add a new geofence
|
||||
boolean clearGeofences(uint16_t maxWait = 1100); //Clears all geofences
|
||||
boolean getGeofenceState(geofenceState ¤tGeofenceState, uint16_t maxWait = 1100); //Returns the combined geofence state
|
||||
boolean clearAntPIO(uint16_t maxWait = 1100); //Clears the antenna control pin settings to release the PIOs
|
||||
geofenceParams currentGeofenceParams; // Global to store the geofence parameters
|
||||
|
||||
boolean powerSaveMode(bool power_save = true, uint16_t maxWait = 1100);
|
||||
uint8_t getPowerSaveMode(uint16_t maxWait = 1100); // Returns 255 if the sendCommand fails
|
||||
|
||||
//Change the dynamic platform model using UBX-CFG-NAV5
|
||||
boolean setDynamicModel(dynModel newDynamicModel = DYN_MODEL_PORTABLE, uint16_t maxWait = 1100);
|
||||
uint8_t getDynamicModel(uint16_t maxWait = 1100); // Get the dynamic model - returns 255 if the sendCommand fails
|
||||
|
||||
boolean getEsfInfo(uint16_t maxWait = 1100);
|
||||
boolean getEsfIns(uint16_t maxWait = 1100);
|
||||
boolean getEsfDataInfo(uint16_t maxWait = 1100);
|
||||
boolean getEsfRawDataInfo(uint16_t maxWait = 1100);
|
||||
sfe_ublox_status_e getSensState(uint8_t sensor, uint16_t maxWait = 1100);
|
||||
boolean getVehAtt(uint16_t maxWait = 1100);
|
||||
|
||||
//Survey-in specific controls
|
||||
struct svinStructure
|
||||
{
|
||||
boolean active;
|
||||
boolean valid;
|
||||
uint16_t observationTime;
|
||||
float meanAccuracy;
|
||||
} svin;
|
||||
|
||||
//Relative Positioning Info in NED frame specific controls
|
||||
struct frelPosInfoStructure
|
||||
{
|
||||
uint16_t refStationID;
|
||||
|
||||
float relPosN;
|
||||
float relPosE;
|
||||
float relPosD;
|
||||
|
||||
long relPosLength;
|
||||
long relPosHeading;
|
||||
|
||||
int8_t relPosHPN;
|
||||
int8_t relPosHPE;
|
||||
int8_t relPosHPD;
|
||||
int8_t relPosHPLength;
|
||||
|
||||
float accN;
|
||||
float accE;
|
||||
float accD;
|
||||
|
||||
bool gnssFixOk;
|
||||
bool diffSoln;
|
||||
bool relPosValid;
|
||||
uint8_t carrSoln;
|
||||
bool isMoving;
|
||||
bool refPosMiss;
|
||||
bool refObsMiss;
|
||||
} relPosInfo;
|
||||
|
||||
//The major datums we want to globally store
|
||||
uint16_t gpsYear;
|
||||
uint8_t gpsMonth;
|
||||
uint8_t gpsDay;
|
||||
uint8_t gpsHour;
|
||||
uint8_t gpsMinute;
|
||||
uint8_t gpsSecond;
|
||||
uint16_t gpsMillisecond;
|
||||
int32_t gpsNanosecond;
|
||||
|
||||
int32_t latitude; //Degrees * 10^-7 (more accurate than floats)
|
||||
int32_t longitude; //Degrees * 10^-7 (more accurate than floats)
|
||||
int32_t altitude; //Number of mm above ellipsoid
|
||||
int32_t altitudeMSL; //Number of mm above Mean Sea Level
|
||||
uint8_t SIV; //Number of satellites used in position solution
|
||||
uint8_t fixType; //Tells us when we have a solution aka lock
|
||||
uint8_t carrierSolution; //Tells us when we have an RTK float/fixed solution
|
||||
int32_t groundSpeed; //mm/s
|
||||
int32_t headingOfMotion; //degrees * 10^-5
|
||||
uint16_t pDOP; //Positional dilution of precision * 10^-2 (dimensionless)
|
||||
uint8_t versionLow; //Loaded from getProtocolVersion().
|
||||
uint8_t versionHigh;
|
||||
|
||||
uint32_t timeOfWeek; // ms
|
||||
int32_t highResLatitude; // Degrees * 10^-7
|
||||
int32_t highResLongitude; // Degrees * 10^-7
|
||||
int32_t elipsoid; // Height above ellipsoid in mm (Typo! Should be eLLipsoid! **Uncorrected for backward-compatibility.**)
|
||||
int32_t meanSeaLevel; // Height above mean sea level in mm
|
||||
int32_t geoidSeparation; // This seems to only be provided in NMEA GGA and GNS messages
|
||||
uint32_t horizontalAccuracy; // mm * 10^-1 (i.e. 0.1mm)
|
||||
uint32_t verticalAccuracy; // mm * 10^-1 (i.e. 0.1mm)
|
||||
int8_t elipsoidHp; // High precision component of the height above ellipsoid in mm * 10^-1 (Deliberate typo! Should be eLLipsoidHp!)
|
||||
int8_t meanSeaLevelHp; // High precision component of Height above mean sea level in mm * 10^-1
|
||||
int8_t highResLatitudeHp; // High precision component of latitude: Degrees * 10^-9
|
||||
int8_t highResLongitudeHp; // High precision component of longitude: Degrees * 10^-9
|
||||
|
||||
uint16_t rtcmFrameCounter = 0; //Tracks the type of incoming byte inside RTCM frame
|
||||
|
||||
#define DEF_NUM_SENS 7
|
||||
struct deadReckData
|
||||
{
|
||||
uint8_t version;
|
||||
uint8_t fusionMode;
|
||||
|
||||
uint8_t xAngRateVald;
|
||||
uint8_t yAngRateVald;
|
||||
uint8_t zAngRateVald;
|
||||
uint8_t xAccelVald;
|
||||
uint8_t yAccelVald;
|
||||
uint8_t zAccelVald;
|
||||
|
||||
int32_t xAngRate;
|
||||
int32_t yAngRate;
|
||||
int32_t zAngRate;
|
||||
|
||||
int32_t xAccel;
|
||||
int32_t yAccel;
|
||||
int32_t zAccel;
|
||||
|
||||
// The array size is based on testing directly on M8U and F9R
|
||||
uint32_t rawData;
|
||||
uint32_t rawDataType;
|
||||
uint32_t rawTStamp;
|
||||
|
||||
uint32_t data[DEF_NUM_SENS];
|
||||
uint32_t dataType[DEF_NUM_SENS];
|
||||
uint32_t dataTStamp[DEF_NUM_SENS];
|
||||
} imuMeas;
|
||||
|
||||
struct indivImuData
|
||||
{
|
||||
|
||||
uint8_t numSens;
|
||||
|
||||
uint8_t senType;
|
||||
boolean isUsed;
|
||||
boolean isReady;
|
||||
uint8_t calibStatus;
|
||||
uint8_t timeStatus;
|
||||
|
||||
uint8_t freq; // Hz
|
||||
|
||||
boolean badMeas;
|
||||
boolean badTag;
|
||||
boolean missMeas;
|
||||
boolean noisyMeas;
|
||||
} ubloxSen;
|
||||
|
||||
struct vehicleAttitude
|
||||
{
|
||||
// All values in degrees
|
||||
int32_t roll;
|
||||
int32_t pitch;
|
||||
int32_t heading;
|
||||
uint32_t accRoll;
|
||||
uint32_t accPitch;
|
||||
uint32_t accHeading;
|
||||
} vehAtt;
|
||||
|
||||
private:
|
||||
//Depending on the sentence type the processor will load characters into different arrays
|
||||
enum SentenceTypes
|
||||
{
|
||||
NONE = 0,
|
||||
NMEA,
|
||||
UBX,
|
||||
RTCM
|
||||
} currentSentence = NONE;
|
||||
|
||||
//Depending on the ubx binary response class, store binary responses into different places
|
||||
enum classTypes
|
||||
{
|
||||
CLASS_NONE = 0,
|
||||
CLASS_ACK,
|
||||
CLASS_NOT_AN_ACK
|
||||
} ubxFrameClass = CLASS_NONE;
|
||||
|
||||
enum commTypes
|
||||
{
|
||||
COMM_TYPE_I2C = 0,
|
||||
COMM_TYPE_SERIAL,
|
||||
COMM_TYPE_SPI
|
||||
} commType = COMM_TYPE_I2C; //Controls which port we look to for incoming bytes
|
||||
|
||||
//Functions
|
||||
boolean checkUbloxInternal(ubxPacket *incomingUBX, uint8_t requestedClass = 255, uint8_t requestedID = 255); //Checks module with user selected commType
|
||||
uint32_t extractLong(uint8_t spotToStart); //Combine four bytes from payload into long
|
||||
uint16_t extractInt(uint8_t spotToStart); //Combine two bytes from payload into int
|
||||
uint8_t extractByte(uint8_t spotToStart); //Get byte from payload
|
||||
int8_t extractSignedChar(uint8_t spotToStart); //Get signed 8-bit value from payload
|
||||
void addToChecksum(uint8_t incoming); //Given an incoming byte, adjust rollingChecksumA/B
|
||||
|
||||
//Variables
|
||||
TwoWire *_i2cPort; //The generic connection to user's chosen I2C hardware
|
||||
Stream *_serialPort; //The generic connection to user's chosen Serial hardware
|
||||
Stream *_nmeaOutputPort = NULL; //The user can assign an output port to print NMEA sentences if they wish
|
||||
Stream *_debugSerial; //The stream to send debug messages to if enabled
|
||||
|
||||
uint8_t _gpsI2Caddress = 0x42; //Default 7-bit unshifted address of the ublox 6/7/8/M8/F9 series
|
||||
//This can be changed using the ublox configuration software
|
||||
|
||||
boolean _printDebug = false; //Flag to print the serial commands we are sending to the Serial port for debug
|
||||
boolean _printLimitedDebug = false; //Flag to print limited debug messages. Useful for I2C debugging or high navigation rates
|
||||
|
||||
//The packet buffers
|
||||
//These are pointed at from within the ubxPacket
|
||||
uint8_t payloadAck[2]; // Holds the requested ACK/NACK
|
||||
uint8_t payloadCfg[MAX_PAYLOAD_SIZE]; // Holds the requested data packet
|
||||
uint8_t payloadBuf[2]; // Temporary buffer used to screen incoming packets or dump unrequested packets
|
||||
|
||||
//Init the packet structures and init them with pointers to the payloadAck, payloadCfg and payloadBuf arrays
|
||||
ubxPacket packetAck = {0, 0, 0, 0, 0, payloadAck, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
|
||||
ubxPacket packetCfg = {0, 0, 0, 0, 0, payloadCfg, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
|
||||
ubxPacket packetBuf = {0, 0, 0, 0, 0, payloadBuf, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
|
||||
|
||||
//Flag if this packet is unrequested (and so should be ignored and not copied into packetCfg or packetAck)
|
||||
boolean ignoreThisPayload = false;
|
||||
|
||||
//Identify which buffer is in use
|
||||
//Data is stored in packetBuf until the requested class and ID can be validated
|
||||
//If a match is seen, data is diverted into packetAck or packetCfg
|
||||
sfe_ublox_packet_buffer_e activePacketBuffer = SFE_UBLOX_PACKET_PACKETBUF;
|
||||
|
||||
//Limit checking of new data to every X ms
|
||||
//If we are expecting an update every X Hz then we should check every half that amount of time
|
||||
//Otherwise we may block ourselves from seeing new data
|
||||
uint8_t i2cPollingWait = 100; //Default to 100ms. Adjusted when user calls setNavigationFrequency()
|
||||
|
||||
unsigned long lastCheck = 0;
|
||||
boolean autoPVT = false; //Whether autoPVT is enabled or not
|
||||
boolean autoPVTImplicitUpdate = true; // Whether autoPVT is triggered by accessing stale data (=true) or by a call to checkUblox (=false)
|
||||
uint16_t ubxFrameCounter; //It counts all UBX frame. [Fixed header(2bytes), CLS(1byte), ID(1byte), length(2bytes), payload(x bytes), checksums(2bytes)]
|
||||
|
||||
uint8_t rollingChecksumA; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes
|
||||
uint8_t rollingChecksumB; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes
|
||||
|
||||
//Create bit field for staleness of each datum in PVT we want to monitor
|
||||
//moduleQueried.latitude goes true each time we call getPVT()
|
||||
//This reduces the number of times we have to call getPVT as this can take up to ~1s per read
|
||||
//depending on update rate
|
||||
struct
|
||||
{
|
||||
uint32_t gpsiTOW : 1;
|
||||
uint32_t gpsYear : 1;
|
||||
uint32_t gpsMonth : 1;
|
||||
uint32_t gpsDay : 1;
|
||||
uint32_t gpsHour : 1;
|
||||
uint32_t gpsMinute : 1;
|
||||
uint32_t gpsSecond : 1;
|
||||
uint32_t gpsNanosecond : 1;
|
||||
|
||||
uint32_t all : 1;
|
||||
uint32_t longitude : 1;
|
||||
uint32_t latitude : 1;
|
||||
uint32_t altitude : 1;
|
||||
uint32_t altitudeMSL : 1;
|
||||
uint32_t SIV : 1;
|
||||
uint32_t fixType : 1;
|
||||
uint32_t carrierSolution : 1;
|
||||
uint32_t groundSpeed : 1;
|
||||
uint32_t headingOfMotion : 1;
|
||||
uint32_t pDOP : 1;
|
||||
uint32_t versionNumber : 1;
|
||||
} moduleQueried;
|
||||
|
||||
struct
|
||||
{
|
||||
uint16_t all : 1;
|
||||
uint16_t timeOfWeek : 1;
|
||||
uint16_t highResLatitude : 1;
|
||||
uint16_t highResLongitude : 1;
|
||||
uint16_t elipsoid : 1;
|
||||
uint16_t meanSeaLevel : 1;
|
||||
uint16_t geoidSeparation : 1; // Redundant but kept for backward-compatibility
|
||||
uint16_t horizontalAccuracy : 1;
|
||||
uint16_t verticalAccuracy : 1;
|
||||
uint16_t elipsoidHp : 1;
|
||||
uint16_t meanSeaLevelHp : 1;
|
||||
uint16_t highResLatitudeHp : 1;
|
||||
uint16_t highResLongitudeHp : 1;
|
||||
} highResModuleQueried;
|
||||
|
||||
uint16_t rtcmLen = 0;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,154 @@
|
||||
/*
|
||||
Get the high precision geodetic solution for latitude and longitude
|
||||
By: Nathan Seidle
|
||||
Modified by: Steven Rowland and Paul Clark
|
||||
SparkFun Electronics
|
||||
Date: April 17th, 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 inspect the accuracy of the high-precision
|
||||
positional solution. Please see below for information about the units.
|
||||
|
||||
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
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(Serial);
|
||||
|
||||
if (myGPS.begin(Wire) == 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.setNavigationFrequency(20); //Set output to 20 times a second
|
||||
|
||||
byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
|
||||
Serial.print("Current update rate: ");
|
||||
Serial.println(rate);
|
||||
|
||||
//myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
// getHighResLatitude: returns the latitude from HPPOSLLH as an int32_t in degrees * 10^-7
|
||||
// getHighResLatitudeHp: returns the high resolution component of latitude from HPPOSLLH as an int8_t in degrees * 10^-9
|
||||
// getHighResLongitude: returns the longitude from HPPOSLLH as an int32_t in degrees * 10^-7
|
||||
// getHighResLongitudeHp: returns the high resolution component of longitude from HPPOSLLH as an int8_t in degrees * 10^-9
|
||||
// getElipsoid: returns the height above ellipsoid as an int32_t in mm
|
||||
// getElipsoidHp: returns the high resolution component of the height above ellipsoid as an int8_t in mm * 10^-1
|
||||
// getMeanSeaLevel: returns the height above mean sea level as an int32_t in mm
|
||||
// getMeanSeaLevelHp: returns the high resolution component of the height above mean sea level as an int8_t in mm * 10^-1
|
||||
// getHorizontalAccuracy: returns the horizontal accuracy estimate from HPPOSLLH as an uint32_t in mm * 10^-1
|
||||
|
||||
// If you want to use the high precision latitude and longitude with the full 9 decimal places
|
||||
// you will need to use a 64-bit double - which is not supported on all platforms
|
||||
|
||||
// To allow this example to run on standard platforms, we cheat by converting lat and lon to integer and fractional degrees
|
||||
|
||||
// The high resolution altitudes can be converted into standard 32-bit float
|
||||
|
||||
// First, let's collect the position data
|
||||
int32_t latitude = myGPS.getHighResLatitude();
|
||||
int8_t latitudeHp = myGPS.getHighResLatitudeHp();
|
||||
int32_t longitude = myGPS.getHighResLongitude();
|
||||
int8_t longitudeHp = myGPS.getHighResLongitudeHp();
|
||||
int32_t ellipsoid = myGPS.getElipsoid();
|
||||
int8_t ellipsoidHp = myGPS.getElipsoidHp();
|
||||
int32_t msl = myGPS.getMeanSeaLevel();
|
||||
int8_t mslHp = myGPS.getMeanSeaLevelHp();
|
||||
uint32_t accuracy = myGPS.getHorizontalAccuracy();
|
||||
|
||||
// Defines storage for the lat and lon units integer and fractional parts
|
||||
int32_t lat_int; // Integer part of the latitude in degrees
|
||||
int32_t lat_frac; // Fractional part of the latitude
|
||||
int32_t lon_int; // Integer part of the longitude in degrees
|
||||
int32_t lon_frac; // Fractional part of the longitude
|
||||
|
||||
// Calculate the latitude and longitude integer and fractional parts
|
||||
lat_int = latitude / 10000000; // Convert latitude from degrees * 10^-7 to Degrees
|
||||
lat_frac = latitude - (lat_int * 10000000); // Calculate the fractional part of the latitude
|
||||
lat_frac = (lat_frac * 100) + latitudeHp; // Now add the high resolution component
|
||||
if (lat_frac < 0) // If the fractional part is negative, remove the minus sign
|
||||
{
|
||||
lat_frac = 0 - lat_frac;
|
||||
}
|
||||
lon_int = longitude / 10000000; // Convert latitude from degrees * 10^-7 to Degrees
|
||||
lon_frac = longitude - (lon_int * 10000000); // Calculate the fractional part of the longitude
|
||||
lon_frac = (lon_frac * 100) + longitudeHp; // Now add the high resolution component
|
||||
if (lon_frac < 0) // If the fractional part is negative, remove the minus sign
|
||||
{
|
||||
lon_frac = 0 - lon_frac;
|
||||
}
|
||||
|
||||
// Print the lat and lon
|
||||
Serial.print("Lat (deg): ");
|
||||
Serial.print(lat_int); // Print the integer part of the latitude
|
||||
Serial.print(".");
|
||||
Serial.print(lat_frac); // Print the fractional part of the latitude
|
||||
Serial.print(", Lon (deg): ");
|
||||
Serial.print(lon_int); // Print the integer part of the latitude
|
||||
Serial.print(".");
|
||||
Serial.println(lon_frac); // Print the fractional part of the latitude
|
||||
|
||||
// Now define float storage for the heights and accuracy
|
||||
float f_ellipsoid;
|
||||
float f_msl;
|
||||
float f_accuracy;
|
||||
|
||||
// Calculate the height above ellipsoid in mm * 10^-1
|
||||
f_ellipsoid = (ellipsoid * 10) + ellipsoidHp;
|
||||
// Now convert to m
|
||||
f_ellipsoid = f_ellipsoid / 10000.0; // Convert from mm * 10^-1 to m
|
||||
|
||||
// Calculate the height above mean sea level in mm * 10^-1
|
||||
f_msl = (msl * 10) + mslHp;
|
||||
// Now convert to m
|
||||
f_msl = f_msl / 10000.0; // Convert from mm * 10^-1 to m
|
||||
|
||||
// Convert the horizontal accuracy (mm * 10^-1) to a float
|
||||
f_accuracy = accuracy;
|
||||
// Now convert to m
|
||||
f_accuracy = f_accuracy / 10000.0; // Convert from mm * 10^-1 to m
|
||||
|
||||
// Finally, do the printing
|
||||
Serial.print("Ellipsoid (m): ");
|
||||
Serial.print(f_ellipsoid, 4); // Print the ellipsoid with 4 decimal places
|
||||
|
||||
Serial.print(", Mean Sea Level(m): ");
|
||||
Serial.print(f_msl, 4); // Print the mean sea level with 4 decimal places
|
||||
|
||||
Serial.print(", Accuracy (m): ");
|
||||
Serial.println(f_accuracy, 4); // Print the accuracy with 4 decimal places
|
||||
}
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
/*
|
||||
Get the high precision geodetic solution for latitude and longitude using double
|
||||
By: Nathan Seidle
|
||||
Modified by: Paul Clark (PaulZC)
|
||||
SparkFun Electronics
|
||||
Date: April 17th, 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 inspect the accuracy of the high-precision
|
||||
positional solution. Please see below for information about the units.
|
||||
|
||||
** This example will only work correctly on platforms which support 64-bit double **
|
||||
|
||||
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
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and (e.g.) a Redboard Artemis https://www.sparkfun.com/products/15444
|
||||
or an Artemis Thing Plus https://www.sparkfun.com/products/15574
|
||||
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 GPS
|
||||
|
||||
#define myWire Wire // This will work on the Redboard Artemis and the Artemis Thing Plus using Qwiic
|
||||
//#define myWire Wire1 // Uncomment this line if you are using the extra SCL1/SDA1 pins (D17 and D16) on the Thing Plus
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
|
||||
myWire.begin();
|
||||
|
||||
//myGPS.enableDebugging(Serial); // Uncomment this line to enable debug messages
|
||||
|
||||
if (myGPS.begin(myWire) == 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)
|
||||
;
|
||||
}
|
||||
|
||||
// Check that this platform supports 64-bit (8 byte) double
|
||||
if (sizeof(double) < 8)
|
||||
{
|
||||
Serial.println(F("Warning! Your platform does not support 64-bit double."));
|
||||
Serial.println(F("The latitude and longitude will be inaccurate."));
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
|
||||
//myGPS.setNavigationFrequency(20); //Set output to 20 times a second
|
||||
|
||||
byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
|
||||
Serial.print("Current update rate: ");
|
||||
Serial.println(rate);
|
||||
|
||||
//myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second.
|
||||
//The module only responds when a new position is available.
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
// getHighResLatitude: returns the latitude from HPPOSLLH as an int32_t in degrees * 10^-7
|
||||
// getHighResLatitudeHp: returns the high resolution component of latitude from HPPOSLLH as an int8_t in degrees * 10^-9
|
||||
// getHighResLongitude: returns the longitude from HPPOSLLH as an int32_t in degrees * 10^-7
|
||||
// getHighResLongitudeHp: returns the high resolution component of longitude from HPPOSLLH as an int8_t in degrees * 10^-9
|
||||
// getElipsoid: returns the height above ellipsoid as an int32_t in mm
|
||||
// getElipsoidHp: returns the high resolution component of the height above ellipsoid as an int8_t in mm * 10^-1
|
||||
// getMeanSeaLevel: returns the height above mean sea level as an int32_t in mm
|
||||
// getMeanSeaLevelHp: returns the high resolution component of the height above mean sea level as an int8_t in mm * 10^-1
|
||||
// getHorizontalAccuracy: returns the horizontal accuracy estimate from HPPOSLLH as an uint32_t in mm * 10^-1
|
||||
|
||||
// First, let's collect the position data
|
||||
int32_t latitude = myGPS.getHighResLatitude();
|
||||
int8_t latitudeHp = myGPS.getHighResLatitudeHp();
|
||||
int32_t longitude = myGPS.getHighResLongitude();
|
||||
int8_t longitudeHp = myGPS.getHighResLongitudeHp();
|
||||
int32_t ellipsoid = myGPS.getElipsoid();
|
||||
int8_t ellipsoidHp = myGPS.getElipsoidHp();
|
||||
int32_t msl = myGPS.getMeanSeaLevel();
|
||||
int8_t mslHp = myGPS.getMeanSeaLevelHp();
|
||||
uint32_t accuracy = myGPS.getHorizontalAccuracy();
|
||||
|
||||
// Defines storage for the lat and lon as double
|
||||
double d_lat; // latitude
|
||||
double d_lon; // longitude
|
||||
|
||||
// Assemble the high precision latitude and longitude
|
||||
d_lat = ((double)latitude) / 10000000.0; // Convert latitude from degrees * 10^-7 to degrees
|
||||
d_lat += ((double)latitudeHp) / 1000000000.0; // Now add the high resolution component (degrees * 10^-9 )
|
||||
d_lon = ((double)longitude) / 10000000.0; // Convert longitude from degrees * 10^-7 to degrees
|
||||
d_lon += ((double)longitudeHp) / 1000000000.0; // Now add the high resolution component (degrees * 10^-9 )
|
||||
|
||||
// Print the lat and lon
|
||||
Serial.print("Lat (deg): ");
|
||||
Serial.print(d_lat, 9);
|
||||
Serial.print(", Lon (deg): ");
|
||||
Serial.print(d_lon, 9);
|
||||
|
||||
// Now define float storage for the heights and accuracy
|
||||
float f_ellipsoid;
|
||||
float f_msl;
|
||||
float f_accuracy;
|
||||
|
||||
// Calculate the height above ellipsoid in mm * 10^-1
|
||||
f_ellipsoid = (ellipsoid * 10) + ellipsoidHp;
|
||||
// Now convert to m
|
||||
f_ellipsoid = f_ellipsoid / 10000.0; // Convert from mm * 10^-1 to m
|
||||
|
||||
// Calculate the height above mean sea level in mm * 10^-1
|
||||
f_msl = (msl * 10) + mslHp;
|
||||
// Now convert to m
|
||||
f_msl = f_msl / 10000.0; // Convert from mm * 10^-1 to m
|
||||
|
||||
// Convert the horizontal accuracy (mm * 10^-1) to a float
|
||||
f_accuracy = accuracy;
|
||||
// Now convert to m
|
||||
f_accuracy = f_accuracy / 10000.0; // Convert from mm * 10^-1 to m
|
||||
|
||||
// Finally, do the printing
|
||||
Serial.print(", Ellipsoid (m): ");
|
||||
Serial.print(f_ellipsoid, 4); // Print the ellipsoid with 4 decimal places
|
||||
|
||||
Serial.print(", Mean Sea Level (m): ");
|
||||
Serial.print(f_msl, 4); // Print the mean sea level with 4 decimal places
|
||||
|
||||
Serial.print(", Accuracy (m): ");
|
||||
Serial.println(f_accuracy, 4); // Print the accuracy with 4 decimal places
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
Set the static position of the receiver.
|
||||
By: SparkFun Electronics / Nathan Seidle
|
||||
Date: September 26th, 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 set the static position of a receiver
|
||||
using an Earth-Centered, Earth-Fixed (ECEF) location. This is the
|
||||
output from a long (24 hour+) survey-in. Setting the static position
|
||||
immediately causes the receiver to begin outputting RTCM data (if
|
||||
enabled), perfect for setting up your own RTCM NTRIP caster or CORS.
|
||||
|
||||
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
|
||||
|
||||
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 <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(F("SparkFun u-blox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the u-blox module using Wire port
|
||||
{
|
||||
Serial.println(F("u-blox 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)
|
||||
|
||||
//-1280208.308,-4716803.847,4086665.811 is SparkFun HQ so...
|
||||
|
||||
//Units are cm so 1234 = 12.34m
|
||||
//myGPS.setStaticPosition(-128020831, -471680385, 408666581);
|
||||
|
||||
//Units are cm with a high precision extension so -1234.5678 should be called: (-123456, -78)
|
||||
myGPS.setStaticPosition(-128020830, -80, -471680384, -70, 408666581, 10); //With high precision 0.1mm parts
|
||||
|
||||
//We can also set via lat/long
|
||||
//40.09029751,-105.18507900,1560.238
|
||||
//myGPS.setStaticPosition(400902975, -1051850790, 156024, true); //True at end enables lat/long input
|
||||
//myGPS.setStaticPosition(400902975, 10, -1051850790, 0, 156023, 80, true);
|
||||
|
||||
//Now let's use getVals to read back the data
|
||||
//long ecefX = myGPS.getVal32(0x40030003);
|
||||
//Serial.print("ecefX: ");
|
||||
//Serial.println(ecefX);
|
||||
|
||||
Serial.println(F("Done!"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
Configuring the GPS to automatically send HPPOSLLH position reports over I2C
|
||||
By: Paul Clark
|
||||
Date: October 27th 2020
|
||||
|
||||
Based on an earlier example:
|
||||
By: Nathan Seidle and Thorsten von Eicken
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the U-Blox GPS the send navigation reports automatically
|
||||
and retrieving the latest one via getHPPOSLLH. This eliminates the blocking in getHPPOSLLH while the GPS
|
||||
produces a fresh navigation solution at the expense of returning a slighly old solution.
|
||||
|
||||
This can be used over serial or over I2C, this example shows the I2C use. With serial the GPS
|
||||
simply outputs the UBX_NAV_HPPOSLLH packet. With I2C it queues it into its internal I2C buffer (4KB in
|
||||
size?) where it can be retrieved in the next I2C poll.
|
||||
|
||||
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
|
||||
|
||||
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 <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);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // Uncomment this line to enable lots of helpful debug messages
|
||||
//myGPS.enableDebugging(Serial, true); // Uncomment this line to enable the minimum of helpful 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);
|
||||
}
|
||||
|
||||
// Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
|
||||
//myGPS.factoryDefault(); delay(5000);
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save the communications port settings to flash and BBR
|
||||
|
||||
myGPS.setNavigationFrequency(1); //Produce one solution per second
|
||||
|
||||
|
||||
// The acid test: all four of these combinations should work seamlessly :-)
|
||||
|
||||
//myGPS.setAutoPVT(false); // Library will poll each reading
|
||||
//myGPS.setAutoHPPOSLLH(false); // Library will poll each reading
|
||||
|
||||
//myGPS.setAutoPVT(true); // Tell the GPS to "send" each solution automatically
|
||||
//myGPS.setAutoHPPOSLLH(false); // Library will poll each reading
|
||||
|
||||
//myGPS.setAutoPVT(false); // Library will poll each reading
|
||||
//myGPS.setAutoHPPOSLLH(true); // Tell the GPS to "send" each hi res solution automatically
|
||||
|
||||
myGPS.setAutoPVT(true); // Tell the GPS to "send" each solution automatically
|
||||
myGPS.setAutoHPPOSLLH(true); // Tell the GPS to "send" each hi res solution automatically
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Calling getHPPOSLLH returns true if there actually is a fresh navigation solution available.
|
||||
// Calling getPVT returns true if there actually is a fresh navigation solution available.
|
||||
if ((myGPS.getHPPOSLLH()) || (myGPS.getPVT()))
|
||||
{
|
||||
Serial.println();
|
||||
|
||||
long highResLatitude = myGPS.getHighResLatitude();
|
||||
Serial.print(F("Hi Res Lat: "));
|
||||
Serial.print(highResLatitude);
|
||||
|
||||
int highResLatitudeHp = myGPS.getHighResLatitudeHp();
|
||||
Serial.print(F(" "));
|
||||
Serial.print(highResLatitudeHp);
|
||||
|
||||
long highResLongitude = myGPS.getHighResLongitude();
|
||||
Serial.print(F(" Hi Res Long: "));
|
||||
Serial.print(highResLongitude);
|
||||
|
||||
int highResLongitudeHp = myGPS.getHighResLongitudeHp();
|
||||
Serial.print(F(" "));
|
||||
Serial.print(highResLongitudeHp);
|
||||
|
||||
unsigned long horizAccuracy = myGPS.getHorizontalAccuracy();
|
||||
Serial.print(F(" Horiz accuracy: "));
|
||||
Serial.print(horizAccuracy);
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F(" Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.println(longitude);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(".");
|
||||
delay(50);
|
||||
}
|
||||
}
|
@ -0,0 +1,274 @@
|
||||
/*
|
||||
Use ESP32 WiFi to push RTCM data to RTK2Go (caster) as a Server
|
||||
By: SparkFun Electronics / Nathan Seidle
|
||||
Date: December 14th, 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 gather RTCM data over I2C and push it to a casting service over WiFi.
|
||||
It's confusing, but the Arduino is acting as a 'server' to a 'caster'. In this case we will
|
||||
use RTK2Go.com as our caster because it is free. A rover (car, surveyor stick, etc) can
|
||||
then connect to RTK2Go as a 'client' and get the RTCM data it needs.
|
||||
|
||||
You will need to register your mountpoint here: http://www.rtk2go.com/new-reservation/
|
||||
(They'll probably block the credentials we include in this example)
|
||||
|
||||
To see if your mountpoint is active go here: http://rtk2go.com:2101/
|
||||
|
||||
This is a proof of concept. Serving RTCM to a caster over WiFi is useful when you need to
|
||||
set up a high-precision base station.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/16481
|
||||
RTK Surveyor: https://www.sparkfun.com/products/17369
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS 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 <WiFi.h>
|
||||
#include "secrets.h"
|
||||
WiFiClient client;
|
||||
|
||||
#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;
|
||||
|
||||
//Basic Connection settings to RTK2Go NTRIP Caster - See secrets for mount specific credentials
|
||||
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
const uint16_t casterPort = 2101;
|
||||
const char * casterHost = "rtk2go.com";
|
||||
const char * ntrip_server_name = "SparkFun_RTK_Surveyor";
|
||||
|
||||
long lastSentRTCM_ms = 0; //Time of last data pushed to socket
|
||||
int maxTimeBeforeHangup_ms = 10000; //If we fail to get a complete RTCM frame after 10s, then disconnect from caster
|
||||
|
||||
uint32_t serverBytesSent = 0; //Just a running total
|
||||
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
long lastReport_ms = 0; //Time of last report of bytes sent
|
||||
|
||||
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(F("SparkFun u-blox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the u-blox module using Wire port
|
||||
{
|
||||
Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to local WiFi");
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
|
||||
Serial.print("\nWiFi connected with IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_RTCM3); //UBX+RTCM3 is not a valid option so we enable all three.
|
||||
|
||||
myGPS.setNavigationFrequency(1); //Set output in Hz. RTCM rarely benefits from >1Hz.
|
||||
|
||||
//Disable all NMEA sentences
|
||||
bool response = true;
|
||||
response &= myGPS.disableNMEAMessage(UBX_NMEA_GGA, COM_PORT_I2C);
|
||||
response &= myGPS.disableNMEAMessage(UBX_NMEA_GSA, COM_PORT_I2C);
|
||||
response &= myGPS.disableNMEAMessage(UBX_NMEA_GSV, COM_PORT_I2C);
|
||||
response &= myGPS.disableNMEAMessage(UBX_NMEA_RMC, COM_PORT_I2C);
|
||||
response &= myGPS.disableNMEAMessage(UBX_NMEA_GST, COM_PORT_I2C);
|
||||
response &= myGPS.disableNMEAMessage(UBX_NMEA_GLL, COM_PORT_I2C);
|
||||
response &= myGPS.disableNMEAMessage(UBX_NMEA_VTG, COM_PORT_I2C);
|
||||
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println(F("Failed to disable NMEA. Freezing..."));
|
||||
while (1);
|
||||
}
|
||||
else
|
||||
Serial.println(F("NMEA disabled"));
|
||||
|
||||
//Enable necessary RTCM sentences
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_I2C, 1); //Enable message 1005 to output through UART2, message every second
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1074, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1084, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1094, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1124, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_I2C, 10); //Enable message every 10 seconds
|
||||
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println(F("Failed to enable RTCM. Freezing..."));
|
||||
while (1);
|
||||
}
|
||||
else
|
||||
Serial.println(F("RTCM sentences enabled"));
|
||||
|
||||
//-1280208.308,-4716803.847,4086665.811 is SparkFun HQ so...
|
||||
//Units are cm with a high precision extension so -1234.5678 should be called: (-123456, -78)
|
||||
//For more infomation see Example12_setStaticPosition
|
||||
//Note: If you leave these coordinates in place and setup your antenna *not* at SparkFun, your receiver
|
||||
//will be very confused and fail to generate correction data because, well, you aren't at SparkFun...
|
||||
//See this tutorial on getting PPP coordinates: https://learn.sparkfun.com/tutorials/how-to-build-a-diy-gnss-reference-station/all
|
||||
response &= myGPS.setStaticPosition(-128020830, -80, -471680384, -70, 408666581, 10); //With high precision 0.1mm parts
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println(F("Failed to enter static position. Freezing..."));
|
||||
while (1);
|
||||
}
|
||||
else
|
||||
Serial.println(F("Static position set"));
|
||||
|
||||
//You could instead do a survey-in but it takes much longer to start generating RTCM data. See Example4_BaseWithLCD
|
||||
//myGPS.enableSurveyMode(60, 5.000); //Enable Survey in, 60 seconds, 5.0m
|
||||
|
||||
if (myGPS.saveConfiguration() == false) //Save the current settings to flash and BBR
|
||||
Serial.println(F("Module failed to save."));
|
||||
|
||||
Serial.println(F("Module configuration complete"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (Serial.available()) beginServing();
|
||||
|
||||
Serial.println(F("Press any key to start serving."));
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void beginServing()
|
||||
{
|
||||
Serial.println("Xmit to RTK2Go. Press any 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 (client.connected() == false)
|
||||
{
|
||||
Serial.printf("Opening socket to %s\n", casterHost);
|
||||
|
||||
if (client.connect(casterHost, casterPort) == true) //Attempt connection
|
||||
{
|
||||
Serial.printf("Connected to %s:%d\n", casterHost, casterPort);
|
||||
|
||||
const int SERVER_BUFFER_SIZE = 512;
|
||||
char serverBuffer[SERVER_BUFFER_SIZE];
|
||||
|
||||
snprintf(serverBuffer, SERVER_BUFFER_SIZE, "SOURCE %s /%s\r\nSource-Agent: NTRIP %s/%s\r\n\r\n",
|
||||
mntpnt_pw, mntpnt, ntrip_server_name, "App Version 1.0");
|
||||
|
||||
Serial.printf("Sending credentials:\n%s\n", serverBuffer);
|
||||
client.write(serverBuffer, strlen(serverBuffer));
|
||||
|
||||
//Wait for response
|
||||
unsigned long timeout = millis();
|
||||
while (client.available() == 0)
|
||||
{
|
||||
if (millis() - timeout > 5000)
|
||||
{
|
||||
Serial.println(">>> Client Timeout !");
|
||||
client.stop();
|
||||
return;
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
|
||||
//Check reply
|
||||
bool connectionSuccess = false;
|
||||
char response[512];
|
||||
int responseSpot = 0;
|
||||
while (client.available())
|
||||
{
|
||||
response[responseSpot++] = client.read();
|
||||
if (strstr(response, "200") > 0) //Look for 'ICY 200 OK'
|
||||
connectionSuccess = true;
|
||||
if (responseSpot == 512 - 1) break;
|
||||
}
|
||||
response[responseSpot] = '\0';
|
||||
|
||||
if (connectionSuccess == false)
|
||||
{
|
||||
Serial.printf("Failed to connect to RTK2Go: %s", response);
|
||||
}
|
||||
} //End attempt to connect
|
||||
else
|
||||
{
|
||||
Serial.println("Connection to host failed");
|
||||
}
|
||||
} //End connected == false
|
||||
|
||||
if (client.connected() == true)
|
||||
{
|
||||
delay(10);
|
||||
while (Serial.available()) Serial.read(); //Flush any endlines or carriage returns
|
||||
|
||||
lastReport_ms = millis();
|
||||
lastSentRTCM_ms = millis();
|
||||
|
||||
//This is the main sending loop. We scan for new ublox data but processRTCM() is where the data actually gets sent out.
|
||||
while (1)
|
||||
{
|
||||
if (Serial.available()) break;
|
||||
|
||||
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
|
||||
|
||||
//Close socket if we don't have new data for 10s
|
||||
//RTK2Go will ban your IP address if you abuse it. See http://www.rtk2go.com/how-to-get-your-ip-banned/
|
||||
//So let's not leave the socket open/hanging without data
|
||||
if (millis() - lastSentRTCM_ms > maxTimeBeforeHangup_ms)
|
||||
{
|
||||
Serial.println("RTCM timeout. Disconnecting...");
|
||||
client.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
delay(10);
|
||||
|
||||
//Report some statistics every 250
|
||||
if (millis() - lastReport_ms > 250)
|
||||
{
|
||||
lastReport_ms += 250;
|
||||
Serial.printf("Total sent: %d\n", serverBytesSent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
||||
Serial.println("User pressed a key");
|
||||
Serial.println("Disconnecting...");
|
||||
client.stop();
|
||||
|
||||
delay(10);
|
||||
while (Serial.available()) Serial.read(); //Flush any endlines or carriage returns
|
||||
}
|
||||
|
||||
//This function gets called from the SparkFun u-blox Arduino Library.
|
||||
//As each RTCM byte comes in you can specify what to do with it
|
||||
//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
|
||||
void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
|
||||
{
|
||||
if (client.connected() == true)
|
||||
{
|
||||
client.write(incoming); //Send this byte to socket
|
||||
serverBytesSent++;
|
||||
lastSentRTCM_ms = millis();
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
//Your WiFi credentials
|
||||
const char* ssid = "TRex";
|
||||
const char* password = "hasBigTeeth";
|
||||
|
||||
//Your RTK2GO mount point credentials
|
||||
const char* mntpnt_pw = "WR5wRo4H";
|
||||
const char* mntpnt = "bldr_dwntwn2";
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
Get the high position accuracy of the RTK enhanced position
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to inspect the accuracy of the high-precision
|
||||
positional solution.
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
long accuracy = myGPS.getPositionAccuracy();
|
||||
Serial.print(F(" 3D Positional Accuracy: "));
|
||||
Serial.print(accuracy);
|
||||
Serial.println(F("mm"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Configuring Ublox Module using new VALGET / VALSET / VALDEL methods
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
Ublox depricated many -CFG messages and replaced them with new
|
||||
VALGET, VALSET, VALDEL methods. This shows the basics of how to use
|
||||
these methods.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
byte response;
|
||||
response = myGPS.getVal8(VAL_GROUP_I2C, VAL_ID_I2C_ADDRESS, VAL_GROUP_I2C_SIZE, VAL_LAYER_RAM);
|
||||
Serial.print(F("I2C Address: 0x"));
|
||||
Serial.println(response >> 1, HEX); //We have to shift by 1 to get the common '7-bit' I2C address format
|
||||
|
||||
response = myGPS.getVal8(VAL_GROUP_I2COUTPROT, VAL_ID_I2COUTPROT_NMEA, VAL_GROUP_I2COUTPROT_SIZE, VAL_LAYER_RAM);
|
||||
Serial.print(F("Output NMEA over I2C port: 0x"));
|
||||
Serial.print(response, HEX);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
/*
|
||||
Send UBX binary commands to enable RTCM sentences on Ublox ZED-F9P module
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 9th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example does all steps to configure and enable a ZED-F9P as a base station:
|
||||
Begin Survey-In
|
||||
Once we've achieved 2m accuracy and 300s have passed, survey is complete
|
||||
Enable six RTCM messages
|
||||
Begin outputting RTCM bytes
|
||||
|
||||
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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
//#define USE_SERIAL1 // Uncomment this line to push the RTCM data to Serial1
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("Ublox Base station example");
|
||||
|
||||
#ifdef USE_SERIAL1
|
||||
// If our board supports it, we can output the RTCM data on Serial1
|
||||
Serial1.begin(115200);
|
||||
#endif
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
|
||||
//myGPS.factoryDefault(); delay(5000);
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save the communications port settings to flash and BBR
|
||||
|
||||
while (Serial.available()) Serial.read(); //Clear any latent chars in serial buffer
|
||||
Serial.println("Press any key to send commands to begin Survey-In");
|
||||
while (Serial.available() == 0) ; //Wait for user to press a key
|
||||
|
||||
boolean response = true;
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_I2C, 1); //Enable message 1005 to output through I2C port, message every second
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1074, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1084, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1094, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1124, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_I2C, 10); //Enable message every 10 seconds
|
||||
|
||||
//Use COM_PORT_UART1 for the above six messages to direct RTCM messages out UART1
|
||||
//COM_PORT_UART2, COM_PORT_USB, COM_PORT_SPI are also available
|
||||
//For example: response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_UART1, 10);
|
||||
|
||||
if (response == true)
|
||||
{
|
||||
Serial.println("RTCM messages enabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("RTCM failed to enable. Are you sure you have an ZED-F9P?");
|
||||
while (1); //Freeze
|
||||
}
|
||||
|
||||
//Check if Survey is in Progress before initiating one
|
||||
response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (request can take a long time)
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println("Failed to get Survey In status");
|
||||
while (1); //Freeze
|
||||
}
|
||||
|
||||
if (myGPS.svin.active == true)
|
||||
{
|
||||
Serial.print("Survey already in progress.");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Start survey
|
||||
//The ZED-F9P is slightly different than the NEO-M8P. See the Integration manual 3.5.8 for more info.
|
||||
//response = myGPS.enableSurveyMode(300, 2.000); //Enable Survey in on NEO-M8P, 300 seconds, 2.0m
|
||||
response = myGPS.enableSurveyMode(60, 5.000); //Enable Survey in, 60 seconds, 5.0m
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println("Survey start failed");
|
||||
while (1);
|
||||
}
|
||||
Serial.println("Survey started. This will run until 60s has passed and less than 5m accuracy is achieved.");
|
||||
}
|
||||
|
||||
while(Serial.available()) Serial.read(); //Clear buffer
|
||||
|
||||
//Begin waiting for survey to complete
|
||||
while (myGPS.svin.valid == false)
|
||||
{
|
||||
if(Serial.available())
|
||||
{
|
||||
byte incoming = Serial.read();
|
||||
if(incoming == 'x')
|
||||
{
|
||||
//Stop survey mode
|
||||
response = myGPS.disableSurveyMode(); //Disable survey
|
||||
Serial.println("Survey stopped");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (req can take a long time)
|
||||
if (response == true)
|
||||
{
|
||||
Serial.print("Press x to end survey - ");
|
||||
Serial.print("Time elapsed: ");
|
||||
Serial.print((String)myGPS.svin.observationTime);
|
||||
|
||||
Serial.print(" Accuracy: ");
|
||||
Serial.print((String)myGPS.svin.meanAccuracy);
|
||||
Serial.println();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("SVIN request failed");
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
Serial.println("Survey valid!");
|
||||
|
||||
Serial.println("Base survey complete! RTCM now broadcasting.");
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX | COM_TYPE_RTCM3); //Set the I2C port to output UBX and RTCM sentences (not really an option, turns on NMEA as well)
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
|
||||
|
||||
delay(250); //Don't pound too hard on the I2C bus
|
||||
}
|
||||
|
||||
//This function gets called from the SparkFun Ublox Arduino Library.
|
||||
//As each RTCM byte comes in you can specify what to do with it
|
||||
//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
|
||||
void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
|
||||
{
|
||||
#ifdef USE_SERIAL1
|
||||
//Push the RTCM data to Serial1
|
||||
Serial1.write(incoming);
|
||||
#endif
|
||||
|
||||
//Pretty-print the HEX values to Serial
|
||||
if (myGPS.rtcmFrameCounter % 16 == 0) Serial.println();
|
||||
Serial.print(" ");
|
||||
if (incoming < 0x10) Serial.print("0");
|
||||
Serial.print(incoming, HEX);
|
||||
}
|
@ -0,0 +1,200 @@
|
||||
/*
|
||||
Send UBX binary commands to enable RTCM sentences on Ublox ZED-F9P module
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 9th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example does all steps to configure and enable a ZED-F9P as a base station:
|
||||
Begin Survey-In
|
||||
Once we've achieved 2m accuracy and 300s have passed, survey is complete
|
||||
Enable six RTCM messages
|
||||
Begin outputting RTCM bytes
|
||||
|
||||
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
|
||||
Plug a SerLCD onto the Qwiic bus
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Watch the output on the LCD or open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#define STAT_LED 13
|
||||
|
||||
#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;
|
||||
|
||||
#include <SerLCD.h> //http://librarymanager/All#SparkFun_SerLCD
|
||||
SerLCD lcd; // Initialize the library with default I2C address 0x72
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("Ublox GPS I2C Test");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
pinMode(STAT_LED, OUTPUT);
|
||||
digitalWrite(STAT_LED, LOW);
|
||||
|
||||
lcd.begin(Wire); //Set up the LCD for Serial communication at 9600bps
|
||||
lcd.setBacklight(0x4B0082); //indigo, a kind of dark purplish blue
|
||||
lcd.clear();
|
||||
lcd.print(F("LCD Ready"));
|
||||
|
||||
myGPS.begin(Wire);
|
||||
if (myGPS.isConnected() == false)
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("No GPS detected"));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
|
||||
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("GPS Detected");
|
||||
|
||||
//myGPS.setI2COutput(COM_TYPE_RTCM3); //Set the I2C port to output RTCM3 sentences (turn off NMEA noise)
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX sentences (turn off NMEA noise)
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
|
||||
boolean response = true;
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_I2C, 1); //Enable message 1005 to output through I2C port, message every second
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1074, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1084, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1094, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1124, COM_PORT_I2C, 1);
|
||||
response &= myGPS.enableRTCMmessage(UBX_RTCM_1230, COM_PORT_I2C, 10); //Enable message every 10 seconds
|
||||
if (response == true)
|
||||
{
|
||||
Serial.println(F("RTCM messages enabled"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("RTCM failed to enable. Are you sure you have an ZED-F9P? Freezing."));
|
||||
while (1)
|
||||
; //Freeze
|
||||
}
|
||||
|
||||
//Check if Survey is in Progress before initiating one
|
||||
response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (request can take a long time)
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println(F("Failed to get Survey In status. Freezing."));
|
||||
while (1)
|
||||
; //Freeze
|
||||
}
|
||||
|
||||
if (myGPS.svin.active == true)
|
||||
{
|
||||
Serial.print(F("Survey already in progress."));
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("Survey already going"));
|
||||
}
|
||||
else
|
||||
{
|
||||
//Start survey
|
||||
response = myGPS.enableSurveyMode(60, 5.000); //Enable Survey in, 60 seconds, 5.0m
|
||||
if (response == false)
|
||||
{
|
||||
Serial.println(F("Survey start failed"));
|
||||
lcd.setCursor(0, 3);
|
||||
lcd.print(F("Survey start failed. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
Serial.println(F("Survey started. This will run until 60s has passed and less than 5m accuracy is achieved."));
|
||||
}
|
||||
|
||||
while (Serial.available())
|
||||
Serial.read(); //Clear buffer
|
||||
|
||||
lcd.clear();
|
||||
lcd.print(F("Survey in progress"));
|
||||
|
||||
//Begin waiting for survey to complete
|
||||
while (myGPS.svin.valid == false)
|
||||
{
|
||||
if (Serial.available())
|
||||
{
|
||||
byte incoming = Serial.read();
|
||||
if (incoming == 'x')
|
||||
{
|
||||
//Stop survey mode
|
||||
response = myGPS.disableSurveyMode(); //Disable survey
|
||||
Serial.println(F("Survey stopped"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
response = myGPS.getSurveyStatus(2000); //Query module for SVIN status with 2000ms timeout (req can take a long time)
|
||||
if (response == true)
|
||||
{
|
||||
Serial.print(F("Press x to end survey - "));
|
||||
Serial.print(F("Time elapsed: "));
|
||||
Serial.print((String)myGPS.svin.observationTime);
|
||||
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("Elapsed: "));
|
||||
lcd.print((String)myGPS.svin.observationTime);
|
||||
|
||||
Serial.print(F(" Accuracy: "));
|
||||
Serial.print((String)myGPS.svin.meanAccuracy);
|
||||
Serial.println();
|
||||
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("Accuracy: "));
|
||||
lcd.print((String)myGPS.svin.meanAccuracy);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("SVIN request failed"));
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
Serial.println(F("Survey valid!"));
|
||||
|
||||
Serial.println(F("Base survey complete! RTCM now broadcasting."));
|
||||
lcd.clear();
|
||||
lcd.print(F("Transmitting RTCM"));
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX | COM_TYPE_RTCM3); //Set the I2C port to output UBX and RTCM sentences (not really an option, turns on NMEA as well)
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
|
||||
|
||||
//Do anything you want. Call checkUblox() every second. ZED-F9P has TX buffer of 4k bytes.
|
||||
|
||||
delay(250); //Don't pound too hard on the I2C bus
|
||||
}
|
||||
|
||||
//This function gets called from the SparkFun Ublox Arduino Library.
|
||||
//As each RTCM byte comes in you can specify what to do with it
|
||||
//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
|
||||
void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
|
||||
{
|
||||
//Let's just pretty-print the HEX values for now
|
||||
if (myGPS.rtcmFrameCounter % 16 == 0)
|
||||
Serial.println();
|
||||
Serial.print(" ");
|
||||
if (incoming < 0x10)
|
||||
Serial.print("0");
|
||||
Serial.print(incoming, HEX);
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
/*
|
||||
Send UBX binary commands to enable RTCM sentences on Ublox ZED-F9P module
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 9th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query the module for RELPOS information in the NED frame.
|
||||
It assumes you already have RTCM correction data being fed to the receiver.
|
||||
|
||||
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 RedBoard Qwiic or 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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
//#define USE_SERIAL1 // Uncomment this line to push the RTCM data from Serial1 to the module via I2C
|
||||
|
||||
size_t numBytes = 0; // Record the number os bytes received from Serial1
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("Ublox Base station example");
|
||||
|
||||
#ifdef USE_SERIAL1
|
||||
// If our board supports it, we can receive the RTCM data on Serial1
|
||||
Serial1.begin(115200);
|
||||
#endif
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
|
||||
//myGPS.factoryDefault(); delay(5000);
|
||||
|
||||
#ifdef USE_SERIAL1
|
||||
Serial.print(F("Enabling UBX and RTCM input on I2C. Result: "));
|
||||
Serial.print(myGPS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_RTCM3)); //Enable UBX and RTCM input on I2C
|
||||
myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save the communications port settings to flash and BBR
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (myGPS.getRELPOSNED() == true)
|
||||
{
|
||||
Serial.print("relPosN: ");
|
||||
Serial.println(myGPS.relPosInfo.relPosN, 4);
|
||||
Serial.print("relPosE: ");
|
||||
Serial.println(myGPS.relPosInfo.relPosE, 4);
|
||||
Serial.print("relPosD: ");
|
||||
Serial.println(myGPS.relPosInfo.relPosD, 4);
|
||||
|
||||
Serial.print("relPosLength: ");
|
||||
Serial.println(myGPS.relPosInfo.relPosLength);
|
||||
Serial.print("relPosHeading: ");
|
||||
Serial.println(myGPS.relPosInfo.relPosHeading);
|
||||
|
||||
Serial.print("relPosHPN: ");
|
||||
Serial.println(myGPS.relPosInfo.relPosHPN);
|
||||
Serial.print("relPosHPE: ");
|
||||
Serial.println(myGPS.relPosInfo.relPosHPE);
|
||||
Serial.print("relPosHPD: ");
|
||||
Serial.println(myGPS.relPosInfo.relPosHPD);
|
||||
Serial.print("relPosHPLength: ");
|
||||
Serial.println(myGPS.relPosInfo.relPosHPLength);
|
||||
|
||||
Serial.print("accN: ");
|
||||
Serial.println(myGPS.relPosInfo.accN, 4);
|
||||
Serial.print("accE: ");
|
||||
Serial.println(myGPS.relPosInfo.accE, 4);
|
||||
Serial.print("accD: ");
|
||||
Serial.println(myGPS.relPosInfo.accD, 4);
|
||||
|
||||
Serial.print("gnssFixOk: ");
|
||||
if (myGPS.relPosInfo.gnssFixOk == true)
|
||||
Serial.println("x");
|
||||
else
|
||||
Serial.println("");
|
||||
|
||||
Serial.print("diffSolution: ");
|
||||
if (myGPS.relPosInfo.diffSoln == true)
|
||||
Serial.println("x");
|
||||
else
|
||||
Serial.println("");
|
||||
|
||||
Serial.print("relPosValid: ");
|
||||
if (myGPS.relPosInfo.relPosValid == true)
|
||||
Serial.println("x");
|
||||
else
|
||||
Serial.println("");
|
||||
|
||||
Serial.print("carrier Solution Type: ");
|
||||
if (myGPS.relPosInfo.carrSoln == 0)
|
||||
Serial.println("None");
|
||||
else if (myGPS.relPosInfo.carrSoln == 1)
|
||||
Serial.println("Float");
|
||||
else if (myGPS.relPosInfo.carrSoln == 2)
|
||||
Serial.println("Fixed");
|
||||
|
||||
Serial.print("isMoving: ");
|
||||
if (myGPS.relPosInfo.isMoving == true)
|
||||
Serial.println("x");
|
||||
else
|
||||
Serial.println("");
|
||||
|
||||
Serial.print("refPosMiss: ");
|
||||
if (myGPS.relPosInfo.refPosMiss == true)
|
||||
Serial.println("x");
|
||||
else
|
||||
Serial.println("");
|
||||
|
||||
Serial.print("refObsMiss: ");
|
||||
if (myGPS.relPosInfo.refObsMiss == true)
|
||||
Serial.println("x");
|
||||
else
|
||||
Serial.println("");
|
||||
}
|
||||
else
|
||||
Serial.println("RELPOS request failed");
|
||||
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
#ifdef USE_SERIAL1
|
||||
uint8_t store[256];
|
||||
while ((Serial1.available()) && (numBytes < 256)) // Check if data has been received
|
||||
{
|
||||
store[numBytes++] = Serial1.read(); // Read a byte from Serial1 and store it
|
||||
}
|
||||
if (numBytes > 0) // Check if data was received
|
||||
{
|
||||
//Serial.print("Pushing ");
|
||||
//Serial.print(numBytes);
|
||||
//Serial.println(" bytes via I2C");
|
||||
myGPS.pushRawData(((uint8_t *)&store), numBytes); // Push the RTCM data via I2C
|
||||
numBytes = 0; // Reset numBytes
|
||||
}
|
||||
#endif
|
||||
delay(10);
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
Get a device's I2C address using advanced getVal method
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 9th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
u-blox changed how to configure their modules in 2019. As of version 23 of the UBX protocol the
|
||||
UBX-CFG commands are deprecated; they still work, they just recommend using VALSET, VALGET, and VALDEL
|
||||
commands instead. This example shows how to use this new command structure.
|
||||
|
||||
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 RedBoard Qwiic or 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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("u-blox getVal example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
|
||||
|
||||
if (myGPS.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)
|
||||
;
|
||||
}
|
||||
|
||||
myGPS.enableDebugging(); //Enable debug messages over Serial (default)
|
||||
//myGPS.enableDebugging(SerialUSB); //Enable debug messages over Serial USB
|
||||
|
||||
uint8_t currentI2Caddress = myGPS.getVal8(UBLOX_CFG_I2C_ADDRESS);
|
||||
Serial.print("Current I2C address (should be 0x42): 0x");
|
||||
Serial.println(currentI2Caddress >> 1, HEX); //Ublox module returns a shifted 8-bit address. Make it 7-bit unshifted.
|
||||
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
Send UBX binary commands to enable RTCM sentences on u-blox ZED-F9P module
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 9th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
u-blox changed how to configure their modules in 2019. As of version 23 of the UBX protocol the
|
||||
UBX-CFG commands are deprecated; they still work, they just recommend using VALSET, VALGET, and VALDEL
|
||||
commands instead. This example shows how to use this new command structure.
|
||||
|
||||
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 RedBoard Qwiic or 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 <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to u-blox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("u-blox getVal example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the u-blox module using Wire port
|
||||
{
|
||||
Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
myGPS.enableDebugging(); //Enable debug messages over Serial (default)
|
||||
//myGPS.enableDebugging(SerialUSB); //Enable debug messages over Serial USB
|
||||
|
||||
bool setValueSuccess;
|
||||
|
||||
//These key values are hard coded and defined in u-blox_config_keys.h.
|
||||
//You can obtain them from the ZED-F9P interface description doc
|
||||
//or from u-center's Messages->CFG->VALSET window. Keys must be 32-bit.
|
||||
//setValueSuccess = myGPS.setVal(UBLOX_CFG_NMEA_HIGHPREC, 0); //Enable high precision NMEA
|
||||
setValueSuccess = myGPS.setVal(UBLOX_CFG_RATE_MEAS, 100); //Set measurement rate to 100ms (10Hz update rate)
|
||||
//setValueSuccess = myGPS.setVal(UBLOX_CFG_RATE_MEAS, 1000); //Set measurement rate to 1000ms (1Hz update rate)
|
||||
|
||||
//Below is the original way we enabled the RTCM message on the I2C port. After that, we show how to do the same
|
||||
//but with setVal().
|
||||
//Original: myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_I2C, 1); //Enable message 1005 to output through I2C port, message every second
|
||||
//setValueSuccess = myGPS.setVal(0x209102bd, 1); //Set output rate of msg 1005 over the I2C port to once per second
|
||||
|
||||
if (setValueSuccess == true)
|
||||
{
|
||||
Serial.println("Value was successfully set");
|
||||
}
|
||||
else
|
||||
Serial.println("Value set failed");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
Configuring port settings using the newer getVal/setVal methods
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: October 23rd, 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 query a u-blox module for its UART1 settings and
|
||||
then change them if the settings aren't what we want.
|
||||
|
||||
Note: getVal/setVal/delVal are only support in u-blox protocol versions 27 and higher.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS 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 GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun u-blox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the u-blox module using Wire port
|
||||
{
|
||||
Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
bool response = true;
|
||||
|
||||
//Read the settings from RAM (what the module is running right now, not BBR, Flash, or default)
|
||||
uint8_t currentUART1Setting_ubx = myGPS.getVal8(UBLOX_CFG_UART1INPROT_UBX);
|
||||
uint8_t currentUART1Setting_nmea = myGPS.getVal8(UBLOX_CFG_UART1INPROT_NMEA);
|
||||
uint8_t currentUART1Setting_rtcm3 = myGPS.getVal8(UBLOX_CFG_UART1INPROT_RTCM3X);
|
||||
|
||||
Serial.print("currentUART1Setting_ubx: ");
|
||||
Serial.println(currentUART1Setting_ubx);
|
||||
Serial.print("currentUART1Setting_nmea: ");
|
||||
Serial.println(currentUART1Setting_nmea);
|
||||
Serial.print("currentUART1Setting_rtcm3: ");
|
||||
Serial.println(currentUART1Setting_rtcm3);
|
||||
|
||||
//Check if NMEA and RTCM are enabled for UART1
|
||||
if (currentUART1Setting_ubx == 0 || currentUART1Setting_nmea == 0)
|
||||
{
|
||||
Serial.println("Updating UART1 configuration");
|
||||
|
||||
//setVal sets the values for RAM, BBR, and Flash automatically so no .saveConfiguration() is needed
|
||||
response &= myGPS.setVal8(UBLOX_CFG_UART1INPROT_UBX, 1); //Enable UBX on UART1 Input
|
||||
response &= myGPS.setVal8(UBLOX_CFG_UART1INPROT_NMEA, 1); //Enable NMEA on UART1 Input
|
||||
response &= myGPS.setVal8(UBLOX_CFG_UART1INPROT_RTCM3X, 0); //Disable RTCM on UART1 Input
|
||||
|
||||
if (response == false)
|
||||
Serial.println("SetVal failed");
|
||||
else
|
||||
Serial.println("SetVal succeeded");
|
||||
}
|
||||
else
|
||||
Serial.println("No port change needed");
|
||||
|
||||
//Change speed of UART2
|
||||
uint32_t currentUART2Baud = myGPS.getVal32(UBLOX_CFG_UART2_BAUDRATE);
|
||||
Serial.print("currentUART2Baud: ");
|
||||
Serial.println(currentUART2Baud);
|
||||
|
||||
if (currentUART2Baud != 57600)
|
||||
{
|
||||
response &= myGPS.setVal32(UBLOX_CFG_UART2_BAUDRATE, 57600);
|
||||
if (response == false)
|
||||
Serial.println("SetVal failed");
|
||||
else
|
||||
Serial.println("SetVal succeeded");
|
||||
}
|
||||
else
|
||||
Serial.println("No baud change needed");
|
||||
|
||||
Serial.println("Done");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
Send UBX binary commands to enable RTCM sentences on u-blox ZED-F9P module
|
||||
Based on Example7 By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Updated by Paul Clark to demonstrate setVal8/16/32, newCfgValset8/16/32, addCfgValset8/16/32 and sendCfgValset8/16/32
|
||||
Date: July 1st, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
u-blox changed how to configure their modules in 2019. As of version 23 of the UBX protocol the
|
||||
UBX-CFG commands are deprecated; they still work, they just recommend using VALSET, VALGET, and VALDEL
|
||||
commands instead. This example shows how to use this new command structure.
|
||||
|
||||
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 RedBoard Qwiic or 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 <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);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("u-blox multi setVal example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the u-blox module using Wire port
|
||||
{
|
||||
Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
myGPS.enableDebugging(); //Enable debug messages over Serial (default)
|
||||
//myGPS.enableDebugging(SerialUSB); //Enable debug messages over Serial USB
|
||||
|
||||
bool setValueSuccess = true;
|
||||
|
||||
//These key values are hard coded. You can obtain them from the ZED-F9P interface description doc
|
||||
//or from u-center's Messages->CFG->VALSET window. Keys must be 32-bit.
|
||||
//Choose setVal8, setVal16 or setVal32 depending on the required value data width (1, 2 or 4 bytes)
|
||||
//L, U1, I1, E1 and X1 values are 8-bit
|
||||
//U2, I2, E2 and X2 values are 16-bit
|
||||
//U4, I4, R4, E4, X4 values are 32-bit
|
||||
|
||||
setValueSuccess &= myGPS.setVal8(UBLOX_CFG_NMEA_HIGHPREC, 0); //Enable high precision NMEA (value is 8-bit (L / U1))
|
||||
//setValueSuccess &= myGPS.setVal16(UBLOX_CFG_RATE_MEAS, 200); //Set measurement rate to 100ms (10Hz update rate) (value is 16-bit (U2))
|
||||
//setValueSuccess &= myGPS.setVal16(UBLOX_CFG_RATE_MEAS, 200, 1); //Set rate setting in RAM instead of BBR
|
||||
setValueSuccess &= myGPS.setVal16(UBLOX_CFG_RATE_MEAS, 1000); //Set measurement rate to 1000ms (1Hz update rate) (value is 16-bit (U2))
|
||||
|
||||
//Below is the original way we enabled a single RTCM message on the I2C port. After that, we show how to do the same
|
||||
//but with multiple messages all in one go using newCfgValset, addCfgValset and sendCfgValset.
|
||||
//Original: myGPS.enableRTCMmessage(UBX_RTCM_1005, COM_PORT_I2C, 1); //Enable message 1005 to output through I2C port, message every second
|
||||
|
||||
//Begin with newCfgValset8/16/32
|
||||
setValueSuccess &= myGPS.newCfgValset8(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_I2C, 1); //Set output rate of msg 1005 over the I2C port to once per measurement (value is 8-bit (U1))
|
||||
//setValueSuccess &= myGPS.newCfgValset8(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1005_I2C, 1, VAL_LAYER_RAM); //Set this and the following settings in RAM only instead of Flash/RAM/BBR
|
||||
//Add extra keyIDs and values using addCfgValset8/16/32
|
||||
setValueSuccess &= myGPS.addCfgValset8(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1077_I2C, 1); //Set output rate of msg 1077 over the I2C port to once per measurement (value is 8-bit (U1))
|
||||
setValueSuccess &= myGPS.addCfgValset8(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1087_I2C, 1); //Set output rate of msg 1087 over the I2C port to once per measurement (value is 8-bit (U1))
|
||||
setValueSuccess &= myGPS.addCfgValset8(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1127_I2C, 1); //Set output rate of msg 1127 over the I2C port to once per measurement (value is 8-bit (U1))
|
||||
setValueSuccess &= myGPS.addCfgValset8(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1097_I2C, 1); //Set output rate of msg 1097 over the I2C port to once per measurement (value is 8-bit (U1))
|
||||
// Add the final value and send the packet using sendCfgValset8/16/32
|
||||
setValueSuccess &= myGPS.sendCfgValset8(UBLOX_CFG_MSGOUT_RTCM_3X_TYPE1230_I2C, 10); //Set output rate of msg 1230 over the I2C port to once every 10 measurements (value is 8-bit (U1))
|
||||
|
||||
if (setValueSuccess == true)
|
||||
{
|
||||
Serial.println("Values were successfully set");
|
||||
}
|
||||
else
|
||||
Serial.println("Value set failed");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
|
||||
find_package(Zephyr HINTS $ENV{ZEPHYR_BASE})
|
||||
project(sparkfun_ublox_zephyr_library)
|
||||
|
||||
zephyr_compile_options(-fdiagnostics-color=always)
|
||||
|
||||
zephyr_include_directories(.)
|
||||
target_sources(app PRIVATE src/SparkFun_Ublox_Zephyr_Library.cpp)
|
||||
target_sources(app PRIVATE src/SparkFun_Ublox_Zephyr_Interface.cpp)
|
||||
|
||||
target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c)
|
@ -0,0 +1,4 @@
|
||||
&i2c0 {
|
||||
status = "okay";
|
||||
compatible = "nordic,nrf-twim";
|
||||
};
|
@ -0,0 +1,7 @@
|
||||
#turn on c++ support
|
||||
CONFIG_CPLUSPLUS=y
|
||||
|
||||
# turn on peripherals
|
||||
CONFIG_GPIO=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_0=y
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
This is an interface that connects the CPP Ublox library with the main C code.
|
||||
Added to make it possible to run Ublox lib on Zephyr (NCS)
|
||||
|
||||
This port was made by Vid Rajtmajer <vid@irnas.eu>, www.irnas.eu
|
||||
*/
|
||||
#include "SparkFun_Ublox_Zephyr_Interface.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "SparkFun_Ublox_Zephyr_Library.h"
|
||||
|
||||
|
||||
SFE_UBLOX_GPS myGPS; // driver class instance
|
||||
long lastTime = 0; // Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
// init GPIO checksumFailurePin and load GPIO device pointer to the driver
|
||||
uint8_t set_gpio_dev(struct device *gpio_dev, uint8_t enable_debug)
|
||||
{
|
||||
if (myGPS.init_gpio_pins(*gpio_dev) == false)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
// turn on debugging if enable_debug is set
|
||||
if (enable_debug)
|
||||
{
|
||||
myGPS.enableDebugging();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// initialize I2C and check if GPS device respons
|
||||
uint8_t gps_begin(struct device *i2c_dev)
|
||||
{
|
||||
if (myGPS.begin(*i2c_dev) == false)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This will pipe all NMEA sentences to UART so we can see them
|
||||
void pipe_nmea_sentences(void)
|
||||
{
|
||||
myGPS.setNMEAOutputPort();
|
||||
}
|
||||
|
||||
// Check for available bytes from the device
|
||||
void check_ublox(void)
|
||||
{
|
||||
myGPS.checkUblox();
|
||||
}
|
||||
|
||||
// Get position information when requested, also display number of satellites used in the fix
|
||||
int get_position(void)
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available, print it to console
|
||||
if (k_uptime_get_32() - lastTime > 1000)
|
||||
{
|
||||
lastTime = k_uptime_get_32(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
long longitude = myGPS.getLongitude();
|
||||
long altitude = myGPS.getAltitude();
|
||||
uint8_t SIV = myGPS.getSIV();
|
||||
|
||||
printk("Position: Lat: %ld, Lon: %ld, Alt: %ld, SIV: %d", latitude, longitude, altitude, SIV);
|
||||
return 0;
|
||||
}
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
// Get date and time information when requested, check if they are valid and print info to console, it returns UNIX time
|
||||
void get_datetime(void)
|
||||
{
|
||||
int year = myGPS.getYear();
|
||||
int month = myGPS.getMonth();
|
||||
int day = myGPS.getDay();
|
||||
int hour = myGPS.getHour();
|
||||
int minute = myGPS.getMinute();
|
||||
int second = myGPS.getSecond();
|
||||
|
||||
printk("DateTime: %d-%d-%d %d:%d:%d\n", year, month, day, hour, minute, second);
|
||||
|
||||
printk("Time is ");
|
||||
if (myGPS.getTimeValid() == false)
|
||||
{
|
||||
printk("not ");
|
||||
}
|
||||
printk("valid. Date is ");
|
||||
if (myGPS.getDateValid() == false)
|
||||
{
|
||||
printk("not ");
|
||||
}
|
||||
printk("valid.\n");
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
This is an interface that connects the CPP Ublox library with the main C code.
|
||||
Added to make it possible to run Ublox lib on Zephyr (NCS)
|
||||
|
||||
This port was made by Vid Rajtmajer <vid@irnas.eu>, www.irnas.eu
|
||||
*/
|
||||
#include <time.h>
|
||||
#include <zephyr.h>
|
||||
|
||||
#ifndef _UBLOX_LIB_INTERFACE_H_
|
||||
#define _UBLOX_LIB_INTERFACE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint8_t set_gpio_dev(struct device *gpio_dev, uint8_t enable_debug); // init GPIO
|
||||
uint8_t gps_begin(struct device *i2c_dev); // initialize I2C and check if GPS device respons
|
||||
void pipe_nmea_sentences(void); // print NMEA sentences
|
||||
|
||||
void check_ublox(void); // Check for available bytes from the device
|
||||
int get_position(void); // Get position information
|
||||
void get_datetime(void); // Get date and time information
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //UBLOX_LIB_INTERFACE_H_
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,901 @@
|
||||
/*
|
||||
This is a library written for the Ublox ZED-F9P and NEO-M8P-2
|
||||
SparkFun sells these at its website: www.sparkfun.com
|
||||
Do you like this library? Help support SparkFun. Buy a board!
|
||||
https://www.sparkfun.com/products/15136
|
||||
https://www.sparkfun.com/products/15005
|
||||
https://www.sparkfun.com/products/15733
|
||||
https://www.sparkfun.com/products/15193
|
||||
https://www.sparkfun.com/products/15210
|
||||
|
||||
Written by Nathan Seidle @ SparkFun Electronics, September 6th, 2018
|
||||
|
||||
This library handles configuring and handling the responses
|
||||
from a Ublox GPS module. Works with most modules from Ublox including
|
||||
the Zed-F9P, NEO-M8P-2, NEO-M9N, ZOE-M8Q, SAM-M8Q, and many others.
|
||||
|
||||
https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library
|
||||
|
||||
Development environment specifics:
|
||||
NCS v1.0.3 release
|
||||
|
||||
This port was made by Vid Rajtmajer <vid@irnas.eu>, IRNAS www.irnas.eu
|
||||
|
||||
SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT).
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2016 SparkFun Electronics
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to
|
||||
do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SPARKFUN_UBLOX_ZEPHYR_LIBRARY_H
|
||||
#define SPARKFUN_UBLOX_ZEPHYR_LIBRARY_H
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <drivers/i2c.h>
|
||||
|
||||
//The catch-all default is 32
|
||||
#define I2C_BUFFER_LENGTH 32
|
||||
|
||||
//Define pin states
|
||||
#define LOW 0
|
||||
#define HIGH 1
|
||||
|
||||
//Define a digital pin to aid checksum failure capture and analysis
|
||||
//Leave set to -1 if not needed
|
||||
const int checksumFailurePin = -1;
|
||||
|
||||
// Global Status Returns
|
||||
typedef enum
|
||||
{
|
||||
SFE_UBLOX_STATUS_SUCCESS,
|
||||
SFE_UBLOX_STATUS_FAIL,
|
||||
SFE_UBLOX_STATUS_CRC_FAIL,
|
||||
SFE_UBLOX_STATUS_TIMEOUT,
|
||||
SFE_UBLOX_STATUS_COMMAND_NACK, // Indicates that the command was unrecognised, invalid or that the module is too busy to respond
|
||||
SFE_UBLOX_STATUS_OUT_OF_RANGE,
|
||||
SFE_UBLOX_STATUS_INVALID_ARG,
|
||||
SFE_UBLOX_STATUS_INVALID_OPERATION,
|
||||
SFE_UBLOX_STATUS_MEM_ERR,
|
||||
SFE_UBLOX_STATUS_HW_ERR,
|
||||
SFE_UBLOX_STATUS_DATA_SENT, // This indicates that a 'set' was successful
|
||||
SFE_UBLOX_STATUS_DATA_RECEIVED, // This indicates that a 'get' (poll) was successful
|
||||
SFE_UBLOX_STATUS_I2C_COMM_FAILURE,
|
||||
SFE_UBLOX_STATUS_DATA_OVERWRITTEN // This is an error - the data was valid but has been or _is being_ overwritten by another packet
|
||||
} sfe_ublox_status_e;
|
||||
|
||||
// ubxPacket validity
|
||||
typedef enum
|
||||
{
|
||||
SFE_UBLOX_PACKET_VALIDITY_NOT_VALID,
|
||||
SFE_UBLOX_PACKET_VALIDITY_VALID,
|
||||
SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED,
|
||||
SFE_UBLOX_PACKET_NOTACKNOWLEDGED // This indicates that we received a NACK
|
||||
} sfe_ublox_packet_validity_e;
|
||||
|
||||
// Identify which packet buffer is in use:
|
||||
// packetCfg (or a custom packet), packetAck or packetBuf
|
||||
typedef enum
|
||||
{
|
||||
SFE_UBLOX_PACKET_PACKETCFG,
|
||||
SFE_UBLOX_PACKET_PACKETACK,
|
||||
SFE_UBLOX_PACKET_PACKETBUF
|
||||
} sfe_ublox_packet_buffer_e;
|
||||
|
||||
//Registers
|
||||
const uint8_t UBX_SYNCH_1 = 0xB5;
|
||||
const uint8_t UBX_SYNCH_2 = 0x62;
|
||||
|
||||
//The following are UBX Class IDs. Descriptions taken from ZED-F9P Interface Description Document page 32, NEO-M8P Interface Description page 145
|
||||
const uint8_t UBX_CLASS_NAV = 0x01; //Navigation Results Messages: Position, Speed, Time, Acceleration, Heading, DOP, SVs used
|
||||
const uint8_t UBX_CLASS_RXM = 0x02; //Receiver Manager Messages: Satellite Status, RTC Status
|
||||
const uint8_t UBX_CLASS_INF = 0x04; //Information Messages: Printf-Style Messages, with IDs such as Error, Warning, Notice
|
||||
const uint8_t UBX_CLASS_ACK = 0x05; //Ack/Nak Messages: Acknowledge or Reject messages to UBX-CFG input messages
|
||||
const uint8_t UBX_CLASS_CFG = 0x06; //Configuration Input Messages: Configure the receiver.
|
||||
const uint8_t UBX_CLASS_UPD = 0x09; //Firmware Update Messages: Memory/Flash erase/write, Reboot, Flash identification, etc.
|
||||
const uint8_t UBX_CLASS_MON = 0x0A; //Monitoring Messages: Communication Status, CPU Load, Stack Usage, Task Status
|
||||
const uint8_t UBX_CLASS_AID = 0x0B; //(NEO-M8P ONLY!!!) AssistNow Aiding Messages: Ephemeris, Almanac, other A-GPS data input
|
||||
const uint8_t UBX_CLASS_TIM = 0x0D; //Timing Messages: Time Pulse Output, Time Mark Results
|
||||
const uint8_t UBX_CLASS_ESF = 0x10; //(NEO-M8P ONLY!!!) External Sensor Fusion Messages: External Sensor Measurements and Status Information
|
||||
const uint8_t UBX_CLASS_MGA = 0x13; //Multiple GNSS Assistance Messages: Assistance data for various GNSS
|
||||
const uint8_t UBX_CLASS_LOG = 0x21; //Logging Messages: Log creation, deletion, info and retrieval
|
||||
const uint8_t UBX_CLASS_SEC = 0x27; //Security Feature Messages
|
||||
const uint8_t UBX_CLASS_HNR = 0x28; //(NEO-M8P ONLY!!!) High Rate Navigation Results Messages: High rate time, position speed, heading
|
||||
const uint8_t UBX_CLASS_NMEA = 0xF0; //NMEA Strings: standard NMEA strings
|
||||
|
||||
//The following are used for configuration. Descriptions are from the ZED-F9P Interface Description pg 33-34 and NEO-M9N Interface Description pg 47-48
|
||||
const uint8_t UBX_CFG_ANT = 0x13; //Antenna Control Settings. Used to configure the antenna control settings
|
||||
const uint8_t UBX_CFG_BATCH = 0x93; //Get/set data batching configuration.
|
||||
const uint8_t UBX_CFG_CFG = 0x09; //Clear, Save, and Load Configurations. Used to save current configuration
|
||||
const uint8_t UBX_CFG_DAT = 0x06; //Set User-defined Datum or The currently defined Datum
|
||||
const uint8_t UBX_CFG_DGNSS = 0x70; //DGNSS configuration
|
||||
const uint8_t UBX_CFG_GEOFENCE = 0x69; //Geofencing configuration. Used to configure a geofence
|
||||
const uint8_t UBX_CFG_GNSS = 0x3E; //GNSS system configuration
|
||||
const uint8_t UBX_CFG_INF = 0x02; //Depending on packet length, either: poll configuration for one protocol, or information message configuration
|
||||
const uint8_t UBX_CFG_ITFM = 0x39; //Jamming/Interference Monitor configuration
|
||||
const uint8_t UBX_CFG_LOGFILTER = 0x47; //Data Logger Configuration
|
||||
const uint8_t UBX_CFG_MSG = 0x01; //Poll a message configuration, or Set Message Rate(s), or Set Message Rate
|
||||
const uint8_t UBX_CFG_NAV5 = 0x24; //Navigation Engine Settings. Used to configure the navigation engine including the dynamic model.
|
||||
const uint8_t UBX_CFG_NAVX5 = 0x23; //Navigation Engine Expert Settings
|
||||
const uint8_t UBX_CFG_NMEA = 0x17; //Extended NMEA protocol configuration V1
|
||||
const uint8_t UBX_CFG_ODO = 0x1E; //Odometer, Low-speed COG Engine Settings
|
||||
const uint8_t UBX_CFG_PM2 = 0x3B; //Extended power management configuration
|
||||
const uint8_t UBX_CFG_PMS = 0x86; //Power mode setup
|
||||
const uint8_t UBX_CFG_PRT = 0x00; //Used to configure port specifics. Polls the configuration for one I/O Port, or Port configuration for UART ports, or Port configuration for USB port, or Port configuration for SPI port, or Port configuration for DDC port
|
||||
const uint8_t UBX_CFG_PWR = 0x57; //Put receiver in a defined power state
|
||||
const uint8_t UBX_CFG_RATE = 0x08; //Navigation/Measurement Rate Settings. Used to set port baud rates.
|
||||
const uint8_t UBX_CFG_RINV = 0x34; //Contents of Remote Inventory
|
||||
const uint8_t UBX_CFG_RST = 0x04; //Reset Receiver / Clear Backup Data Structures. Used to reset device.
|
||||
const uint8_t UBX_CFG_RXM = 0x11; //RXM configuration
|
||||
const uint8_t UBX_CFG_SBAS = 0x16; //SBAS configuration
|
||||
const uint8_t UBX_CFG_TMODE3 = 0x71; //Time Mode Settings 3. Used to enable Survey In Mode
|
||||
const uint8_t UBX_CFG_TP5 = 0x31; //Time Pulse Parameters
|
||||
const uint8_t UBX_CFG_USB = 0x1B; //USB Configuration
|
||||
const uint8_t UBX_CFG_VALDEL = 0x8C; //Used for config of higher version Ublox modules (ie protocol v27 and above). Deletes values corresponding to provided keys/ provided keys with a transaction
|
||||
const uint8_t UBX_CFG_VALGET = 0x8B; //Used for config of higher version Ublox modules (ie protocol v27 and above). Configuration Items
|
||||
const uint8_t UBX_CFG_VALSET = 0x8A; //Used for config of higher version Ublox modules (ie protocol v27 and above). Sets values corresponding to provided key-value pairs/ provided key-value pairs within a transaction.
|
||||
|
||||
//The following are used to enable NMEA messages. Descriptions come from the NMEA messages overview in the ZED-F9P Interface Description
|
||||
const uint8_t UBX_NMEA_MSB = 0xF0; //All NMEA enable commands have 0xF0 as MSB
|
||||
const uint8_t UBX_NMEA_DTM = 0x0A; //GxDTM (datum reference)
|
||||
const uint8_t UBX_NMEA_GAQ = 0x45; //GxGAQ (poll a standard message (if the current talker ID is GA))
|
||||
const uint8_t UBX_NMEA_GBQ = 0x44; //GxGBQ (poll a standard message (if the current Talker ID is GB))
|
||||
const uint8_t UBX_NMEA_GBS = 0x09; //GxGBS (GNSS satellite fault detection)
|
||||
const uint8_t UBX_NMEA_GGA = 0x00; //GxGGA (Global positioning system fix data)
|
||||
const uint8_t UBX_NMEA_GLL = 0x01; //GxGLL (latitude and long, whith time of position fix and status)
|
||||
const uint8_t UBX_NMEA_GLQ = 0x43; //GxGLQ (poll a standard message (if the current Talker ID is GL))
|
||||
const uint8_t UBX_NMEA_GNQ = 0x42; //GxGNQ (poll a standard message (if the current Talker ID is GN))
|
||||
const uint8_t UBX_NMEA_GNS = 0x0D; //GxGNS (GNSS fix data)
|
||||
const uint8_t UBX_NMEA_GPQ = 0x040; //GxGPQ (poll a standard message (if the current Talker ID is GP))
|
||||
const uint8_t UBX_NMEA_GRS = 0x06; //GxGRS (GNSS range residuals)
|
||||
const uint8_t UBX_NMEA_GSA = 0x02; //GxGSA (GNSS DOP and Active satellites)
|
||||
const uint8_t UBX_NMEA_GST = 0x07; //GxGST (GNSS Pseudo Range Error Statistics)
|
||||
const uint8_t UBX_NMEA_GSV = 0x03; //GxGSV (GNSS satellites in view)
|
||||
const uint8_t UBX_NMEA_RMC = 0x04; //GxRMC (Recommended minimum data)
|
||||
const uint8_t UBX_NMEA_TXT = 0x41; //GxTXT (text transmission)
|
||||
const uint8_t UBX_NMEA_VLW = 0x0F; //GxVLW (dual ground/water distance)
|
||||
const uint8_t UBX_NMEA_VTG = 0x05; //GxVTG (course over ground and Ground speed)
|
||||
const uint8_t UBX_NMEA_ZDA = 0x08; //GxZDA (Time and Date)
|
||||
|
||||
//The following are used to configure the NMEA protocol main talker ID and GSV talker ID
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_NOTOVERRIDDEN = 0x00; //main talker ID is system dependent
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_GP = 0x01; //main talker ID is GPS
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_GL = 0x02; //main talker ID is GLONASS
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_GN = 0x03; //main talker ID is combined receiver
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_GA = 0x04; //main talker ID is Galileo
|
||||
const uint8_t UBX_NMEA_MAINTALKERID_GB = 0x05; //main talker ID is BeiDou
|
||||
const uint8_t UBX_NMEA_GSVTALKERID_GNSS = 0x00; //GNSS specific Talker ID (as defined by NMEA)
|
||||
const uint8_t UBX_NMEA_GSVTALKERID_MAIN = 0x01; //use the main Talker ID
|
||||
|
||||
//The following are used to configure INF UBX messages (information messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 34)
|
||||
const uint8_t UBX_INF_CLASS = 0x04; //All INF messages have 0x04 as the class
|
||||
const uint8_t UBX_INF_DEBUG = 0x04; //ASCII output with debug contents
|
||||
const uint8_t UBX_INF_ERROR = 0x00; //ASCII output with error contents
|
||||
const uint8_t UBX_INF_NOTICE = 0x02; //ASCII output with informational contents
|
||||
const uint8_t UBX_INF_TEST = 0x03; //ASCII output with test contents
|
||||
const uint8_t UBX_INF_WARNING = 0x01; //ASCII output with warning contents
|
||||
|
||||
//The following are used to configure LOG UBX messages (loggings messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 34)
|
||||
const uint8_t UBX_LOG_CREATE = 0x07; //Create Log File
|
||||
const uint8_t UBX_LOG_ERASE = 0x03; //Erase Logged Data
|
||||
const uint8_t UBX_LOG_FINDTIME = 0x0E; //Find index of a log entry based on a given time, or response to FINDTIME requested
|
||||
const uint8_t UBX_LOG_INFO = 0x08; //Poll for log information, or Log information
|
||||
const uint8_t UBX_LOG_RETRIEVEPOSEXTRA = 0x0F; //Odometer log entry
|
||||
const uint8_t UBX_LOG_RETRIEVEPOS = 0x0B; //Position fix log entry
|
||||
const uint8_t UBX_LOG_RETRIEVESTRING = 0x0D; //Byte string log entry
|
||||
const uint8_t UBX_LOG_RETRIEVE = 0x09; //Request log data
|
||||
const uint8_t UBX_LOG_STRING = 0x04; //Store arbitrary string on on-board flash
|
||||
|
||||
//The following are used to configure MGA UBX messages (Multiple GNSS Assistance Messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 34)
|
||||
const uint8_t UBX_MGA_ACK_DATA0 = 0x60; //Multiple GNSS Acknowledge message
|
||||
const uint8_t UBX_MGA_BDS_EPH = 0x03; //BDS Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_BDS_ALM = 0x03; //BDS Almanac Assistance
|
||||
const uint8_t UBX_MGA_BDS_HEALTH = 0x03; //BDS Health Assistance
|
||||
const uint8_t UBX_MGA_BDS_UTC = 0x03; //BDS UTC Assistance
|
||||
const uint8_t UBX_MGA_BDS_IONO = 0x03; //BDS Ionospheric Assistance
|
||||
const uint8_t UBX_MGA_DBD = 0x80; //Either: Poll the Navigation Database, or Navigation Database Dump Entry
|
||||
const uint8_t UBX_MGA_GAL_EPH = 0x02; //Galileo Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_GAL_ALM = 0x02; //Galileo Almanac Assitance
|
||||
const uint8_t UBX_MGA_GAL_TIMOFFSET = 0x02; //Galileo GPS time offset assistance
|
||||
const uint8_t UBX_MGA_GAL_UTC = 0x02; //Galileo UTC Assistance
|
||||
const uint8_t UBX_MGA_GLO_EPH = 0x06; //GLONASS Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_GLO_ALM = 0x06; //GLONASS Almanac Assistance
|
||||
const uint8_t UBX_MGA_GLO_TIMEOFFSET = 0x06; //GLONASS Auxiliary Time Offset Assistance
|
||||
const uint8_t UBX_MGA_GPS_EPH = 0x00; //GPS Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_GPS_ALM = 0x00; //GPS Almanac Assistance
|
||||
const uint8_t UBX_MGA_GPS_HEALTH = 0x00; //GPS Health Assistance
|
||||
const uint8_t UBX_MGA_GPS_UTC = 0x00; //GPS UTC Assistance
|
||||
const uint8_t UBX_MGA_GPS_IONO = 0x00; //GPS Ionosphere Assistance
|
||||
const uint8_t UBX_MGA_INI_POS_XYZ = 0x40; //Initial Position Assistance
|
||||
const uint8_t UBX_MGA_INI_POS_LLH = 0x40; //Initial Position Assitance
|
||||
const uint8_t UBX_MGA_INI_TIME_UTC = 0x40; //Initial Time Assistance
|
||||
const uint8_t UBX_MGA_INI_TIME_GNSS = 0x40; //Initial Time Assistance
|
||||
const uint8_t UBX_MGA_INI_CLKD = 0x40; //Initial Clock Drift Assitance
|
||||
const uint8_t UBX_MGA_INI_FREQ = 0x40; //Initial Frequency Assistance
|
||||
const uint8_t UBX_MGA_INI_EOP = 0x40; //Earth Orientation Parameters Assistance
|
||||
const uint8_t UBX_MGA_QZSS_EPH = 0x05; //QZSS Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_QZSS_ALM = 0x05; //QZSS Almanac Assistance
|
||||
const uint8_t UBX_MGA_QZAA_HEALTH = 0x05; //QZSS Health Assistance
|
||||
|
||||
//The following are used to configure the MON UBX messages (monitoring messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 35)
|
||||
const uint8_t UBX_MON_COMMS = 0x36; //Comm port information
|
||||
const uint8_t UBX_MON_GNSS = 0x28; //Information message major GNSS selection
|
||||
const uint8_t UBX_MON_HW2 = 0x0B; //Extended Hardware Status
|
||||
const uint8_t UBX_MON_HW3 = 0x37; //HW I/O pin information
|
||||
const uint8_t UBX_MON_HW = 0x09; //Hardware Status
|
||||
const uint8_t UBX_MON_IO = 0x02; //I/O Subsystem Status
|
||||
const uint8_t UBX_MON_MSGPP = 0x06; //Message Parse and Process Status
|
||||
const uint8_t UBX_MON_PATCH = 0x27; //Output information about installed patches
|
||||
const uint8_t UBX_MON_RF = 0x38; //RF information
|
||||
const uint8_t UBX_MON_RXBUF = 0x07; //Receiver Buffer Status
|
||||
const uint8_t UBX_MON_RXR = 0x21; //Receiver Status Information
|
||||
const uint8_t UBX_MON_TXBUF = 0x08; //Transmitter Buffer Status. Used for query tx buffer size/state.
|
||||
const uint8_t UBX_MON_VER = 0x04; //Receiver/Software Version. Used for obtaining Protocol Version.
|
||||
|
||||
//The following are used to configure the NAV UBX messages (navigation results messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 35-36)
|
||||
const uint8_t UBX_NAV_ATT = 0x05; //Vehicle "Attitude" Solution
|
||||
const uint8_t UBX_NAV_CLOCK = 0x22; //Clock Solution
|
||||
const uint8_t UBX_NAV_DOP = 0x04; //Dilution of precision
|
||||
const uint8_t UBX_NAV_EOE = 0x61; //End of Epoch
|
||||
const uint8_t UBX_NAV_GEOFENCE = 0x39; //Geofencing status. Used to poll the geofence status
|
||||
const uint8_t UBX_NAV_HPPOSECEF = 0x13; //High Precision Position Solution in ECEF. Used to find our positional accuracy (high precision).
|
||||
const uint8_t UBX_NAV_HPPOSLLH = 0x14; //High Precision Geodetic Position Solution. Used for obtaining lat/long/alt in high precision
|
||||
const uint8_t UBX_NAV_ODO = 0x09; //Odometer Solution
|
||||
const uint8_t UBX_NAV_ORB = 0x34; //GNSS Orbit Database Info
|
||||
const uint8_t UBX_NAV_POSECEF = 0x01; //Position Solution in ECEF
|
||||
const uint8_t UBX_NAV_POSLLH = 0x02; //Geodetic Position Solution
|
||||
const uint8_t UBX_NAV_PVT = 0x07; //All the things! Position, velocity, time, PDOP, height, h/v accuracies, number of satellites. Navigation Position Velocity Time Solution.
|
||||
const uint8_t UBX_NAV_RELPOSNED = 0x3C; //Relative Positioning Information in NED frame
|
||||
const uint8_t UBX_NAV_RESETODO = 0x10; //Reset odometer
|
||||
const uint8_t UBX_NAV_SAT = 0x35; //Satellite Information
|
||||
const uint8_t UBX_NAV_SIG = 0x43; //Signal Information
|
||||
const uint8_t UBX_NAV_STATUS = 0x03; //Receiver Navigation Status
|
||||
const uint8_t UBX_NAV_SVIN = 0x3B; //Survey-in data. Used for checking Survey In status
|
||||
const uint8_t UBX_NAV_TIMEBDS = 0x24; //BDS Time Solution
|
||||
const uint8_t UBX_NAV_TIMEGAL = 0x25; //Galileo Time Solution
|
||||
const uint8_t UBX_NAV_TIMEGLO = 0x23; //GLO Time Solution
|
||||
const uint8_t UBX_NAV_TIMEGPS = 0x20; //GPS Time Solution
|
||||
const uint8_t UBX_NAV_TIMELS = 0x26; //Leap second event information
|
||||
const uint8_t UBX_NAV_TIMEUTC = 0x21; //UTC Time Solution
|
||||
const uint8_t UBX_NAV_VELECEF = 0x11; //Velocity Solution in ECEF
|
||||
const uint8_t UBX_NAV_VELNED = 0x12; //Velocity Solution in NED
|
||||
|
||||
//The following are used to configure the RXM UBX messages (receiver manager messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 36)
|
||||
const uint8_t UBX_RXM_MEASX = 0x14; //Satellite Measurements for RRLP
|
||||
const uint8_t UBX_RXM_PMREQ = 0x41; //Requests a Power Management task (two differenent packet sizes)
|
||||
const uint8_t UBX_RXM_RAWX = 0x15; //Multi-GNSS Raw Measurement Data
|
||||
const uint8_t UBX_RXM_RLM = 0x59; //Galileo SAR Short-RLM report (two different packet sizes)
|
||||
const uint8_t UBX_RXM_RTCM = 0x32; //RTCM input status
|
||||
const uint8_t UBX_RXM_SFRBX = 0x13; //Boradcast Navigation Data Subframe
|
||||
|
||||
//The following are used to configure the SEC UBX messages (security feature messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 36)
|
||||
const uint8_t UBX_SEC_UNIQID = 0x03; //Unique chip ID
|
||||
|
||||
//The following are used to configure the TIM UBX messages (timing messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 36)
|
||||
const uint8_t UBX_TIM_TM2 = 0x03; //Time mark data
|
||||
const uint8_t UBX_TIM_TP = 0x01; //Time Pulse Timedata
|
||||
const uint8_t UBX_TIM_VRFY = 0x06; //Sourced Time Verification
|
||||
|
||||
//The following are used to configure the UPD UBX messages (firmware update messages). Descriptions from UBX messages overview (ZED-F9P Interface Description Document page 36)
|
||||
const uint8_t UBX_UPD_SOS = 0x14; //Poll Backup Fil Restore Status, Create Backup File in Flash, Clear Backup File in Flash, Backup File Creation Acknowledge, System Restored from Backup
|
||||
|
||||
//The following are used to enable RTCM messages
|
||||
const uint8_t UBX_RTCM_MSB = 0xF5; //All RTCM enable commands have 0xF5 as MSB
|
||||
const uint8_t UBX_RTCM_1005 = 0x05; //Stationary RTK reference ARP
|
||||
const uint8_t UBX_RTCM_1074 = 0x4A; //GPS MSM4
|
||||
const uint8_t UBX_RTCM_1077 = 0x4D; //GPS MSM7
|
||||
const uint8_t UBX_RTCM_1084 = 0x54; //GLONASS MSM4
|
||||
const uint8_t UBX_RTCM_1087 = 0x57; //GLONASS MSM7
|
||||
const uint8_t UBX_RTCM_1094 = 0x5E; //Galileo MSM4
|
||||
const uint8_t UBX_RTCM_1097 = 0x61; //Galileo MSM7
|
||||
const uint8_t UBX_RTCM_1124 = 0x7C; //BeiDou MSM4
|
||||
const uint8_t UBX_RTCM_1127 = 0x7F; //BeiDou MSM7
|
||||
const uint8_t UBX_RTCM_1230 = 0xE6; //GLONASS code-phase biases, set to once every 10 seconds
|
||||
const uint8_t UBX_RTCM_4072_0 = 0xFE; //Reference station PVT (ublox proprietary RTCM message)
|
||||
const uint8_t UBX_RTCM_4072_1 = 0xFD; //Additional reference station information (ublox proprietary RTCM message)
|
||||
|
||||
const uint8_t UBX_ACK_NACK = 0x00;
|
||||
const uint8_t UBX_ACK_ACK = 0x01;
|
||||
const uint8_t UBX_ACK_NONE = 0x02; //Not a real value
|
||||
|
||||
// The following constants are used to get External Sensor Measurements and Status
|
||||
// Information.
|
||||
const uint8_t UBX_ESF_MEAS = 0x02;
|
||||
const uint8_t UBX_ESF_RAW = 0x03;
|
||||
const uint8_t UBX_ESF_STATUS = 0x10;
|
||||
const uint8_t UBX_ESF_INS = 0x15; //36 bytes
|
||||
|
||||
const uint8_t SVIN_MODE_DISABLE = 0x00;
|
||||
const uint8_t SVIN_MODE_ENABLE = 0x01;
|
||||
|
||||
//The following consts are used to configure the various ports and streams for those ports. See -CFG-PRT.
|
||||
const uint8_t COM_PORT_I2C = 0;
|
||||
const uint8_t COM_PORT_UART1 = 1;
|
||||
const uint8_t COM_PORT_UART2 = 2;
|
||||
const uint8_t COM_PORT_USB = 3;
|
||||
const uint8_t COM_PORT_SPI = 4;
|
||||
|
||||
const uint8_t COM_TYPE_UBX = (1 << 0);
|
||||
const uint8_t COM_TYPE_NMEA = (1 << 1);
|
||||
const uint8_t COM_TYPE_RTCM3 = (1 << 5);
|
||||
|
||||
//The following consts are used to generate KEY values for the advanced protocol functions of VELGET/SET/DEL
|
||||
const uint8_t VAL_SIZE_1 = 0x01; //One bit
|
||||
const uint8_t VAL_SIZE_8 = 0x02; //One byte
|
||||
const uint8_t VAL_SIZE_16 = 0x03; //Two bytes
|
||||
const uint8_t VAL_SIZE_32 = 0x04; //Four bytes
|
||||
const uint8_t VAL_SIZE_64 = 0x05; //Eight bytes
|
||||
|
||||
//These are the Bitfield layers definitions for the UBX-CFG-VALSET message (not to be confused with Bitfield deviceMask in UBX-CFG-CFG)
|
||||
const uint8_t VAL_LAYER_RAM = (1 << 0);
|
||||
const uint8_t VAL_LAYER_BBR = (1 << 1);
|
||||
const uint8_t VAL_LAYER_FLASH = (1 << 2);
|
||||
|
||||
//Below are various Groups, IDs, and sizes for various settings
|
||||
//These can be used to call getVal/setVal/delVal
|
||||
const uint8_t VAL_GROUP_I2COUTPROT = 0x72;
|
||||
const uint8_t VAL_GROUP_I2COUTPROT_SIZE = VAL_SIZE_1; //All fields in I2C group are currently 1 bit
|
||||
|
||||
const uint8_t VAL_ID_I2COUTPROT_UBX = 0x01;
|
||||
const uint8_t VAL_ID_I2COUTPROT_NMEA = 0x02;
|
||||
const uint8_t VAL_ID_I2COUTPROT_RTCM3 = 0x03;
|
||||
|
||||
const uint8_t VAL_GROUP_I2C = 0x51;
|
||||
const uint8_t VAL_GROUP_I2C_SIZE = VAL_SIZE_8; //All fields in I2C group are currently 1 byte
|
||||
|
||||
const uint8_t VAL_ID_I2C_ADDRESS = 0x01;
|
||||
|
||||
// Configuration Sub-Section mask definitions for saveConfigSelective (UBX-CFG-CFG)
|
||||
const uint32_t VAL_CFG_SUBSEC_IOPORT = 0x00000001; // ioPort - communications port settings (causes IO system reset!)
|
||||
const uint32_t VAL_CFG_SUBSEC_MSGCONF = 0x00000002; // msgConf - message configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_INFMSG = 0x00000004; // infMsg - INF message configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_NAVCONF = 0x00000008; // navConf - navigation configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_RXMCONF = 0x00000010; // rxmConf - receiver manager configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_SENCONF = 0x00000100; // senConf - sensor interface configuration (requires protocol 19+)
|
||||
const uint32_t VAL_CFG_SUBSEC_RINVCONF = 0x00000200; // rinvConf - remove inventory configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_ANTCONF = 0x00000400; // antConf - antenna configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_LOGCONF = 0x00000800; // logConf - logging configuration
|
||||
const uint32_t VAL_CFG_SUBSEC_FTSCONF = 0x00001000; // ftsConf - FTS configuration (FTS products only)
|
||||
|
||||
// Bitfield wakeupSources for UBX_RXM_PMREQ
|
||||
const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_UARTRX = 0x00000008; // uartrx
|
||||
const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0 = 0x00000020; // extint0
|
||||
const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT1 = 0x00000040; // extint1
|
||||
const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_SPICS = 0x00000080; // spics
|
||||
|
||||
enum dynModel // Possible values for the dynamic platform model, which provide more accuract position output for the situation. Description extracted from ZED-F9P Integration Manual
|
||||
{
|
||||
DYN_MODEL_PORTABLE = 0, //Applications with low acceleration, e.g. portable devices. Suitable for most situations.
|
||||
// 1 is not defined
|
||||
DYN_MODEL_STATIONARY = 2, //Used in timing applications (antenna must be stationary) or other stationary applications. Velocity restricted to 0 m/s. Zero dynamics assumed.
|
||||
DYN_MODEL_PEDESTRIAN, //Applications with low acceleration and speed, e.g. how a pedestrian would move. Low acceleration assumed.
|
||||
DYN_MODEL_AUTOMOTIVE, //Used for applications with equivalent dynamics to those of a passenger car. Low vertical acceleration assumed
|
||||
DYN_MODEL_SEA, //Recommended for applications at sea, with zero vertical velocity. Zero vertical velocity assumed. Sea level assumed.
|
||||
DYN_MODEL_AIRBORNE1g, //Airborne <1g acceleration. Used for applications with a higher dynamic range and greater vertical acceleration than a passenger car. No 2D position fixes supported.
|
||||
DYN_MODEL_AIRBORNE2g, //Airborne <2g acceleration. Recommended for typical airborne environments. No 2D position fixes supported.
|
||||
DYN_MODEL_AIRBORNE4g, //Airborne <4g acceleration. Only recommended for extremely dynamic environments. No 2D position fixes supported.
|
||||
DYN_MODEL_WRIST, // Not supported in protocol versions less than 18. Only recommended for wrist worn applications. Receiver will filter out arm motion.
|
||||
DYN_MODEL_BIKE, // Supported in protocol versions 19.2
|
||||
};
|
||||
|
||||
#ifndef MAX_PAYLOAD_SIZE
|
||||
|
||||
#define MAX_PAYLOAD_SIZE 256 //We need ~220 bytes for getProtocolVersion on most ublox modules
|
||||
//#define MAX_PAYLOAD_SIZE 768 //Worst case: UBX_CFG_VALSET packet with 64 keyIDs each with 64 bit values
|
||||
|
||||
#endif
|
||||
|
||||
//-=-=-=-=- UBX binary specific variables
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cls;
|
||||
uint8_t 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;
|
||||
uint8_t checksumA; //Given to us from 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
|
||||
} ubxPacket;
|
||||
|
||||
// Struct to hold the results returned by getGeofenceState (returned by UBX-NAV-GEOFENCE)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t status; // Geofencing status: 0 - Geofencing not available or not reliable; 1 - Geofencing active
|
||||
uint8_t numFences; // Number of geofences
|
||||
uint8_t combState; // Combined (logical OR) state of all geofences: 0 - Unknown; 1 - Inside; 2 - Outside
|
||||
uint8_t states[4]; // Geofence states: 0 - Unknown; 1 - Inside; 2 - Outside
|
||||
} geofenceState;
|
||||
|
||||
// Struct to hold the current geofence parameters
|
||||
typedef struct
|
||||
{
|
||||
uint8_t numFences; // Number of active geofences
|
||||
int32_t lats[4]; // Latitudes of geofences (in degrees * 10^-7)
|
||||
int32_t longs[4]; // Longitudes of geofences (in degrees * 10^-7)
|
||||
uint32_t rads[4]; // Radii of geofences (in m * 10^-2)
|
||||
} geofenceParams;
|
||||
|
||||
class SFE_UBLOX_GPS
|
||||
{
|
||||
public:
|
||||
SFE_UBLOX_GPS(void);
|
||||
|
||||
// A default of 250ms for maxWait seems fine for I2C but is not enough for SerialUSB.
|
||||
// If you know you are only going to be using I2C / Qwiic communication, you can
|
||||
// safely reduce defaultMaxWait to 250.
|
||||
#ifndef defaultMaxWait // Let's allow the user to define their own value if they want to
|
||||
#define defaultMaxWait 250 // only I2C is used, so this has been reduced from 1100
|
||||
#endif
|
||||
|
||||
// Set gpio device, used by checksumFailurePin
|
||||
bool init_gpio_pins(struct device &gpio_dev);
|
||||
|
||||
//By default use the default I2C address
|
||||
bool begin(struct device &i2c_dev, uint8_t deviceAddress = 0x42); //Returns true if module is detected
|
||||
//serialPort needs to be perviously initialized to correct baud rate
|
||||
//bool begin(Stream &serialPort); //Returns true if module is detected - function not ported
|
||||
|
||||
//Returns true if device answers on _gpsI2Caddress address or via Serial
|
||||
//maxWait is only used for Serial
|
||||
bool isConnected(uint16_t maxWait = 1100);
|
||||
|
||||
//Changed in V1.8.1: provides backward compatibility for the examples that call checkUblox directly
|
||||
//Will default to using packetCfg to look for explicit autoPVT packets so they get processed correctly by processUBX
|
||||
bool checkUblox(uint8_t requestedClass = UBX_CLASS_NAV, uint8_t requestedID = UBX_NAV_PVT); //Checks module with user selected commType
|
||||
|
||||
bool checkUbloxI2C(ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); //Method for I2C polling of data, passing any new bytes to process()
|
||||
bool checkUbloxSerial(ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); //Method for serial polling of data, passing any new bytes to process()
|
||||
|
||||
void process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); //Processes NMEA and UBX binary sentences one byte at a time
|
||||
void processUBX(uint8_t incoming, ubxPacket *incomingUBX, uint8_t requestedClass, uint8_t requestedID); //Given a character, file it away into the uxb packet structure
|
||||
void processRTCMframe(uint8_t incoming); //Monitor the incoming bytes for start and length bytes
|
||||
void processRTCM(uint8_t incoming) __attribute__((weak)); //Given rtcm byte, do something with it. User can overwrite if desired to pipe bytes to radio, internet, etc.
|
||||
|
||||
void processUBXpacket(ubxPacket *msg); //Once a packet has been received and validated, identify this packet's class/id and update internal flags
|
||||
void processNMEA(char incoming) __attribute__((weak)); //Given a NMEA character, do something with it. User can overwrite if desired to use something like tinyGPS or MicroNMEA libraries
|
||||
|
||||
void calcChecksum(ubxPacket *msg); //Sets the checksumA and checksumB of a given messages
|
||||
sfe_ublox_status_e sendCommand(ubxPacket *outgoingUBX, uint16_t maxWait = defaultMaxWait); //Given a packet and payload, send everything including CRC bytes, return true if we got a response
|
||||
sfe_ublox_status_e sendI2cCommand(ubxPacket *outgoingUBX, uint16_t maxWait = 250);
|
||||
void sendSerialCommand(ubxPacket *outgoingUBX);
|
||||
|
||||
void printPacket(ubxPacket *packet); //Useful for debugging
|
||||
|
||||
void factoryReset(); //Send factory reset sequence (i.e. load "default" configuration and perform hardReset)
|
||||
void hardReset(); //Perform a reset leading to a cold start (zero info start-up)
|
||||
|
||||
int transferWriteI2C(u8_t *buf, u32_t num_bytes, bool stop = true); // Port to Zephyr, i2c function to actualy WRITE data
|
||||
int transferReadI2C(u8_t *buf, u32_t num_bytes); // Port to Zephyr, i2c function to actualy READ data
|
||||
|
||||
bool setI2CAddress(uint8_t deviceAddress, uint16_t maxTime = 250); //Changes the I2C address of the Ublox module
|
||||
void setSerialRate(uint32_t baudrate, uint8_t uartPort = COM_PORT_UART1, uint16_t maxTime = defaultMaxWait); //Changes the serial baud rate of the Ublox module, uartPort should be COM_PORT_UART1/2
|
||||
void setNMEAOutputPort(); //Sets the internal variable for the port to direct NMEA characters to
|
||||
|
||||
bool setNavigationFrequency(uint8_t navFreq, uint16_t maxWait = defaultMaxWait); //Set the number of nav solutions sent per second
|
||||
uint8_t getNavigationFrequency(uint16_t maxWait = defaultMaxWait); //Get the number of nav solutions sent per second currently being output by module
|
||||
bool saveConfiguration(uint16_t maxWait = defaultMaxWait); //Save current configuration to flash and BBR (battery backed RAM)
|
||||
bool factoryDefault(uint16_t maxWait = defaultMaxWait); //Reset module to factory defaults
|
||||
bool saveConfigSelective(uint32_t configMask, uint16_t maxWait = defaultMaxWait); //Save the selected configuration sub-sections to flash and BBR (battery backed RAM)
|
||||
|
||||
sfe_ublox_status_e waitForACKResponse(ubxPacket *outgoingUBX, uint8_t requestedClass, uint8_t requestedID, uint16_t maxTime = defaultMaxWait); //Poll the module until a config packet and an ACK is received
|
||||
sfe_ublox_status_e waitForNoACKResponse(ubxPacket *outgoingUBX, uint8_t requestedClass, uint8_t requestedID, uint16_t maxTime = defaultMaxWait); //Poll the module until a config packet is received
|
||||
|
||||
// getPVT will only return data once in each navigation cycle. By default, that is once per second.
|
||||
// Therefore we should set getPVTmaxWait to slightly longer than that.
|
||||
// If you change the navigation frequency to (e.g.) 4Hz using setNavigationFrequency(4)
|
||||
// then you should use a shorter maxWait for getPVT. 300msec would be about right: getPVT(300)
|
||||
// The same is true for getHPPOSLLH.
|
||||
#define getPVTmaxWait 1100 // Default maxWait for getPVT and all functions which call it
|
||||
#define getHPPOSLLHmaxWait 1100 // Default maxWait for getHPPOSLLH and all functions which call it
|
||||
|
||||
bool assumeAutoPVT(bool enabled, bool implicitUpdate = true); //In case no config access to the GPS is possible and PVT is send cyclically already
|
||||
bool setAutoPVT(bool enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic PVT reports at the navigation frequency
|
||||
bool getPVT(uint16_t maxWait = getPVTmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available.
|
||||
bool setAutoPVT(bool enabled, bool implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic PVT reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update
|
||||
bool getHPPOSLLH(uint16_t maxWait = getHPPOSLLHmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available.
|
||||
void flushPVT(); //Mark all the PVT data as read/stale. This is handy to get data alignment after CRC failure
|
||||
|
||||
int32_t getLatitude(uint16_t maxWait = getPVTmaxWait); //Returns the current latitude in degrees * 10^-7. Auto selects between HighPrecision and Regular depending on ability of module.
|
||||
int32_t getLongitude(uint16_t maxWait = getPVTmaxWait); //Returns the current longitude in degrees * 10-7. Auto selects between HighPrecision and Regular depending on ability of module.
|
||||
int32_t getAltitude(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above ellipsoid
|
||||
int32_t getAltitudeMSL(uint16_t maxWait = getPVTmaxWait); //Returns number of sats used in fix
|
||||
uint8_t getSIV(uint16_t maxWait = getPVTmaxWait); //Returns number of sats used in fix
|
||||
uint8_t getFixType(uint16_t maxWait = getPVTmaxWait); //Returns the type of fix: 0=no, 3=3D, 4=GNSS+Deadreckoning
|
||||
uint8_t getCarrierSolutionType(uint16_t maxWait = getPVTmaxWait); //Returns RTK solution: 0=no, 1=float solution, 2=fixed solution
|
||||
int32_t getGroundSpeed(uint16_t maxWait = getPVTmaxWait); //Returns speed in mm/s
|
||||
int32_t getHeading(uint16_t maxWait = getPVTmaxWait); //Returns heading in degrees * 10^-7
|
||||
uint16_t getPDOP(uint16_t maxWait = getPVTmaxWait); //Returns positional dillution of precision * 10^-2
|
||||
uint16_t getYear(uint16_t maxWait = getPVTmaxWait);
|
||||
uint8_t getMonth(uint16_t maxWait = getPVTmaxWait);
|
||||
uint8_t getDay(uint16_t maxWait = getPVTmaxWait);
|
||||
uint8_t getHour(uint16_t maxWait = getPVTmaxWait);
|
||||
uint8_t getMinute(uint16_t maxWait = getPVTmaxWait);
|
||||
uint8_t getSecond(uint16_t maxWait = getPVTmaxWait);
|
||||
uint16_t getMillisecond(uint16_t maxWait = getPVTmaxWait);
|
||||
int32_t getNanosecond(uint16_t maxWait = getPVTmaxWait);
|
||||
uint32_t getTimeOfWeek(uint16_t maxWait = getPVTmaxWait);
|
||||
bool getDateValid(uint16_t maxWait = getPVTmaxWait);
|
||||
bool getTimeValid(uint16_t maxWait = getPVTmaxWait);
|
||||
|
||||
int32_t getHighResLatitude(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int8_t getHighResLatitudeHp(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int32_t getHighResLongitude(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int8_t getHighResLongitudeHp(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int32_t getElipsoid(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int8_t getElipsoidHp(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int32_t getMeanSeaLevel(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int8_t getMeanSeaLevelHp(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
int32_t getGeoidSeparation(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
uint32_t getHorizontalAccuracy(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
uint32_t getVerticalAccuracy(uint16_t maxWait = getHPPOSLLHmaxWait);
|
||||
|
||||
//Port configurations
|
||||
bool setPortOutput(uint8_t portID, uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure a given port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
bool setPortInput(uint8_t portID, uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure a given port to input UBX, NMEA, RTCM3 or a combination thereof
|
||||
bool getPortSettings(uint8_t portID, uint16_t maxWait = defaultMaxWait); //Returns the current protocol bits in the UBX-CFG-PRT command for a given port
|
||||
|
||||
bool setI2COutput(uint8_t comSettings, uint16_t maxWait = 250); //Configure I2C port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
bool setUART1Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART1 port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
bool setUART2Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART2 port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
bool setUSBOutput(uint8_t comSettings, uint16_t maxWait = 250); //Configure USB port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
bool setSPIOutput(uint8_t comSettings, uint16_t maxWait = 250); //Configure SPI port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||
|
||||
//Functions to turn on/off message types for a given port ID (see COM_PORT_I2C, etc above)
|
||||
bool configureMessage(uint8_t msgClass, uint8_t msgID, uint8_t portID, uint8_t sendRate, uint16_t maxWait = defaultMaxWait);
|
||||
bool enableMessage(uint8_t msgClass, uint8_t msgID, uint8_t portID, uint8_t sendRate = 1, uint16_t maxWait = defaultMaxWait);
|
||||
bool disableMessage(uint8_t msgClass, uint8_t msgID, uint8_t portID, uint16_t maxWait = defaultMaxWait);
|
||||
bool enableNMEAMessage(uint8_t msgID, uint8_t portID, uint8_t sendRate = 1, uint16_t maxWait = defaultMaxWait);
|
||||
bool disableNMEAMessage(uint8_t msgID, uint8_t portID, uint16_t maxWait = defaultMaxWait);
|
||||
bool enableRTCMmessage(uint8_t messageNumber, uint8_t portID, uint8_t sendRate, uint16_t maxWait = defaultMaxWait); //Given a message number turns on a message ID for output over given PortID
|
||||
bool disableRTCMmessage(uint8_t messageNumber, uint8_t portID, uint16_t maxWait = defaultMaxWait); //Turn off given RTCM message from a given port
|
||||
|
||||
//General configuration (used only on protocol v27 and higher - ie, ZED-F9P)
|
||||
//It is probably safe to assume that users ofovaj the ZED-F9P will be using I2C / Qwiic.
|
||||
//If they are using Serial then the higher baud rate will also help. So let's leave maxWait set to 250ms.
|
||||
uint8_t getVal8(uint16_t group, uint16_t id, uint8_t size, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Returns the value at a given group/id/size location
|
||||
uint8_t getVal8(uint32_t keyID, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Returns the value at a given group/id/size location
|
||||
uint8_t setVal(uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Sets the 16-bit value at a given group/id/size location
|
||||
uint8_t setVal8(uint32_t keyID, uint8_t value, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Sets the 8-bit value at a given group/id/size location
|
||||
uint8_t setVal16(uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Sets the 16-bit value at a given group/id/size location
|
||||
uint8_t setVal32(uint32_t keyID, uint32_t value, uint8_t layer = VAL_LAYER_BBR, uint16_t maxWait = 250); //Sets the 32-bit value at a given group/id/size location
|
||||
uint8_t newCfgValset8(uint32_t keyID, uint8_t value, uint8_t layer = VAL_LAYER_BBR); //Define a new UBX-CFG-VALSET with the given KeyID and 8-bit value
|
||||
uint8_t newCfgValset16(uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_BBR); //Define a new UBX-CFG-VALSET with the given KeyID and 16-bit value
|
||||
uint8_t newCfgValset32(uint32_t keyID, uint32_t value, uint8_t layer = VAL_LAYER_BBR); //Define a new UBX-CFG-VALSET with the given KeyID and 32-bit value
|
||||
uint8_t addCfgValset8(uint32_t keyID, uint8_t value); //Add a new KeyID and 8-bit value to an existing UBX-CFG-VALSET ubxPacket
|
||||
uint8_t addCfgValset16(uint32_t keyID, uint16_t value); //Add a new KeyID and 16-bit value to an existing UBX-CFG-VALSET ubxPacket
|
||||
uint8_t addCfgValset32(uint32_t keyID, uint32_t value); //Add a new KeyID and 32-bit value to an existing UBX-CFG-VALSET ubxPacket
|
||||
uint8_t sendCfgValset8(uint32_t keyID, uint8_t value, uint16_t maxWait = 250); //Add the final KeyID and 8-bit value to an existing UBX-CFG-VALSET ubxPacket and send it
|
||||
uint8_t sendCfgValset16(uint32_t keyID, uint16_t value, uint16_t maxWait = 250); //Add the final KeyID and 16-bit value to an existing UBX-CFG-VALSET ubxPacket and send it
|
||||
uint8_t sendCfgValset32(uint32_t keyID, uint32_t value, uint16_t maxWait = 250); //Add the final KeyID and 32-bit value to an existing UBX-CFG-VALSET ubxPacket and send it
|
||||
|
||||
//Functions used for RTK and base station setup
|
||||
//It is probably safe to assume that users of the RTK will be using I2C / Qwiic. So let's leave maxWait set to 250ms.
|
||||
bool getSurveyMode(uint16_t maxWait = 250); //Get the current TimeMode3 settings
|
||||
bool setSurveyMode(uint8_t mode, uint16_t ovajobservationTime, float requiredAccuracy, uint16_t maxWait = 250); //Control survey in mode
|
||||
bool enableSurveyMode(uint16_t observationTime, float requiredAccuracy, uint16_t maxWait = 250); //Begin Survey-In for NEO-M8P
|
||||
bool disableSurveyMode(uint16_t maxWait = 250); //Stop Survey-In mode
|
||||
|
||||
bool getSurveyStatus(uint16_t maxWait); //Reads survey in status and sets the global variables
|
||||
|
||||
uint32_t getPositionAccuracy(uint16_t maxWait = 1100); //Returns the 3D accuracy of the current high-precision fix, in mm. Supported on NEO-M8P, ZED-F9P,
|
||||
|
||||
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
|
||||
bool getProtocolVersion(uint16_t maxWait = 500); //Queries module, loads low/high bytes
|
||||
|
||||
bool getRELPOSNED(uint16_t maxWait = 1100); //Get Relative Positioning Information of the NED frame
|
||||
|
||||
void enableDebugging(bool printLimitedDebug = false); //Given a port to print to, enable debug messages. Default to all, not limited.
|
||||
void disableDebugging(void); //Turn off debug statements
|
||||
void debugPrint(char *message); //Safely print debug statements
|
||||
void debugPrintln(char *message); //Safely print debug statements
|
||||
const char *statusString(sfe_ublox_status_e stat); //Pretty print the return value
|
||||
|
||||
//Support for geofences
|
||||
bool addGeofence(int32_t latitude, int32_t longitude, uint32_t radius, uint8_t confidence = 0, uint8_t pinPolarity = 0, uint8_t pin = 0, uint16_t maxWait = 1100); // Add a new geofence
|
||||
bool clearGeofences(uint16_t maxWait = 1100); //Clears all geofences
|
||||
bool getGeofenceState(geofenceState ¤tGeofenceState, uint16_t maxWait = 1100); //Returns the combined geofence state
|
||||
bool clearAntPIO(uint16_t maxWait = 1100); //Clears the antenna control pin settings to release the PIOs
|
||||
geofenceParams currentGeofenceParams; // Global to store the geofence parameters
|
||||
|
||||
bool powerSaveMode(bool power_save = true, uint16_t maxWait = 1100);
|
||||
uint8_t getPowerSaveMode(uint16_t maxWait = 1100); // Returns 255 if the sendCommand fails
|
||||
bool powerOff(uint32_t durationInMs, uint16_t maxWait = 1100);
|
||||
bool powerOffWithInterrupt(uint32_t durationInMs, uint32_t wakeupSources = VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0, bool forceWhileUsb = true, uint16_t maxWait = 1100);
|
||||
|
||||
//Change the dynamic platform model using UBX-CFG-NAV5
|
||||
bool setDynamicModel(dynModel newDynamicModel = DYN_MODEL_PORTABLE, uint16_t maxWait = 1100);
|
||||
uint8_t getDynamicModel(uint16_t maxWait = 1100); // Get the dynamic model - returns 255 if the sendCommand fails
|
||||
|
||||
bool getEsfInfo(uint16_t maxWait = 1100);
|
||||
bool getEsfIns(uint16_t maxWait = 1100);
|
||||
bool getEsfDataInfo(uint16_t maxWait = 1100);
|
||||
bool getEsfRawDataInfo(uint16_t maxWait = 1100);
|
||||
sfe_ublox_status_e getSensState(uint8_t sensor, uint16_t maxWait = 1100);
|
||||
bool getVehAtt(uint16_t maxWait = 1100);
|
||||
|
||||
//Survey-in specific controls
|
||||
struct svinStructure
|
||||
{
|
||||
bool active;
|
||||
bool valid;
|
||||
uint16_t observationTime;
|
||||
float meanAccuracy;
|
||||
} svin;
|
||||
|
||||
//Relative Positioning Info in NED frame specific controls
|
||||
struct frelPosInfoStructure
|
||||
{
|
||||
uint16_t refStationID;
|
||||
|
||||
float relPosN;
|
||||
float relPosE;
|
||||
float relPosD;
|
||||
|
||||
long relPosLength;
|
||||
long relPosHeading;
|
||||
|
||||
int8_t relPosHPN;
|
||||
int8_t relPosHPE;
|
||||
int8_t relPosHPD;
|
||||
int8_t relPosHPLength;
|
||||
|
||||
float accN;
|
||||
float accE;
|
||||
float accD;
|
||||
|
||||
bool gnssFixOk;
|
||||
bool diffSoln;
|
||||
bool relPosValid;
|
||||
uint8_t carrSoln;
|
||||
bool isMoving;
|
||||
bool refPosMiss;
|
||||
bool refObsMiss;
|
||||
} relPosInfo;
|
||||
|
||||
//The major datums we want to globally store
|
||||
uint16_t gpsYear;
|
||||
uint8_t gpsMonth;
|
||||
uint8_t gpsDay;
|
||||
uint8_t gpsHour;
|
||||
uint8_t gpsMinute;
|
||||
uint8_t gpsSecond;
|
||||
uint16_t gpsMillisecond;
|
||||
int32_t gpsNanosecond;
|
||||
bool gpsDateValid;
|
||||
bool gpsTimeValid;
|
||||
|
||||
int32_t latitude; //Degrees * 10^-7 (more accurate than floats)
|
||||
int32_t longitude; //Degrees * 10^-7 (more accurate than floats)
|
||||
int32_t altitude; //Number of mm above ellipsoid
|
||||
int32_t altitudeMSL; //Number of mm above Mean Sea Level
|
||||
uint8_t SIV; //Number of satellites used in position solution
|
||||
uint8_t fixType; //Tells us when we have a solution aka lock
|
||||
uint8_t carrierSolution; //Tells us when we have an RTK float/fixed solution
|
||||
int32_t groundSpeed; //mm/s
|
||||
int32_t headingOfMotion; //degrees * 10^-5
|
||||
uint16_t pDOP; //Positional dilution of precision
|
||||
uint8_t versionLow; //Loaded from getProtocolVersion().
|
||||
uint8_t versionHigh;
|
||||
|
||||
uint32_t timeOfWeek; // ms
|
||||
int32_t highResLatitude; // Degrees * 10^-7
|
||||
int32_t highResLongitude; // Degrees * 10^-7
|
||||
int32_t elipsoid; // Height above ellipsoid in mm (Typo! Should be eLLipsoid! **Uncorrected for backward-compatibility.**)
|
||||
int32_t meanSeaLevel; // Height above mean sea level in mm
|
||||
int32_t geoidSeparation; // This seems to only be provided in NMEA GGA and GNS messages
|
||||
uint32_t horizontalAccuracy; // mm * 10^-1 (i.e. 0.1mm)
|
||||
uint32_t verticalAccuracy; // mm * 10^-1 (i.e. 0.1mm)
|
||||
int8_t elipsoidHp; // High precision component of the height above ellipsoid in mm * 10^-1 (Deliberate typo! Should be eLLipsoidHp!)
|
||||
int8_t meanSeaLevelHp; // High precision component of Height above mean sea level in mm * 10^-1
|
||||
int8_t highResLatitudeHp; // High precision component of latitude: Degrees * 10^-9
|
||||
int8_t highResLongitudeHp; // High precision component of longitude: Degrees * 10^-9
|
||||
|
||||
uint16_t rtcmFrameCounter = 0; //Tracks the type of incoming byte inside RTCM frame
|
||||
|
||||
#define DEF_NUM_SENS 7
|
||||
struct deadReckData
|
||||
{
|
||||
uint8_t version;
|
||||
uint8_t fusionMode;
|
||||
|
||||
uint8_t xAngRateVald;
|
||||
uint8_t yAngRateVald;
|
||||
uint8_t zAngRateVald;
|
||||
uint8_t xAccelVald;
|
||||
uint8_t yAccelVald;
|
||||
uint8_t zAccelVald;
|
||||
|
||||
int32_t xAngRate;
|
||||
int32_t yAngRate;
|
||||
int32_t zAngRate;
|
||||
|
||||
int32_t xAccel;
|
||||
int32_t yAccel;
|
||||
int32_t zAccel;
|
||||
|
||||
// The array size is based on testing directly on M8U and F9R
|
||||
uint32_t rawData;
|
||||
uint32_t rawDataType;
|
||||
uint32_t rawTStamp;
|
||||
|
||||
uint32_t data[DEF_NUM_SENS];
|
||||
uint32_t dataType[DEF_NUM_SENS];
|
||||
uint32_t dataTStamp[DEF_NUM_SENS];
|
||||
} imuMeas;
|
||||
|
||||
struct indivImuData
|
||||
{
|
||||
|
||||
uint8_t numSens;
|
||||
|
||||
uint8_t senType;
|
||||
bool isUsed;
|
||||
bool isReady;
|
||||
uint8_t calibStatus;
|
||||
uint8_t timeStatus;
|
||||
|
||||
uint8_t freq; // Hz
|
||||
|
||||
bool badMeas;
|
||||
bool badTag;
|
||||
bool missMeas;
|
||||
bool noisyMeas;
|
||||
} ubloxSen;
|
||||
|
||||
struct vehicleAttitude
|
||||
{
|
||||
// All values in degrees
|
||||
int32_t roll;
|
||||
int32_t pitch;
|
||||
int32_t heading;
|
||||
uint32_t accRoll;
|
||||
uint32_t accPitch;
|
||||
uint32_t accHeading;
|
||||
} vehAtt;
|
||||
|
||||
private:
|
||||
//Depending on the sentence type the processor will load characters into different arrays
|
||||
enum SentenceTypes
|
||||
{
|
||||
NONE = 0,
|
||||
NMEA,
|
||||
UBX,
|
||||
RTCM
|
||||
} currentSentence = NONE;
|
||||
|
||||
//Depending on the ubx binary response class, store binary responses into different places
|
||||
enum classTypes
|
||||
{
|
||||
CLASS_NONE = 0,
|
||||
CLASS_ACK,
|
||||
CLASS_NOT_AN_ACK
|
||||
} ubxFrameClass = CLASS_NONE;
|
||||
|
||||
enum commTypes
|
||||
{
|
||||
COMM_TYPE_I2C = 0,
|
||||
COMM_TYPE_SERIAL,
|
||||
COMM_TYPE_SPI
|
||||
} commType = COMM_TYPE_I2C; //Controls which port we look to for incoming bytes
|
||||
|
||||
//Functions
|
||||
bool checkUbloxInternal(ubxPacket *incomingUBX, uint8_t requestedClass = 255, uint8_t requestedID = 255); //Checks module with user selected commType
|
||||
uint32_t extractLong(uint8_t spotToStart); //Combine four bytes from payload into long
|
||||
uint16_t extractInt(uint8_t spotToStart); //Combine two bytes from payload into int
|
||||
uint8_t extractByte(uint8_t spotToStart); //Get byte from payload
|
||||
int8_t extractSignedChar(uint8_t spotToStart); //Get signed 8-bit value from payload
|
||||
void addToChecksum(uint8_t incoming); //Given an incoming byte, adjust rollingChecksumA/B
|
||||
|
||||
//Variables
|
||||
struct device *_gpio_dev; // GPIO device
|
||||
struct device *_i2cPort; //The generic connection to user's chosen I2C hardware
|
||||
//Stream *_serialPort; //The generic connection to user's chosen Serial hardware
|
||||
bool _nmeaOutputPort = false; //The user can assign an output port to print NMEA sentences if they wish - ported to print to console, converted to flag
|
||||
//Stream *_debugSerial; //The stream to send debug messages to if enabled
|
||||
|
||||
uint8_t _gpsI2Caddress = 0x42; //Default 7-bit unshifted address of the ublox 6/7/8/M8/F9 series
|
||||
//This can be changed using the ublox configuration software
|
||||
|
||||
bool _printDebug = false; //Flag to print the serial commands we are sending to the Serial port for debug
|
||||
bool _printLimitedDebug = false; //Flag to print limited debug messages. Useful for I2C debugging or high navigation rates
|
||||
|
||||
//The packet buffers
|
||||
//These are pointed at from within the ubxPacket
|
||||
uint8_t payloadAck[2]; // Holds the requested ACK/NACK
|
||||
uint8_t payloadCfg[MAX_PAYLOAD_SIZE]; // Holds the requested data packet
|
||||
uint8_t payloadBuf[2]; // Temporary buffer used to screen incoming packets or dump unrequested packets
|
||||
|
||||
//Init the packet structures and init them with pointers to the payloadAck, payloadCfg and payloadBuf arrays
|
||||
ubxPacket packetAck = {0, 0, 0, 0, 0, payloadAck, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
|
||||
ubxPacket packetCfg = {0, 0, 0, 0, 0, payloadCfg, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
|
||||
ubxPacket packetBuf = {0, 0, 0, 0, 0, payloadBuf, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
|
||||
|
||||
//Flag if this packet is unrequested (and so should be ignored and not copied into packetCfg or packetAck)
|
||||
bool ignoreThisPayload = false;
|
||||
|
||||
//Identify which buffer is in use
|
||||
//Data is stored in packetBuf until the requested class and ID can be validated
|
||||
//If a match is seen, data is diverted into packetAck or packetCfg
|
||||
sfe_ublox_packet_buffer_e activePacketBuffer = SFE_UBLOX_PACKET_PACKETBUF;
|
||||
|
||||
//Limit checking of new data to every X ms
|
||||
//If we are expecting an update every X Hz then we should check every half that amount of time
|
||||
//Otherwise we may block ourselves from seeing new data
|
||||
uint8_t i2cPollingWait = 100; //Default to 100ms. Adjusted when user calls setNavigationFrequency()
|
||||
|
||||
unsigned long lastCheck = 0;
|
||||
bool autoPVT = false; //Whether autoPVT is enabled or not
|
||||
bool autoPVTImplicitUpdate = true; // Whether autoPVT is triggered by accessing stale data (=true) or by a call to checkUblox (=false)
|
||||
uint16_t ubxFrameCounter; //It counts all UBX frame. [Fixed header(2bytes), CLS(1byte), ID(1byte), length(2bytes), payload(x bytes), checksums(2bytes)]
|
||||
|
||||
uint8_t rollingChecksumA; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes
|
||||
uint8_t rollingChecksumB; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes
|
||||
|
||||
//Create bit field for staleness of each datum in PVT we want to monitor
|
||||
//moduleQueried.latitude goes true each time we call getPVT()
|
||||
//This reduces the number of times we have to call getPVT as this can take up to ~1s per read
|
||||
//depending on update rate
|
||||
struct
|
||||
{
|
||||
uint32_t gpsiTOW : 1;
|
||||
uint32_t gpsYear : 1;
|
||||
uint32_t gpsMonth : 1;
|
||||
uint32_t gpsDay : 1;
|
||||
uint32_t gpsHour : 1;
|
||||
uint32_t gpsMinute : 1;
|
||||
uint32_t gpsSecond : 1;
|
||||
uint32_t gpsDateValid : 1;
|
||||
uint32_t gpsTimeValid : 1;
|
||||
uint32_t gpsNanosecond : 1;
|
||||
|
||||
uint32_t all : 1;
|
||||
uint32_t longitude : 1;
|
||||
uint32_t latitude : 1;
|
||||
uint32_t altitude : 1;
|
||||
uint32_t altitudeMSL : 1;
|
||||
uint32_t SIV : 1;
|
||||
uint32_t fixType : 1;
|
||||
uint32_t carrierSolution : 1;
|
||||
uint32_t groundSpeed : 1;
|
||||
uint32_t headingOfMotion : 1;
|
||||
uint32_t pDOP : 1;
|
||||
uint32_t versionNumber : 1;
|
||||
} moduleQueried;
|
||||
|
||||
struct
|
||||
{
|
||||
uint16_t all : 1;
|
||||
uint16_t timeOfWeek : 1;
|
||||
uint16_t highResLatitude : 1;
|
||||
uint16_t highResLongitude : 1;
|
||||
uint16_t elipsoid : 1;
|
||||
uint16_t meanSeaLevel : 1;
|
||||
uint16_t geoidSeparation : 1; // Redundant but kept for backward-compatibility
|
||||
uint16_t horizontalAccuracy : 1;
|
||||
uint16_t verticalAccuracy : 1;
|
||||
uint16_t elipsoidHp : 1;
|
||||
uint16_t meanSeaLevelHp : 1;
|
||||
uint16_t highResLatitudeHp : 1;
|
||||
uint16_t highResLongitudeHp : 1;
|
||||
} highResModuleQueried;
|
||||
|
||||
uint16_t rtcmLen = 0;
|
||||
};
|
||||
|
||||
#endif //SPARKFUN_UBLOX_ZEPHYR_LIBRARY_H
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
Reading lat, long and UTC time via UBX binary commands
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: August 22nd, 2018
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example reads the NMEA setences from the Ublox module over I2c and outputs
|
||||
them to the serial port
|
||||
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
I2C clock speed: 100 kHz
|
||||
|
||||
Ported to Zephyr by Vid Rajtmajer <vid@irnas.eu>, www.irnas.eu
|
||||
|
||||
Development environment specifics: NCS v1.0.3 release
|
||||
|
||||
To build: west build -b <BOARD_NAME> -p Can also read NMEA sentences over I2C with check_ublox function
|
||||
To flash: west flash --erase
|
||||
*/
|
||||
#include <device.h>
|
||||
#include <drivers/i2c.h>
|
||||
#include <errno.h>
|
||||
#include <zephyr.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include "SparkFun_Ublox_Zephyr_Interface.h"
|
||||
|
||||
|
||||
#define I2C_DEV "I2C_0"
|
||||
|
||||
struct device *gpio_dev;
|
||||
struct device *i2c_dev;
|
||||
/* I2C pins used are defaults for I2C_0 on nrf52840
|
||||
SDA: 26
|
||||
SCL: 27
|
||||
*/
|
||||
|
||||
uint8_t init_gpio(void) {
|
||||
const char* gpioName = "GPIO_0";
|
||||
gpio_dev = device_get_binding(gpioName);
|
||||
if (gpio_dev == NULL) {
|
||||
printk("Error: Could not get %s device\n", gpioName);
|
||||
return -EIO;
|
||||
}
|
||||
int err = set_gpio_dev(gpio_dev, true); // set GPIO_0 device and enable debugging
|
||||
if (err) {
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t init_i2c(void) {
|
||||
i2c_dev = device_get_binding(I2C_DEV);
|
||||
if (!i2c_dev)
|
||||
{
|
||||
printk("I2C_0 error\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("I2C_0 Init OK\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t init_gps(void) {
|
||||
if (gps_begin(i2c_dev) != 0)
|
||||
{
|
||||
printk("Ublox GPS init error!\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void main(void) {
|
||||
printk("Zephyr Ublox example\n");
|
||||
|
||||
int err;
|
||||
err = init_gpio();
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
err = init_i2c();
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
err = init_gps();
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
//check_ublox(); // See if new data is available. Process bytes as they come in.
|
||||
get_position();
|
||||
get_datetime();
|
||||
k_msleep(250); // Don't pound too hard on the I2C bus
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user