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

Added powerSaveMode (and some minor corrections) #56

Merged
merged 5 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
135 changes: 135 additions & 0 deletions examples/Example19_PowerSaveMode/Example19_PowerSaveMode.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
Power Save Mode
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 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_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)
//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())
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 !!!***"));
}
}

//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();
}
}
2 changes: 2 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ addGeofence KEYWORD2
clearGeofences KEYWORD2
getGeofenceState KEYWORD2

powerSaveMode KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
Expand Down
57 changes: 54 additions & 3 deletions src/SparkFun_Ublox_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,53 @@ boolean SFE_UBLOX_GPS::getGeofenceState(geofenceState &currentGeofenceState, uin
return(true);
}

//Power Save Mode
//Enables/Disables Low Power Mode using UBX-CFG-RXM
boolean SFE_UBLOX_GPS::powerSaveMode(bool power_save, uint16_t maxWait)
{
// Let's begin by checking the Protocol Version as UBX_CFG_RXM is not supported on the ZED (protocol >= 27)
uint8_t protVer = getProtocolVersionHigh(maxWait);
/*
if (_printDebug == true)
{
_debugSerial->print("Protocol version is ");
_debugSerial->println(protVer);
}
*/
if (protVer >= 27)
{
debugPrintln((char *)"powerSaveMode (UBX-CFG-RXM) is not supported by this protocol version");
return (false);
}

// Now let's change the power setting using UBX-CFG-RXM
packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_RXM;
packetCfg.len = 0;
packetCfg.startingSpot = 0;

if (sendCommand(packetCfg, maxWait) == false) //Ask module for the current power management 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_RXM, 100); // But we'll only wait for 100msec max

if (power_save)
{
payloadCfg[1] = 1; // Power Save Mode
}
else
{
payloadCfg[1] = 0; // Continuous Mode
}

packetCfg.len = 2;
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 Expand Up @@ -2133,7 +2180,7 @@ uint16_t SFE_UBLOX_GPS::getPDOP(uint16_t maxWait)
uint8_t SFE_UBLOX_GPS::getProtocolVersionHigh(uint16_t maxWait)
{
if (moduleQueried.versionNumber == false)
getProtocolVersion();
getProtocolVersion(maxWait);
moduleQueried.versionNumber = false;
return (versionHigh);
}
Expand All @@ -2143,7 +2190,7 @@ uint8_t SFE_UBLOX_GPS::getProtocolVersionHigh(uint16_t maxWait)
uint8_t SFE_UBLOX_GPS::getProtocolVersionLow(uint16_t maxWait)
{
if (moduleQueried.versionNumber == false)
getProtocolVersion();
getProtocolVersion(maxWait);
moduleQueried.versionNumber = false;
return (versionLow);
}
Expand All @@ -2166,6 +2213,10 @@ boolean SFE_UBLOX_GPS::getProtocolVersion(uint16_t maxWait)
if (sendCommand(packetCfg, maxWait) == false)
return (false); //If command send fails then 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 multiple sendCommands in quick succession using the same class and ID
waitForResponse(UBX_CLASS_MON, UBX_MON_VER, 100); // But we'll only wait for 100msec max

if (_printDebug == true)
{
_debugSerial->print("Extension ");
Expand All @@ -2185,7 +2236,7 @@ boolean SFE_UBLOX_GPS::getProtocolVersion(uint16_t maxWait)
{
versionHigh = (payloadCfg[8] - '0') * 10 + (payloadCfg[9] - '0'); //Convert '18' to 18
versionLow = (payloadCfg[11] - '0') * 10 + (payloadCfg[12] - '0'); //Convert '00' to 00
return (versionLow);
return (true); // This function returns a boolean (so we can't return versionLow)
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/SparkFun_Ublox_Arduino_Library.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ const uint8_t UBX_CFG_PRT = 0x00; //Used to configure port specifics
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_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 @@ -344,6 +345,9 @@ class SFE_UBLOX_GPS
boolean clearGeofences(uint16_t maxWait = 2000); //Clears all geofences
boolean getGeofenceState(geofenceState &currentGeofenceState, uint16_t maxWait = 2000); //Returns the combined geofence state

//Power Save Mode
boolean powerSaveMode(bool power_save = true, uint16_t maxWait = 2000);

//Survey-in specific controls
struct svinStructure
{
Expand Down