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

Commit 3b5a81b

Browse files
authored
Merge pull request #56 from PaulZC/PaulZC_powerSaveMode
Added powerSaveMode (and some minor corrections)
2 parents ab0bf7a + 9024f2e commit 3b5a81b

File tree

4 files changed

+195
-3
lines changed

4 files changed

+195
-3
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
Power Save Mode
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 put the Ublox module into power save mode 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+
** When it is able to ** the module will reduce its current draw.
18+
For the ZOE-M8Q with a passive antenna, you should see the current drop
19+
from (approx.) 25-28mA to (approx.) 9mA when power save mode kicks in.
20+
21+
Note: this will fail on the ZED (protocol version >= 27) as UBX-CFG-RXM is not supported
22+
23+
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
24+
to something google maps understands simply divide the numbers by 10,000,000. We
25+
do this so that we don't have to use floating point numbers.
26+
27+
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
28+
29+
Feel like supporting open source hardware?
30+
Buy a board from SparkFun!
31+
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
32+
NEO-M8P RTK: https://www.sparkfun.com/products/15005
33+
SAM-M8Q: https://www.sparkfun.com/products/15106
34+
35+
Hardware Connections:
36+
Plug a Qwiic cable into the GPS and a BlackBoard
37+
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
38+
Open the serial monitor at 115200 baud to see the output
39+
*/
40+
41+
#include <Wire.h> //Needed for I2C to GPS
42+
43+
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS
44+
SFE_UBLOX_GPS myGPS;
45+
46+
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
47+
48+
void setup()
49+
{
50+
Serial.begin(115200);
51+
while (!Serial)
52+
; //Wait for user to open terminal
53+
Serial.println("SparkFun Ublox Example");
54+
55+
Wire.begin();
56+
57+
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
58+
{
59+
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
60+
while (1)
61+
;
62+
}
63+
64+
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages
65+
66+
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
67+
//myGPS.saveConfiguration(); //Uncomment this line to save the current settings to flash and BBR
68+
69+
Serial.println("Power save example.");
70+
Serial.println("1) Enable power saving");
71+
Serial.println("2) Disable power saving");
72+
}
73+
74+
void loop()
75+
{
76+
if (Serial.available())
77+
{
78+
byte incoming = Serial.read();
79+
80+
if (incoming == '1')
81+
{
82+
// Put the GNSS into power save mode
83+
// (If you want to disable power save mode, call myGPS.powerSaveMode(false) instead)
84+
// This will fail on the ZED (protocol version >= 27) as UBX-CFG-RXM is not supported
85+
if (myGPS.powerSaveMode())
86+
Serial.println(F("Power Save Mode enabled."));
87+
else
88+
Serial.println(F("***!!! Power Save Mode FAILED !!!***"));
89+
}
90+
else if (incoming == '2')
91+
{
92+
//Go to normal power mode (not power saving mode)
93+
if (myGPS.powerSaveMode(false))
94+
Serial.println(F("Power Save Mode disabled."));
95+
else
96+
Serial.println(F("***!!! Power Save Disable FAILED !!!***"));
97+
}
98+
}
99+
100+
//Query module every 10 seconds so it is easier to monitor the current draw
101+
if (millis() - lastTime > 10000)
102+
{
103+
lastTime = millis(); //Update the timer
104+
105+
byte fixType = myGPS.getFixType(); // Get the fix type
106+
Serial.print(F("Fix: "));
107+
Serial.print(fixType);
108+
if (fixType == 0)
109+
Serial.print(F("(No fix)"));
110+
else if (fixType == 1)
111+
Serial.print(F("(Dead reckoning)"));
112+
else if (fixType == 2)
113+
Serial.print(F("(2D)"));
114+
else if (fixType == 3)
115+
Serial.print(F("(3D)"));
116+
else if (fixType == 4)
117+
Serial.print(F("(GNSS + Dead reckoning)"));
118+
119+
long latitude = myGPS.getLatitude();
120+
Serial.print(F(" Lat: "));
121+
Serial.print(latitude);
122+
123+
long longitude = myGPS.getLongitude();
124+
Serial.print(F(" Long: "));
125+
Serial.print(longitude);
126+
Serial.print(F(" (degrees * 10^-7)"));
127+
128+
long altitude = myGPS.getAltitude();
129+
Serial.print(F(" Alt: "));
130+
Serial.print(altitude);
131+
Serial.print(F(" (mm)"));
132+
133+
Serial.println();
134+
}
135+
}

keywords.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ addGeofence KEYWORD2
125125
clearGeofences KEYWORD2
126126
getGeofenceState KEYWORD2
127127

128+
powerSaveMode KEYWORD2
129+
128130
#######################################
129131
# Constants (LITERAL1)
130132
#######################################

src/SparkFun_Ublox_Arduino_Library.cpp

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,6 +1789,53 @@ boolean SFE_UBLOX_GPS::getGeofenceState(geofenceState &currentGeofenceState, uin
17891789
return(true);
17901790
}
17911791

1792+
//Power Save Mode
1793+
//Enables/Disables Low Power Mode using UBX-CFG-RXM
1794+
boolean SFE_UBLOX_GPS::powerSaveMode(bool power_save, uint16_t maxWait)
1795+
{
1796+
// Let's begin by checking the Protocol Version as UBX_CFG_RXM is not supported on the ZED (protocol >= 27)
1797+
uint8_t protVer = getProtocolVersionHigh(maxWait);
1798+
/*
1799+
if (_printDebug == true)
1800+
{
1801+
_debugSerial->print("Protocol version is ");
1802+
_debugSerial->println(protVer);
1803+
}
1804+
*/
1805+
if (protVer >= 27)
1806+
{
1807+
debugPrintln((char *)"powerSaveMode (UBX-CFG-RXM) is not supported by this protocol version");
1808+
return (false);
1809+
}
1810+
1811+
// Now let's change the power setting using UBX-CFG-RXM
1812+
packetCfg.cls = UBX_CLASS_CFG;
1813+
packetCfg.id = UBX_CFG_RXM;
1814+
packetCfg.len = 0;
1815+
packetCfg.startingSpot = 0;
1816+
1817+
if (sendCommand(packetCfg, maxWait) == false) //Ask module for the current power management settings. Loads into payloadCfg.
1818+
return (false);
1819+
1820+
// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
1821+
// This is only required because we are doing two sendCommands in quick succession using the same class and ID
1822+
waitForResponse(UBX_CLASS_CFG, UBX_CFG_RXM, 100); // But we'll only wait for 100msec max
1823+
1824+
if (power_save)
1825+
{
1826+
payloadCfg[1] = 1; // Power Save Mode
1827+
}
1828+
else
1829+
{
1830+
payloadCfg[1] = 0; // Continuous Mode
1831+
}
1832+
1833+
packetCfg.len = 2;
1834+
packetCfg.startingSpot = 0;
1835+
1836+
return (sendCommand(packetCfg, maxWait)); //Wait for ack
1837+
}
1838+
17921839
//Given a spot in the payload array, extract four bytes and build a long
17931840
uint32_t SFE_UBLOX_GPS::extractLong(uint8_t spotToStart)
17941841
{
@@ -2133,7 +2180,7 @@ uint16_t SFE_UBLOX_GPS::getPDOP(uint16_t maxWait)
21332180
uint8_t SFE_UBLOX_GPS::getProtocolVersionHigh(uint16_t maxWait)
21342181
{
21352182
if (moduleQueried.versionNumber == false)
2136-
getProtocolVersion();
2183+
getProtocolVersion(maxWait);
21372184
moduleQueried.versionNumber = false;
21382185
return (versionHigh);
21392186
}
@@ -2143,7 +2190,7 @@ uint8_t SFE_UBLOX_GPS::getProtocolVersionHigh(uint16_t maxWait)
21432190
uint8_t SFE_UBLOX_GPS::getProtocolVersionLow(uint16_t maxWait)
21442191
{
21452192
if (moduleQueried.versionNumber == false)
2146-
getProtocolVersion();
2193+
getProtocolVersion(maxWait);
21472194
moduleQueried.versionNumber = false;
21482195
return (versionLow);
21492196
}
@@ -2166,6 +2213,10 @@ boolean SFE_UBLOX_GPS::getProtocolVersion(uint16_t maxWait)
21662213
if (sendCommand(packetCfg, maxWait) == false)
21672214
return (false); //If command send fails then bail
21682215

2216+
// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
2217+
// This is only required because we are doing multiple sendCommands in quick succession using the same class and ID
2218+
waitForResponse(UBX_CLASS_MON, UBX_MON_VER, 100); // But we'll only wait for 100msec max
2219+
21692220
if (_printDebug == true)
21702221
{
21712222
_debugSerial->print("Extension ");
@@ -2185,7 +2236,7 @@ boolean SFE_UBLOX_GPS::getProtocolVersion(uint16_t maxWait)
21852236
{
21862237
versionHigh = (payloadCfg[8] - '0') * 10 + (payloadCfg[9] - '0'); //Convert '18' to 18
21872238
versionLow = (payloadCfg[11] - '0') * 10 + (payloadCfg[12] - '0'); //Convert '00' to 00
2188-
return (versionLow);
2239+
return (true); // This function returns a boolean (so we can't return versionLow)
21892240
}
21902241
}
21912242

src/SparkFun_Ublox_Arduino_Library.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ const uint8_t UBX_CFG_PRT = 0x00; //Used to configure port specifics
9999
const uint8_t UBX_CFG_RST = 0x04; //Used to reset device
100100
const uint8_t UBX_CFG_RATE = 0x08; //Used to set port baud rates
101101
const uint8_t UBX_CFG_CFG = 0x09; //Used to save current configuration
102+
const uint8_t UBX_CFG_RXM = 0x11; //Used to set receiver power management (power save mode)
102103
const uint8_t UBX_CFG_VALSET = 0x8A; //Used for config of higher version Ublox modules (ie protocol v27 and above)
103104
const uint8_t UBX_CFG_VALGET = 0x8B; //Used for config of higher version Ublox modules (ie protocol v27 and above)
104105
const uint8_t UBX_CFG_VALDEL = 0x8C; //Used for config of higher version Ublox modules (ie protocol v27 and above)
@@ -344,6 +345,9 @@ class SFE_UBLOX_GPS
344345
boolean clearGeofences(uint16_t maxWait = 2000); //Clears all geofences
345346
boolean getGeofenceState(geofenceState &currentGeofenceState, uint16_t maxWait = 2000); //Returns the combined geofence state
346347

348+
//Power Save Mode
349+
boolean powerSaveMode(bool power_save = true, uint16_t maxWait = 2000);
350+
347351
//Survey-in specific controls
348352
struct svinStructure
349353
{

0 commit comments

Comments
 (0)