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

Commit c0abfe6

Browse files
authored
Merge pull request #116 from unsurv/master
implemented Power On/Off (UBX-RXM-PMREQ)
2 parents cd6b4dc + 8c8ee4b commit c0abfe6

File tree

4 files changed

+221
-0
lines changed

4 files changed

+221
-0
lines changed

Diff for: examples/Example22_PowerOff/Example22_PowerOff.ino

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
Powering off a ublox GPS module
3+
By: bjorn
4+
unsurv.org
5+
Date: July 20th, 2020
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 you how to turn off the ublox module to lower the power consumption.
10+
There are two functions: one just specifies a duration in milliseconds the other also specifies a pin on the GPS device to wake it up with.
11+
By driving a voltage from LOW to HIGH or HIGH to LOW on the chosen module pin you wake the device back up.
12+
Note: Doing so on the INT0 pin when using the regular powerOff(durationInMs) function will wake the device anyway. (tested on SAM-M8Q)
13+
Note: While powered off, you should not query the device for data or it might wake up. This can be used to wake the device but is not recommended.
14+
Works best when also putting your microcontroller to sleep.
15+
16+
Feel like supporting open source hardware?
17+
Buy a board from SparkFun!
18+
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
19+
NEO-M8P RTK: https://www.sparkfun.com/products/15005
20+
SAM-M8Q: https://www.sparkfun.com/products/15106
21+
22+
Hardware Connections:
23+
Plug a Qwiic cable into the GPS and a BlackBoard.
24+
To force the device to wake up you need to connect to a pin (for example INT0) seperately on the module.
25+
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
26+
Open the serial monitor at 115200 baud to see the output
27+
*/
28+
29+
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS
30+
SFE_UBLOX_GPS myGPS;
31+
32+
// define a digital pin capable of driving HIGH and LOW
33+
#define WAKEUP_PIN 5
34+
35+
// Possible GNSS interrupt pins for powerOffWithInterrupt are:
36+
// VAL_RXM_PMREQ_WAKEUPSOURCE_UARTRX = uartrx
37+
// VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0 = extint0 (default)
38+
// VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT1 = extint1
39+
// VAL_RXM_PMREQ_WAKEUPSOURCE_SPICS = spics
40+
// These values can be or'd (|) together to enable interrupts on multiple pins
41+
42+
void wakeUp() {
43+
44+
Serial.print("-- waking up module via pin " + String(WAKEUP_PIN));
45+
Serial.println(" on your microcontroller --");
46+
47+
digitalWrite(WAKEUP_PIN, LOW);
48+
delay(1000);
49+
digitalWrite(WAKEUP_PIN, HIGH);
50+
delay(1000);
51+
digitalWrite(WAKEUP_PIN, LOW);
52+
}
53+
54+
55+
void setup() {
56+
57+
pinMode(WAKEUP_PIN, OUTPUT);
58+
digitalWrite(WAKEUP_PIN, LOW);
59+
60+
Serial.begin(115200);
61+
while (!Serial); //Wait for user to open terminal
62+
Serial.println("SparkFun Ublox Example");
63+
64+
Wire.begin();
65+
66+
//myGPS.enableDebugging(); // Enable debug messages
67+
68+
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
69+
{
70+
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
71+
while (1);
72+
}
73+
74+
// Powering off for 20s, you should see the power consumption drop.
75+
Serial.println("-- Powering off module for 20s --");
76+
77+
myGPS.powerOff(20000);
78+
//myGPS.powerOffWithInterrupt(20000, VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0);
79+
80+
delay(10000);
81+
82+
// After 10 seconds wake the device via the specified pin on your microcontroller and module.
83+
wakeUp();
84+
}
85+
86+
void loop() {
87+
//Do nothing
88+
}

Diff for: keywords.txt

+2
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ setDynamicModel KEYWORD2
139139
getDynamicModel KEYWORD2
140140
powerSaveMode KEYWORD2
141141
getPowerSaveMode KEYWORD2
142+
powerOff KEYWORD2
143+
powerOffWithInterrupt KEYWORD2
142144

143145
configureMessage KEYWORD2
144146
enableMessage KEYWORD2

Diff for: src/SparkFun_Ublox_Arduino_Library.cpp

+123
Original file line numberDiff line numberDiff line change
@@ -2569,6 +2569,129 @@ uint8_t SFE_UBLOX_GPS::getPowerSaveMode(uint16_t maxWait)
25692569
return (payloadCfg[1]); // Return the low power mode
25702570
}
25712571

2572+
// Powers off the GPS device for a given duration to reduce power consumption.
2573+
// NOTE: Querying the device before the duration is complete, for example by "getLatitude()" will wake it up!
2574+
// Returns true if command has not been not acknowledged.
2575+
// Returns false if command has not been acknowledged or maxWait = 0.
2576+
boolean SFE_UBLOX_GPS::powerOff(uint32_t durationInMs, uint16_t maxWait)
2577+
{
2578+
// use durationInMs = 0 for infinite duration
2579+
if (_printDebug == true)
2580+
{
2581+
_debugSerial->print(F("Powering off for "));
2582+
_debugSerial->print(durationInMs);
2583+
_debugSerial->println(" ms");
2584+
}
2585+
2586+
// Power off device using UBX-RXM-PMREQ
2587+
packetCfg.cls = UBX_CLASS_RXM; // 0x02
2588+
packetCfg.id = UBX_RXM_PMREQ; // 0x41
2589+
packetCfg.len = 8;
2590+
packetCfg.startingSpot = 0;
2591+
2592+
// duration
2593+
// big endian to little endian, switch byte order
2594+
payloadCfg[0] = (durationInMs >> (8*0)) & 0xff;
2595+
payloadCfg[1] = (durationInMs >> (8*1)) & 0xff;
2596+
payloadCfg[2] = (durationInMs >> (8*2)) & 0xff;
2597+
payloadCfg[3] = (durationInMs >> (8*3)) & 0xff;
2598+
2599+
payloadCfg[4] = 0x02; //Flags : set the backup bit
2600+
payloadCfg[5] = 0x00; //Flags
2601+
payloadCfg[6] = 0x00; //Flags
2602+
payloadCfg[7] = 0x00; //Flags
2603+
2604+
if (maxWait != 0)
2605+
{
2606+
// check for "not acknowledged" command
2607+
return (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_COMMAND_NACK);
2608+
}
2609+
else
2610+
{
2611+
sendCommand(&packetCfg, maxWait);
2612+
return false; // can't tell if command not acknowledged if maxWait = 0
2613+
}
2614+
}
2615+
2616+
// Powers off the GPS device for a given duration to reduce power consumption.
2617+
// While powered off it can be woken up by creating a falling or rising voltage edge on the specified pin.
2618+
// NOTE: The GPS seems to be sensitve to signals on the pins while powered off. Works best when Microcontroller is in deepsleep.
2619+
// NOTE: Querying the device before the duration is complete, for example by "getLatitude()" will wake it up!
2620+
// Returns true if command has not been not acknowledged.
2621+
// Returns false if command has not been acknowledged or maxWait = 0.
2622+
boolean SFE_UBLOX_GPS::powerOffWithInterrupt(uint32_t durationInMs, uint32_t wakeupSources, boolean forceWhileUsb, uint16_t maxWait)
2623+
{
2624+
// use durationInMs = 0 for infinite duration
2625+
if (_printDebug == true)
2626+
{
2627+
_debugSerial->print(F("Powering off for "));
2628+
_debugSerial->print(durationInMs);
2629+
_debugSerial->println(" ms");
2630+
}
2631+
2632+
// Power off device using UBX-RXM-PMREQ
2633+
packetCfg.cls = UBX_CLASS_RXM; // 0x02
2634+
packetCfg.id = UBX_RXM_PMREQ; // 0x41
2635+
packetCfg.len = 16;
2636+
packetCfg.startingSpot = 0;
2637+
2638+
payloadCfg[0] = 0x00; // message version
2639+
2640+
// bytes 1-3 are reserved - and must be set to zero
2641+
payloadCfg[1] = 0x00;
2642+
payloadCfg[2] = 0x00;
2643+
payloadCfg[3] = 0x00;
2644+
2645+
// duration
2646+
// big endian to little endian, switch byte order
2647+
payloadCfg[4] = (durationInMs >> (8*0)) & 0xff;
2648+
payloadCfg[5] = (durationInMs >> (8*1)) & 0xff;
2649+
payloadCfg[6] = (durationInMs >> (8*2)) & 0xff;
2650+
payloadCfg[7] = (durationInMs >> (8*3)) & 0xff;
2651+
2652+
// flags
2653+
2654+
// disables USB interface when powering off, defaults to true
2655+
if (forceWhileUsb)
2656+
{
2657+
payloadCfg[8] = 0x06; // force | backup
2658+
}
2659+
else
2660+
{
2661+
payloadCfg[8] = 0x02; // backup only (leave the force bit clear - module will stay on if USB is connected)
2662+
}
2663+
2664+
payloadCfg[9] = 0x00;
2665+
payloadCfg[10] = 0x00;
2666+
payloadCfg[11] = 0x00;
2667+
2668+
// wakeUpSources
2669+
2670+
// wakeupPin mapping, defaults to VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0
2671+
2672+
// Possible values are:
2673+
// VAL_RXM_PMREQ_WAKEUPSOURCE_UARTRX
2674+
// VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0
2675+
// VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT1
2676+
// VAL_RXM_PMREQ_WAKEUPSOURCE_SPICS
2677+
2678+
payloadCfg[12] = (wakeupSources >> (8*0)) & 0xff;
2679+
payloadCfg[13] = (wakeupSources >> (8*1)) & 0xff;
2680+
payloadCfg[14] = (wakeupSources >> (8*2)) & 0xff;
2681+
payloadCfg[15] = (wakeupSources >> (8*3)) & 0xff;
2682+
2683+
if (maxWait != 0)
2684+
{
2685+
// check for "not acknowledged" command
2686+
return (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_COMMAND_NACK);
2687+
}
2688+
else
2689+
{
2690+
sendCommand(&packetCfg, maxWait);
2691+
return false; // can't tell if command not acknowledged if maxWait = 0
2692+
}
2693+
}
2694+
25722695
//Change the dynamic platform model using UBX-CFG-NAV5
25732696
//Possible values are:
25742697
//PORTABLE,STATIONARY,PEDESTRIAN,AUTOMOTIVE,SEA,

Diff for: src/SparkFun_Ublox_Arduino_Library.h

+8
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,12 @@ const uint32_t VAL_CFG_SUBSEC_ANTCONF = 0x00000400; // antConf - antenna config
407407
const uint32_t VAL_CFG_SUBSEC_LOGCONF = 0x00000800; // logConf - logging configuration
408408
const uint32_t VAL_CFG_SUBSEC_FTSCONF = 0x00001000; // ftsConf - FTS configuration (FTS products only)
409409

410+
// Bitfield wakeupSources for UBX_RXM_PMREQ
411+
const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_UARTRX = 0x00000008; // uartrx
412+
const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0 = 0x00000020; // extint0
413+
const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT1 = 0x00000040; // extint1
414+
const uint32_t VAL_RXM_PMREQ_WAKEUPSOURCE_SPICS = 0x00000080; // spics
415+
410416
enum dynModel // Possible values for the dynamic platform model, which provide more accuract position output for the situation. Description extracted from ZED-F9P Integration Manual
411417
{
412418
DYN_MODEL_PORTABLE = 0, //Applications with low acceleration, e.g. portable devices. Suitable for most situations.
@@ -641,6 +647,8 @@ class SFE_UBLOX_GPS
641647

642648
boolean powerSaveMode(bool power_save = true, uint16_t maxWait = 1100);
643649
uint8_t getPowerSaveMode(uint16_t maxWait = 1100); // Returns 255 if the sendCommand fails
650+
boolean powerOff(uint32_t durationInMs, uint16_t maxWait = 1100);
651+
boolean powerOffWithInterrupt(uint32_t durationInMs, uint32_t wakeupSources = VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0, boolean forceWhileUsb = true, uint16_t maxWait = 1100);
644652

645653
//Change the dynamic platform model using UBX-CFG-NAV5
646654
boolean setDynamicModel(dynModel newDynamicModel = DYN_MODEL_PORTABLE, uint16_t maxWait = 1100);

0 commit comments

Comments
 (0)