Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Commit e2ec849

Browse files
authored
Merge pull request #18 from FelixJirka/prepare_AutoPVT_PR
Update to AutoPVT functionality
2 parents 21b708a + a284616 commit e2ec849

File tree

5 files changed

+211
-1
lines changed

5 files changed

+211
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
Configuring the GPS to automatically send position reports over I2C, with explicit data parsing calls
3+
By: Nathan Seidle Thorsten von Eicken and Felix Jirka
4+
SparkFun Electronics
5+
Date: July 1st, 2019
6+
License: MIT. See license file for more information but you can
7+
basically do whatever you want with this code.
8+
9+
This example shows how to configure the U-Blox GPS the send navigation reports automatically
10+
and retrieving the latest one via checkUblox when available.
11+
This eliminates the implicit update in getPVT when accessing data fields twice.
12+
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).
13+
14+
This can be used over serial or over I2C, this example shows the I2C use. With serial the GPS
15+
simply outputs the UBX_NAV_PVT packet. With I2C it queues it into its internal I2C buffer (4KB in
16+
size?) where it can be retrieved in the next I2C poll.
17+
18+
Feel like supporting open source hardware?
19+
Buy a board from SparkFun!
20+
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
21+
NEO-M8P RTK: https://www.sparkfun.com/products/15005
22+
SAM-M8Q: https://www.sparkfun.com/products/15106
23+
24+
Hardware Connections:
25+
Plug a Qwiic cable into the GPS and a BlackBoard
26+
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
27+
Open the serial monitor at 115200 baud to see the output
28+
*/
29+
30+
#include <Wire.h> //Needed for I2C to GPS
31+
32+
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_Ublox_GPS
33+
SFE_UBLOX_GPS myGPS;
34+
35+
void setup()
36+
{
37+
Serial.begin(115200);
38+
while (!Serial); //Wait for user to open terminal
39+
Serial.println("SparkFun Ublox Example");
40+
41+
Wire.begin();
42+
43+
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
44+
{
45+
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
46+
while (1);
47+
}
48+
49+
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
50+
myGPS.setNavigationFrequency(2); //Produce two solutions per second
51+
myGPS.setAutoPVT(true, false); //Tell the GPS to "send" each solution and the lib not to update stale data implicitly
52+
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
53+
}
54+
55+
/*
56+
Calling getPVT would return false now (compare to Example 13 where it would return true), so we just use the data provided
57+
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
58+
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.
59+
Also you could oversample (10Hz - 20Hz) the data to smooth out such issues...
60+
*/
61+
void loop()
62+
{
63+
static uint16_t counter = 0;
64+
65+
if (counter % 10 == 0) {
66+
// update your AHRS filter here for a ~100Hz update rate
67+
// GPS data will be quasi static but data from your IMU will be changing
68+
}
69+
// debug output each half second
70+
if (counter % 500 == 0) {
71+
Serial.println();
72+
long latitude = myGPS.getLatitude();
73+
Serial.print(F("Lat: "));
74+
Serial.print(latitude);
75+
76+
long longitude = myGPS.getLongitude();
77+
Serial.print(F(" Long: "));
78+
Serial.print(longitude);
79+
Serial.print(F(" (degrees * 10^-7)"));
80+
81+
long altitude = myGPS.getAltitude();
82+
Serial.print(F(" Alt: "));
83+
Serial.print(altitude);
84+
Serial.print(F(" (mm)"));
85+
86+
byte SIV = myGPS.getSIV();
87+
Serial.print(F(" SIV: "));
88+
Serial.print(SIV);
89+
90+
Serial.println();
91+
}
92+
// call checkUblox all 50ms to capture the gps data
93+
if (counter % 50 == 0) {
94+
myGPS.checkUblox();
95+
}
96+
delay(1);
97+
counter++;
98+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
Reading lat and long via UBX binary commands using an RX-only UART
3+
By: Nathan Seidle, Adapted from Example11 by Felix Jirka
4+
SparkFun Electronics
5+
Date: July 2nd, 2019
6+
License: MIT. See license file for more information but you can
7+
basically do whatever you want with this code.
8+
9+
This example shows how to configure the library for serial port use with a single wire connection using the assumeAutoPVT method.
10+
Saving your pins for other stuff :-)
11+
12+
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
13+
14+
Feel like supporting open source hardware?
15+
Buy a board from SparkFun!
16+
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
17+
NEO-M8P RTK: https://www.sparkfun.com/products/15005
18+
SAM-M8Q: https://www.sparkfun.com/products/15106
19+
20+
Preconditions:
21+
U-Blox module is configured to send cyclical PVT message
22+
Hardware Connections:
23+
Connect the U-Blox serial TX pin to Rx of Serial2 (default: GPIO16) on your ESP32
24+
Open the serial monitor at 115200 baud to see the output
25+
*/
26+
27+
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS
28+
SFE_UBLOX_GPS myGPS;
29+
30+
void setup()
31+
{
32+
Serial.begin(115200);
33+
while (!Serial); //Wait for user to open terminal
34+
Serial.println("SparkFun Ublox Example 17");
35+
36+
//Use any Serial port with at least a Rx Pin connected or a receive only version of SoftwareSerial here
37+
//Assume that the U-Blox GPS is running at 9600 baud (the default)
38+
Serial2.begin(9600);
39+
// no need to check return value as internal call to isConnected() will not succeed
40+
myGPS.begin(Serial2);
41+
42+
// tell lib, we are expecting the module to send PVT messages by itself to our Rx pin
43+
// you can set second parameter to "false" if you want to control the parsing and eviction of the data (need to call checkUblox cyclically)
44+
myGPS.assumeAutoPVT(true, true);
45+
46+
}
47+
48+
void loop()
49+
{
50+
// if implicit updates are allowed, this will trigger parsing the incoming messages
51+
// and be true once a PVT message has been parsed
52+
// 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
53+
if (myGPS.getPVT())
54+
{
55+
long latitude = myGPS.getLatitude();
56+
Serial.print(F("Lat: "));
57+
Serial.print(latitude);
58+
59+
long longitude = myGPS.getLongitude();
60+
Serial.print(F(" Long: "));
61+
Serial.print(longitude);
62+
Serial.print(F(" (degrees * 10^-7)"));
63+
64+
long altitude = myGPS.getAltitude();
65+
Serial.print(F(" Alt: "));
66+
Serial.print(altitude);
67+
Serial.print(F(" (mm)"));
68+
69+
byte SIV = myGPS.getSIV();
70+
Serial.print(F(" SIV: "));
71+
Serial.print(SIV);
72+
73+
Serial.println();
74+
}
75+
else {
76+
Serial.println(F("Wait for GPS data"));
77+
delay(500);
78+
}
79+
}

Diff for: keywords.txt

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ debugPrintln KEYWORD2
8888

8989
factoryReset KEYWORD2
9090
setAutoPVT KEYWORD2
91+
assumeAutoPVT KEYWORD2
9192

9293
getYear KEYWORD2
9394
getMonth KEYWORD2

Diff for: src/SparkFun_Ublox_Arduino_Library.cpp

+30-1
Original file line numberDiff line numberDiff line change
@@ -1308,9 +1308,29 @@ uint8_t SFE_UBLOX_GPS::getNavigationFrequency(uint16_t maxWait)
13081308
return (measurementRate);
13091309
}
13101310

1311+
//In case no config access to the GPS is possible and PVT is send cyclically already
1312+
//set config to suitable parameters
1313+
boolean SFE_UBLOX_GPS::assumeAutoPVT(boolean enabled, boolean implicitUpdate)
1314+
{
1315+
boolean changes = autoPVT != enabled || autoPVTImplicitUpdate != implicitUpdate;
1316+
if(changes)
1317+
{
1318+
autoPVT = enabled;
1319+
autoPVTImplicitUpdate = implicitUpdate;
1320+
}
1321+
return changes;
1322+
}
1323+
13111324
//Enable or disable automatic navigation message generation by the GPS. This changes the way getPVT
13121325
//works.
13131326
boolean SFE_UBLOX_GPS::setAutoPVT(boolean enable, uint16_t maxWait)
1327+
{
1328+
return setAutoPVT(enable, true, maxWait);
1329+
}
1330+
1331+
//Enable or disable automatic navigation message generation by the GPS. This changes the way getPVT
1332+
//works.
1333+
boolean SFE_UBLOX_GPS::setAutoPVT(boolean enable, boolean implicitUpdate, uint16_t maxWait)
13141334
{
13151335
packetCfg.cls = UBX_CLASS_CFG;
13161336
packetCfg.id = UBX_CFG_MSG;
@@ -1322,7 +1342,10 @@ boolean SFE_UBLOX_GPS::setAutoPVT(boolean enable, uint16_t maxWait)
13221342

13231343
bool ok = sendCommand(packetCfg, maxWait);
13241344
if (ok)
1345+
{
13251346
autoPVT = enable;
1347+
autoPVTImplicitUpdate = implicitUpdate;
1348+
}
13261349
moduleQueried.all = false;
13271350
return ok;
13281351
}
@@ -1428,12 +1451,17 @@ int32_t SFE_UBLOX_GPS::getNanosecond(uint16_t maxWait)
14281451
//Get the latest Position/Velocity/Time solution and fill all global variables
14291452
boolean SFE_UBLOX_GPS::getPVT(uint16_t maxWait)
14301453
{
1431-
if (autoPVT)
1454+
if (autoPVT && autoPVTImplicitUpdate)
14321455
{
14331456
//The GPS is automatically reporting, we just check whether we got unread data
14341457
checkUblox();
14351458
return moduleQueried.all;
14361459
}
1460+
else if(autoPVT && !autoPVTImplicitUpdate)
1461+
{
1462+
//Someone else has to call checkUblox for us...
1463+
return (false);
1464+
}
14371465
else
14381466
{
14391467
//The GPS is not automatically reporting navigation position so we have to poll explicitly
@@ -1543,6 +1571,7 @@ uint32_t SFE_UBLOX_GPS::getPositionAccuracy(uint16_t maxWait)
15431571

15441572
return (tempAccuracy);
15451573
}
1574+
15461575
//Get the current latitude in degrees
15471576
//Returns a long representing the number of degrees *10^-7
15481577
int32_t SFE_UBLOX_GPS::getLatitude(uint16_t maxWait)

Diff for: src/SparkFun_Ublox_Arduino_Library.h

+3
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,10 @@ class SFE_UBLOX_GPS
234234

235235
boolean waitForResponse(uint8_t requestedClass, uint8_t requestedID, uint16_t maxTime = 250); //Poll the module until and ack is received
236236

237+
boolean assumeAutoPVT(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and PVT is send cyclically already
237238
boolean setAutoPVT(boolean enabled, uint16_t maxWait = 250); //Enable/disable automatic PVT reports at the navigation frequency
238239
boolean getPVT(uint16_t maxWait = 1000); //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.
240+
boolean setAutoPVT(boolean enabled, boolean implicitUpdate, uint16_t maxWait = 250); //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
239241
boolean getHPPOSLLH(uint16_t maxWait = 1000); //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.
240242

241243
int32_t getLatitude(uint16_t maxWait = 250); //Returns the current latitude in degrees * 10^-7. Auto selects between HighPrecision and Regular depending on ability of module.
@@ -435,6 +437,7 @@ class SFE_UBLOX_GPS
435437

436438
unsigned long lastCheck = 0;
437439
boolean autoPVT = false; //Whether autoPVT is enabled or not
440+
boolean autoPVTImplicitUpdate = true; // Whether autoPVT is triggered by accessing stale data (=true) or by a call to checkUblox (=false)
438441
boolean commandAck = false; //This goes true after we send a command and it's ack'd
439442
uint8_t ubxFrameCounter;
440443

0 commit comments

Comments
 (0)