mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-08-29 02:38:19 +00:00
GPS PowerSaving v1.1: Added support for BLE companions
This commit is contained in:
@@ -234,6 +234,18 @@ void setup() {
|
||||
#error "need to define filesystem"
|
||||
#endif
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
// Apply PowerSaving profile for GPS
|
||||
if(sensors.getLocationProvider() != NULL) {
|
||||
// Enable by default
|
||||
sensors.powersaving_enabled = true;
|
||||
sensors.getLocationProvider()->enablePowerSaving(true);
|
||||
|
||||
// Set GPS on and off duration in seconds
|
||||
sensors.getLocationProvider()->setPowerSavingProfile(600, 300); // Max 10 minutes, 5 minutes
|
||||
}
|
||||
#endif
|
||||
|
||||
sensors.begin();
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
|
||||
@@ -87,6 +87,18 @@ void setup() {
|
||||
|
||||
command[0] = 0;
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
// Apply PowerSaving profile for GPS
|
||||
if (sensors.getLocationProvider() != NULL) {
|
||||
// Let CLI "gps on" call setSettingValue to enable the PowerSaving mode
|
||||
// sensors.powersaving_enabled = true;
|
||||
// sensors.getLocationProvider()->enablePowerSaving(true);
|
||||
|
||||
// GPS on and off duration in seconds
|
||||
sensors.getLocationProvider()->setPowerSavingProfile(600, 86400); // Max 10 minutes, 1 day
|
||||
}
|
||||
#endif
|
||||
|
||||
sensors.begin();
|
||||
|
||||
the_mesh.begin(fs);
|
||||
|
||||
@@ -37,6 +37,15 @@
|
||||
#define BRIDGE_DEBUG_PRINTLN(...) {}
|
||||
#endif
|
||||
|
||||
#if POWERSAVING_DEBUG && ARDUINO
|
||||
#include <Arduino.h>
|
||||
#define POWERSAVING_DEBUG_PRINT(F, ...) Serial.printf("POWERSAVING: " F, ##__VA_ARGS__)
|
||||
#define POWERSAVING_DEBUG_PRINTLN(F, ...) Serial.printf("POWERSAVING: " F "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define POWERSAVING_DEBUG_PRINT(...) {}
|
||||
#define POWERSAVING_DEBUG_PRINTLN(...) {}
|
||||
#endif
|
||||
|
||||
namespace mesh {
|
||||
|
||||
#define BD_STARTUP_NORMAL 0 // getStartupReason() codes
|
||||
|
||||
@@ -436,9 +436,9 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
|
||||
int sats = l->satellitesCount();
|
||||
bool active = !strcmp(_sensors->getSettingByKey("gps"), "1");
|
||||
|
||||
if (_prefs->powersaving_enabled && l->getGPSPowerSaving()) { // GPS Power Saving
|
||||
if (_prefs->powersaving_enabled && l->isPowerSavingEnabled()) { // GPS Power Saving
|
||||
if (enabled) {
|
||||
unsigned long mins = (l->getNextGPSOff() - millis()) / 60000UL;
|
||||
unsigned long mins = (l->getNextSleep() - millis()) / 60000UL;
|
||||
sprintf(reply, "on (powersaving, sleep in %luh %lum), %s, %s, %d sats",
|
||||
mins / 60UL,
|
||||
mins % 60UL,
|
||||
@@ -446,7 +446,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
|
||||
fix ? "fix" : "no fix",
|
||||
sats);
|
||||
} else {
|
||||
unsigned long mins = (l->getNextGPSOn() - millis()) / 60000UL;
|
||||
unsigned long mins = (l->getNextWake() - millis()) / 60000UL;
|
||||
sprintf(reply, "off (powersaving, wake in %luh %lum)",
|
||||
mins / 60UL,
|
||||
mins % 60UL);
|
||||
|
||||
@@ -621,12 +621,6 @@ static const SensorDef SENSOR_TABLE[] = {
|
||||
|
||||
static const size_t SENSOR_TABLE_SIZE = (sizeof(SENSOR_TABLE) / sizeof(SENSOR_TABLE[0])) - 1;
|
||||
|
||||
// ============================================================
|
||||
// Power Saving GPS
|
||||
// ============================================================
|
||||
static unsigned long GPS_ON_DURATION_SECS = 600; // 10 minutes
|
||||
static unsigned long GPS_OFF_DURATION_SECS = 86400; // 1 day
|
||||
|
||||
// ============================================================
|
||||
// begin() — scan the I2C bus, then initialize only what was
|
||||
// found. A sensor whose address does not ACK during the scan
|
||||
@@ -737,13 +731,13 @@ bool EnvironmentSensorManager::setSettingValue(const char* name, const char* val
|
||||
if (gps_detected && strcmp(name, "gps") == 0) {
|
||||
if (strcmp(value, "0") == 0) {
|
||||
if (powersaving_enabled) {
|
||||
_location->setGPSPowerSaving(false);
|
||||
_location->enablePowerSaving(false);
|
||||
}
|
||||
|
||||
stop_gps();
|
||||
} else {
|
||||
if (powersaving_enabled) {
|
||||
_location->setGPSPowerSaving(true);
|
||||
_location->enablePowerSaving(true);
|
||||
}
|
||||
|
||||
start_gps();
|
||||
@@ -885,6 +879,13 @@ bool EnvironmentSensorManager::gpsIsAwake(uint8_t ioPin){
|
||||
|
||||
void EnvironmentSensorManager::start_gps() {
|
||||
gps_active = true;
|
||||
|
||||
if (powersaving_enabled && _location->isPowerSavingEnabled()) {
|
||||
gps_wake = true; // gps_active is true
|
||||
_location->syncTime(); // Clear GPS data and force sync time
|
||||
_location->setNextSleep(); // Next time to off
|
||||
}
|
||||
|
||||
#ifdef RAK_WISBLOCK_GPS
|
||||
pinMode(gpsResetPin, OUTPUT);
|
||||
digitalWrite(gpsResetPin, HIGH);
|
||||
@@ -897,22 +898,19 @@ void EnvironmentSensorManager::start_gps() {
|
||||
#ifndef PIN_GPS_EN
|
||||
MESH_DEBUG_PRINTLN("Start GPS is N/A on this board. Actual GPS state unchanged");
|
||||
#endif
|
||||
|
||||
if (powersaving_enabled && _location->getGPSPowerSaving()) {
|
||||
_location->syncTime(); // Clear GPS data and force sync time
|
||||
_location->setNextGPSOff(millis() + GPS_ON_DURATION_SECS * 1000UL); // Next time to off
|
||||
}
|
||||
}
|
||||
|
||||
void EnvironmentSensorManager::stop_gps() {
|
||||
gps_active = false;
|
||||
|
||||
if (powersaving_enabled && _location->getGPSPowerSaving()) {
|
||||
if (powersaving_enabled && _location->isPowerSavingEnabled()) {
|
||||
gps_wake = false; // gps_active is unchanged (true) even the GPS sleep (e.g: off)
|
||||
_location->stopTimeSync(); // Stop time sync
|
||||
_location->setNextGPSOn(millis() + GPS_OFF_DURATION_SECS * 1000UL); // Next time to on
|
||||
_location->setNextWake(); // Next time to on
|
||||
} else {
|
||||
gps_active = false;
|
||||
gps_wake = false; // When GPS is off, wake is false to be sure
|
||||
}
|
||||
|
||||
#ifdef RAK_WISBLOCK_GPS
|
||||
#ifdef RAK_WISBLOCK_GPS
|
||||
pinMode(gpsResetPin, OUTPUT);
|
||||
digitalWrite(gpsResetPin, LOW);
|
||||
return;
|
||||
@@ -934,37 +932,35 @@ void EnvironmentSensorManager::loop() {
|
||||
|
||||
// PowerSaving
|
||||
if (powersaving_enabled) {
|
||||
if (gps_detected && _location->getGPSPowerSaving()) {
|
||||
if (gps_active && ((int32_t)(millis() - _location->getNextGPSOff()) >= 0 ||
|
||||
if (gps_detected && _location->isPowerSavingEnabled()) {
|
||||
if (gps_wake && ((int32_t)(millis() - _location->getNextSleep()) >= 0 ||
|
||||
!_location->waitingTimeSync())) { // Time to off or GPS set
|
||||
// --- TO REMOVE
|
||||
if ((int32_t)(millis() - _location->getNextGPSOff()) >= 0) Serial.println("Timeout, off");
|
||||
else if (!_location->waitingTimeSync()) Serial.println("GPS set, off early");
|
||||
// --- TO REMOVE
|
||||
if ((int32_t)(millis() - _location->getNextSleep()) >= 0) {
|
||||
POWERSAVING_DEBUG_PRINTLN("GPS wake timeout. Enter sleep");
|
||||
}
|
||||
else if (!_location->waitingTimeSync()) {
|
||||
POWERSAVING_DEBUG_PRINTLN("GPS set. Enter sleep early");
|
||||
}
|
||||
|
||||
stop_gps();
|
||||
} else if (!gps_active && ((int32_t)(millis() - _location->getNextGPSOn()) >= 0)) { // Time to on
|
||||
// --- TO REMOVE
|
||||
Serial.println("Timeout, on");
|
||||
// --- TO REMOVE
|
||||
} else if (!gps_wake && ((int32_t)(millis() - _location->getNextWake()) >= 0)) { // Time to on
|
||||
POWERSAVING_DEBUG_PRINTLN("GPS sleep timeout. Wakeup.");
|
||||
|
||||
start_gps();
|
||||
} else if (!gps_active && _location->waitingTimeSync()) { // On for "gps sync"
|
||||
// --- TO REMOVE
|
||||
Serial.println("gps sync CLI, on");
|
||||
// --- TO REMOVE
|
||||
} else if (!gps_wake && _location->waitingTimeSync()) { // On for "gps sync"
|
||||
POWERSAVING_DEBUG_PRINTLN("CLI gps sync. Wakeup");
|
||||
|
||||
start_gps();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gps_active) {
|
||||
if ((!powersaving_enabled && gps_active) || (powersaving_enabled && gps_wake)) {
|
||||
_location->loop();
|
||||
}
|
||||
|
||||
if ((int32_t)(millis() - next_gps_update) >= 0) {
|
||||
if(gps_active){
|
||||
if((!powersaving_enabled && gps_active) || (powersaving_enabled && gps_wake)){
|
||||
#ifdef RAK_WISBLOCK_GPS
|
||||
if ((i2cGPSFlag || serialGPSFlag) && _location->isValid()) {
|
||||
node_lat = ((double)_location->getLatitude())/1000000.;
|
||||
|
||||
@@ -21,6 +21,7 @@ protected:
|
||||
|
||||
bool gps_detected = false;
|
||||
bool gps_active = false;
|
||||
bool gps_wake = false; // In PowerSaving, gps_active can have gps_wake true or false
|
||||
uint32_t gps_update_interval_sec = 1;
|
||||
|
||||
#if ENV_INCLUDE_GPS
|
||||
|
||||
@@ -6,22 +6,32 @@
|
||||
class LocationProvider {
|
||||
protected:
|
||||
bool _time_sync_needed = true;
|
||||
|
||||
bool powersaving_enabled = false;
|
||||
unsigned long _next_gps_off = 0;
|
||||
unsigned long _next_gps_on = 0;
|
||||
unsigned long _wake_duration_secs = 86400; // Full day
|
||||
unsigned long _sleep_duration_secs = 0; // No off
|
||||
unsigned long _next_wake = 0;
|
||||
unsigned long _next_sleep = 0;
|
||||
unsigned long _last_valid_time_sync = 0;
|
||||
|
||||
public:
|
||||
virtual void syncTime() { _time_sync_needed = true; }
|
||||
virtual bool waitingTimeSync() { return _time_sync_needed; }
|
||||
virtual void stopTimeSync() { _time_sync_needed = false; }
|
||||
virtual void setGPSPowerSaving(bool enabled) { powersaving_enabled = enabled; _next_gps_off = 0; _next_gps_on = 0; }
|
||||
virtual bool getGPSPowerSaving() { return powersaving_enabled; }
|
||||
virtual void setNextGPSOff(unsigned long _millis) { _next_gps_off = _millis; }
|
||||
virtual unsigned long getNextGPSOff() { return _next_gps_off; }
|
||||
virtual void setNextGPSOn(unsigned long _millis) { _next_gps_on = _millis; }
|
||||
virtual unsigned long getNextGPSOn() { return _next_gps_on; }
|
||||
|
||||
virtual void setPowerSavingProfile(unsigned long wake_duration_secs, unsigned long sleep_duration_secs) {
|
||||
_wake_duration_secs = wake_duration_secs;
|
||||
_sleep_duration_secs = sleep_duration_secs;
|
||||
}
|
||||
|
||||
virtual void enablePowerSaving(bool enabled) { powersaving_enabled = enabled; _next_wake = 0; _next_sleep = 0; }
|
||||
virtual bool isPowerSavingEnabled() { return powersaving_enabled; }
|
||||
virtual void setNextWake() { _next_wake = millis() + _sleep_duration_secs * 1000UL; }
|
||||
virtual unsigned long getNextWake() { return _next_wake; }
|
||||
virtual void setNextSleep() { _next_sleep = millis() + _wake_duration_secs * 1000UL; }
|
||||
virtual unsigned long getNextSleep() { return _next_sleep; }
|
||||
virtual unsigned long getLastValidTimeSync() { return _last_valid_time_sync; }
|
||||
|
||||
virtual long getLatitude() = 0;
|
||||
virtual long getLongitude() = 0;
|
||||
virtual long getAltitude() = 0;
|
||||
|
||||
Reference in New Issue
Block a user