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

Added setDynamicModel (and made some minor corrections) #57

Merged
merged 2 commits into from
Dec 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions examples/Example20_DynamicModel/Example20_DynamicModel.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
Set Dynamic Model
By: Paul Clark (PaulZC)
Date: December 18th, 2019

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_Ublox_GPS
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)

// 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(myGPS.PORTABLE)) // Set the dynamic model to PORTABLE
{
Serial.println("***!!! Warning: setDynamicModel failed !!!***");
}
else
{
Serial.println("Dynamic platform model changed successfully!");
}

//myGPS.saveConfiguration(); //Uncomment this line to 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.println();
}
}
1 change: 1 addition & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ addGeofence KEYWORD2
clearGeofences KEYWORD2
getGeofenceState KEYWORD2

setDynamicModel KEYWORD2
powerSaveMode KEYWORD2

configureMessage KEYWORD2
Expand Down
48 changes: 43 additions & 5 deletions src/SparkFun_Ublox_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,15 @@ void SFE_UBLOX_GPS::setSerialRate(uint32_t baudrate, uint8_t uartPort, uint16_t
_debugSerial->println(((uint32_t)payloadCfg[10] << 16) | ((uint32_t)payloadCfg[9] << 8) | payloadCfg[8]);
}

sendCommand(packetCfg);
sendCommand(packetCfg, maxWait);
}

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

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

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

// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
// This is only required because we are doing two sendCommands in quick succession using the same class and ID
waitForResponse(UBX_CLASS_CFG, UBX_CFG_PRT, 100); // But we'll only wait for 100msec max

//Yes, this is the depreciated way to do it but it's still supported on v27 so it
//covers both ZED-F9P (v27) and SAM-M8Q (v18)

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

// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
// This is only required because we are doing two sendCommands in quick succession using the same class and ID
waitForResponse(UBX_CLASS_CFG, UBX_CFG_PRT, 100); // But we'll only wait for 100msec max

packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_PRT;
packetCfg.len = 20;
Expand Down Expand Up @@ -1870,6 +1878,36 @@ boolean SFE_UBLOX_GPS::powerSaveMode(bool power_save, uint16_t maxWait)
return (sendCommand(packetCfg, maxWait)); //Wait for ack
}

//Change the dynamic platform model using UBX-CFG-NAV5
//Possible values are:
//PORTABLE,STATIONARY,PEDESTRIAN,AUTOMOTIVE,SEA,
//AIRBORNE1g,AIRBORNE2g,AIRBORNE4g,WRIST,BIKE
//WRIST is not supported in protocol versions less than 18
//BIKE is supported in protocol versions 19.2
boolean SFE_UBLOX_GPS::setDynamicModel(uint8_t newDynamicModel, uint16_t maxWait)
{
packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_NAV5;
packetCfg.len = 0;
packetCfg.startingSpot = 0;

if (sendCommand(packetCfg, maxWait) == false) //Ask module for the current navigation model settings. Loads into payloadCfg.
return (false);

// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
// This is only required because we are doing two sendCommands in quick succession using the same class and ID
waitForResponse(UBX_CLASS_CFG, UBX_CFG_NAV5, 100); // But we'll only wait for 100msec max

payloadCfg[0] = 0x01; // mask: set only the dyn bit (0)
payloadCfg[1] = 0x00; // mask
payloadCfg[2] = newDynamicModel; // dynModel

packetCfg.len = 36;
packetCfg.startingSpot = 0;

return (sendCommand(packetCfg, maxWait)); //Wait for ack
}

//Given a spot in the payload array, extract four bytes and build a long
uint32_t SFE_UBLOX_GPS::extractLong(uint8_t spotToStart)
{
Expand Down
20 changes: 20 additions & 0 deletions src/SparkFun_Ublox_Arduino_Library.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ const uint8_t UBX_CFG_RST = 0x04; //Used to reset device
const uint8_t UBX_CFG_RATE = 0x08; //Used to set port baud rates
const uint8_t UBX_CFG_CFG = 0x09; //Used to save current configuration
const uint8_t UBX_CFG_RXM = 0x11; //Used to set receiver power management (power save mode)
const uint8_t UBX_CFG_NAV5 = 0x24; //Used to configure the navigation engine including the dynamic model

const uint8_t UBX_CFG_VALSET = 0x8A; //Used for config of higher version Ublox modules (ie protocol v27 and above)
const uint8_t UBX_CFG_VALGET = 0x8B; //Used for config of higher version Ublox modules (ie protocol v27 and above)
const uint8_t UBX_CFG_VALDEL = 0x8C; //Used for config of higher version Ublox modules (ie protocol v27 and above)
Expand Down Expand Up @@ -370,6 +372,9 @@ class SFE_UBLOX_GPS

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

//Change the dynamic platform model using UBX-CFG-NAV5
boolean setDynamicModel(uint8_t newDynamicModel = PEDESTRIAN, uint16_t maxWait = 2000);

//Survey-in specific controls
struct svinStructure
{
Expand Down Expand Up @@ -443,6 +448,21 @@ class SFE_UBLOX_GPS

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

enum dynModel // Possible values for the dynamic platform model
{
PORTABLE = 0,
// 1 is not defined
STATIONARY = 2,
PEDESTRIAN,
AUTOMOTIVE,
SEA,
AIRBORNE1g,
AIRBORNE2g,
AIRBORNE4g,
WRIST, // Not supported in protocol versions less than 18
BIKE // Supported in protocol versions 19.2
};

private:
//Depending on the sentence type the processor will load characters into different arrays
enum SentenceTypes
Expand Down