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

Commit 1d1e748

Browse files
authored
Merge pull request #57 from PaulZC/PaulZC_setDynamicModel
Added setDynamicModel (and made some minor corrections)
2 parents e206243 + 07fba62 commit 1d1e748

File tree

4 files changed

+166
-5
lines changed

4 files changed

+166
-5
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
Set Dynamic Model
3+
By: Paul Clark (PaulZC)
4+
Date: December 18th, 2019
5+
6+
Based extensively on Example3_GetPosition
7+
By: Nathan Seidle
8+
SparkFun Electronics
9+
Date: January 3rd, 2019
10+
License: MIT. See license file for more information but you can
11+
basically do whatever you want with this code.
12+
13+
This example shows how to change the Ublox module's dynamic platform model and then
14+
query its lat/long/altitude. We also turn off the NMEA output on the I2C port.
15+
This decreases the amount of I2C traffic dramatically.
16+
17+
Possible values for the dynamic model are: PORTABLE, STATIONARY, PEDESTRIAN, AUTOMOTIVE,
18+
SEA, AIRBORNE1g, AIRBORNE2g, AIRBORNE4g, WRIST, BIKE
19+
20+
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
21+
to something google maps understands simply divide the numbers by 10,000,000. We
22+
do this so that we don't have to use floating point numbers.
23+
24+
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
25+
26+
Feel like supporting open source hardware?
27+
Buy a board from SparkFun!
28+
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
29+
NEO-M8P RTK: https://www.sparkfun.com/products/15005
30+
SAM-M8Q: https://www.sparkfun.com/products/15106
31+
32+
Hardware Connections:
33+
Plug a Qwiic cable into the GPS and a BlackBoard
34+
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
35+
Open the serial monitor at 115200 baud to see the output
36+
*/
37+
38+
#include <Wire.h> //Needed for I2C to GPS
39+
40+
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS
41+
SFE_UBLOX_GPS myGPS;
42+
43+
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
44+
45+
void setup()
46+
{
47+
Serial.begin(115200);
48+
while (!Serial); //Wait for user to open terminal
49+
Serial.println("SparkFun Ublox Example");
50+
51+
Wire.begin();
52+
53+
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
54+
{
55+
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
56+
while (1);
57+
}
58+
59+
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages
60+
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
61+
62+
// If we are going to change the dynamic platform model, let's do it here.
63+
// Possible values are:
64+
// PORTABLE, STATIONARY, PEDESTRIAN, AUTOMOTIVE, SEA, AIRBORNE1g, AIRBORNE2g, AIRBORNE4g, WRIST, BIKE
65+
66+
if (!myGPS.setDynamicModel(myGPS.PORTABLE)) // Set the dynamic model to PORTABLE
67+
{
68+
Serial.println("***!!! Warning: setDynamicModel failed !!!***");
69+
}
70+
else
71+
{
72+
Serial.println("Dynamic platform model changed successfully!");
73+
}
74+
75+
//myGPS.saveConfiguration(); //Uncomment this line to save the current settings to flash and BBR
76+
}
77+
78+
void loop()
79+
{
80+
//Query module only every second. Doing it more often will just cause I2C traffic.
81+
//The module only responds when a new position is available
82+
if (millis() - lastTime > 1000)
83+
{
84+
lastTime = millis(); //Update the timer
85+
86+
long latitude = myGPS.getLatitude();
87+
Serial.print(F("Lat: "));
88+
Serial.print(latitude);
89+
90+
long longitude = myGPS.getLongitude();
91+
Serial.print(F(" Long: "));
92+
Serial.print(longitude);
93+
Serial.print(F(" (degrees * 10^-7)"));
94+
95+
long altitude = myGPS.getAltitude();
96+
Serial.print(F(" Alt: "));
97+
Serial.print(altitude);
98+
Serial.print(F(" (mm)"));
99+
100+
Serial.println();
101+
}
102+
}

keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ addGeofence KEYWORD2
126126
clearGeofences KEYWORD2
127127
getGeofenceState KEYWORD2
128128

129+
setDynamicModel KEYWORD2
129130
powerSaveMode KEYWORD2
130131

131132
configureMessage KEYWORD2

src/SparkFun_Ublox_Arduino_Library.cpp

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,15 @@ void SFE_UBLOX_GPS::setSerialRate(uint32_t baudrate, uint8_t uartPort, uint16_t
164164
_debugSerial->println(((uint32_t)payloadCfg[10] << 16) | ((uint32_t)payloadCfg[9] << 8) | payloadCfg[8]);
165165
}
166166

167-
sendCommand(packetCfg);
167+
sendCommand(packetCfg, maxWait);
168168
}
169169

170170
//Changes the I2C address that the Ublox module responds to
171171
//0x42 is the default but can be changed with this command
172172
boolean SFE_UBLOX_GPS::setI2CAddress(uint8_t deviceAddress, uint16_t maxWait)
173173
{
174174
//Get the current config values for the I2C port
175-
getPortSettings(COM_PORT_I2C); //This will load the payloadCfg array with current port settings
175+
getPortSettings(COM_PORT_I2C, maxWait); //This will load the payloadCfg array with current port settings
176176

177177
packetCfg.cls = UBX_CLASS_CFG;
178178
packetCfg.id = UBX_CFG_PRT;
@@ -1361,7 +1361,7 @@ boolean SFE_UBLOX_GPS::getSurveyMode(uint16_t maxWait)
13611361
//Control Survey-In for NEO-M8P
13621362
boolean SFE_UBLOX_GPS::setSurveyMode(uint8_t mode, uint16_t observationTime, float requiredAccuracy, uint16_t maxWait)
13631363
{
1364-
if (getSurveyMode() == false) //Ask module for the current TimeMode3 settings. Loads into payloadCfg.
1364+
if (getSurveyMode(maxWait) == false) //Ask module for the current TimeMode3 settings. Loads into payloadCfg.
13651365
return (false);
13661366

13671367
packetCfg.cls = UBX_CLASS_CFG;
@@ -1449,9 +1449,13 @@ boolean SFE_UBLOX_GPS::getPortSettings(uint8_t portID, uint16_t maxWait)
14491449
boolean SFE_UBLOX_GPS::setPortOutput(uint8_t portID, uint8_t outStreamSettings, uint16_t maxWait)
14501450
{
14511451
//Get the current config values for this port ID
1452-
if (getPortSettings(portID) == false)
1452+
if (getPortSettings(portID, maxWait) == false)
14531453
return (false); //Something went wrong. Bail.
14541454

1455+
// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
1456+
// This is only required because we are doing two sendCommands in quick succession using the same class and ID
1457+
waitForResponse(UBX_CLASS_CFG, UBX_CFG_PRT, 100); // But we'll only wait for 100msec max
1458+
14551459
//Yes, this is the depreciated way to do it but it's still supported on v27 so it
14561460
//covers both ZED-F9P (v27) and SAM-M8Q (v18)
14571461

@@ -1473,9 +1477,13 @@ boolean SFE_UBLOX_GPS::setPortInput(uint8_t portID, uint8_t inStreamSettings, ui
14731477
{
14741478
//Get the current config values for this port ID
14751479
//This will load the payloadCfg array with current port settings
1476-
if (getPortSettings(portID) == false)
1480+
if (getPortSettings(portID, maxWait) == false)
14771481
return (false); //Something went wrong. Bail.
14781482

1483+
// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
1484+
// This is only required because we are doing two sendCommands in quick succession using the same class and ID
1485+
waitForResponse(UBX_CLASS_CFG, UBX_CFG_PRT, 100); // But we'll only wait for 100msec max
1486+
14791487
packetCfg.cls = UBX_CLASS_CFG;
14801488
packetCfg.id = UBX_CFG_PRT;
14811489
packetCfg.len = 20;
@@ -1870,6 +1878,36 @@ boolean SFE_UBLOX_GPS::powerSaveMode(bool power_save, uint16_t maxWait)
18701878
return (sendCommand(packetCfg, maxWait)); //Wait for ack
18711879
}
18721880

1881+
//Change the dynamic platform model using UBX-CFG-NAV5
1882+
//Possible values are:
1883+
//PORTABLE,STATIONARY,PEDESTRIAN,AUTOMOTIVE,SEA,
1884+
//AIRBORNE1g,AIRBORNE2g,AIRBORNE4g,WRIST,BIKE
1885+
//WRIST is not supported in protocol versions less than 18
1886+
//BIKE is supported in protocol versions 19.2
1887+
boolean SFE_UBLOX_GPS::setDynamicModel(uint8_t newDynamicModel, uint16_t maxWait)
1888+
{
1889+
packetCfg.cls = UBX_CLASS_CFG;
1890+
packetCfg.id = UBX_CFG_NAV5;
1891+
packetCfg.len = 0;
1892+
packetCfg.startingSpot = 0;
1893+
1894+
if (sendCommand(packetCfg, maxWait) == false) //Ask module for the current navigation model settings. Loads into payloadCfg.
1895+
return (false);
1896+
1897+
// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
1898+
// This is only required because we are doing two sendCommands in quick succession using the same class and ID
1899+
waitForResponse(UBX_CLASS_CFG, UBX_CFG_NAV5, 100); // But we'll only wait for 100msec max
1900+
1901+
payloadCfg[0] = 0x01; // mask: set only the dyn bit (0)
1902+
payloadCfg[1] = 0x00; // mask
1903+
payloadCfg[2] = newDynamicModel; // dynModel
1904+
1905+
packetCfg.len = 36;
1906+
packetCfg.startingSpot = 0;
1907+
1908+
return (sendCommand(packetCfg, maxWait)); //Wait for ack
1909+
}
1910+
18731911
//Given a spot in the payload array, extract four bytes and build a long
18741912
uint32_t SFE_UBLOX_GPS::extractLong(uint8_t spotToStart)
18751913
{

src/SparkFun_Ublox_Arduino_Library.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ const uint8_t UBX_CFG_RST = 0x04; //Used to reset device
101101
const uint8_t UBX_CFG_RATE = 0x08; //Used to set port baud rates
102102
const uint8_t UBX_CFG_CFG = 0x09; //Used to save current configuration
103103
const uint8_t UBX_CFG_RXM = 0x11; //Used to set receiver power management (power save mode)
104+
const uint8_t UBX_CFG_NAV5 = 0x24; //Used to configure the navigation engine including the dynamic model
105+
104106
const uint8_t UBX_CFG_VALSET = 0x8A; //Used for config of higher version Ublox modules (ie protocol v27 and above)
105107
const uint8_t UBX_CFG_VALGET = 0x8B; //Used for config of higher version Ublox modules (ie protocol v27 and above)
106108
const uint8_t UBX_CFG_VALDEL = 0x8C; //Used for config of higher version Ublox modules (ie protocol v27 and above)
@@ -370,6 +372,9 @@ class SFE_UBLOX_GPS
370372

371373
boolean powerSaveMode(bool power_save = true, uint16_t maxWait = 2000);
372374

375+
//Change the dynamic platform model using UBX-CFG-NAV5
376+
boolean setDynamicModel(uint8_t newDynamicModel = PEDESTRIAN, uint16_t maxWait = 2000);
377+
373378
//Survey-in specific controls
374379
struct svinStructure
375380
{
@@ -443,6 +448,21 @@ class SFE_UBLOX_GPS
443448

444449
uint16_t rtcmFrameCounter = 0; //Tracks the type of incoming byte inside RTCM frame
445450

451+
enum dynModel // Possible values for the dynamic platform model
452+
{
453+
PORTABLE = 0,
454+
// 1 is not defined
455+
STATIONARY = 2,
456+
PEDESTRIAN,
457+
AUTOMOTIVE,
458+
SEA,
459+
AIRBORNE1g,
460+
AIRBORNE2g,
461+
AIRBORNE4g,
462+
WRIST, // Not supported in protocol versions less than 18
463+
BIKE // Supported in protocol versions 19.2
464+
};
465+
446466
private:
447467
//Depending on the sentence type the processor will load characters into different arrays
448468
enum SentenceTypes

0 commit comments

Comments
 (0)