mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-30 03:13:51 +00:00
Merge pull request #2019 from code8buster/gps-toggle-final
Adds a flag to turn the GPS power rail off entirely on tbeam
This commit is contained in:
commit
79ff0659c0
@ -52,6 +52,7 @@ class ButtonThread : public concurrency::OSThread
|
|||||||
pinMode(BUTTON_PIN, INPUT_PULLUP_SENSE);
|
pinMode(BUTTON_PIN, INPUT_PULLUP_SENSE);
|
||||||
#endif
|
#endif
|
||||||
userButton.attachClick(userButtonPressed);
|
userButton.attachClick(userButtonPressed);
|
||||||
|
userButton.setClickTicks(300);
|
||||||
userButton.attachDuringLongPress(userButtonPressedLong);
|
userButton.attachDuringLongPress(userButtonPressedLong);
|
||||||
userButton.attachDoubleClick(userButtonDoublePressed);
|
userButton.attachDoubleClick(userButtonDoublePressed);
|
||||||
userButton.attachMultiClick(userButtonMultiPressed);
|
userButton.attachMultiClick(userButtonMultiPressed);
|
||||||
@ -164,9 +165,21 @@ class ButtonThread : public concurrency::OSThread
|
|||||||
|
|
||||||
static void userButtonDoublePressed()
|
static void userButtonDoublePressed()
|
||||||
{
|
{
|
||||||
#if defined(USE_EINK) && defined(PIN_EINK_EN)
|
#if defined(USE_EINK) && defined(PIN_EINK_EN)
|
||||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(GPS_POWER_TOGGLE)
|
||||||
|
if(config.position.gps_enabled)
|
||||||
|
{
|
||||||
|
DEBUG_MSG("Flag set to false for gps power\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_MSG("Flag set to true to restore power\n");
|
||||||
|
}
|
||||||
|
config.position.gps_enabled = !(config.position.gps_enabled);
|
||||||
|
doGPSpowersave(config.position.gps_enabled);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void userButtonMultiPressed()
|
static void userButtonMultiPressed()
|
||||||
|
@ -20,16 +20,19 @@ class GPSStatus : public Status
|
|||||||
bool hasLock = false; // default to false, until we complete our first read
|
bool hasLock = false; // default to false, until we complete our first read
|
||||||
bool isConnected = false; // Do we have a GPS we are talking to
|
bool isConnected = false; // Do we have a GPS we are talking to
|
||||||
|
|
||||||
|
bool isPowerSaving = false; //Are we in power saving state
|
||||||
|
|
||||||
Position p = Position_init_default;
|
Position p = Position_init_default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GPSStatus() { statusType = STATUS_TYPE_GPS; }
|
GPSStatus() { statusType = STATUS_TYPE_GPS; }
|
||||||
|
|
||||||
// preferred method
|
// preferred method
|
||||||
GPSStatus(bool hasLock, bool isConnected, const Position &pos) : Status()
|
GPSStatus(bool hasLock, bool isConnected, bool isPowerSaving, const Position &pos) : Status()
|
||||||
{
|
{
|
||||||
this->hasLock = hasLock;
|
this->hasLock = hasLock;
|
||||||
this->isConnected = isConnected;
|
this->isConnected = isConnected;
|
||||||
|
this->isPowerSaving = isPowerSaving;
|
||||||
|
|
||||||
// all-in-one struct copy
|
// all-in-one struct copy
|
||||||
this->p = pos;
|
this->p = pos;
|
||||||
@ -44,6 +47,8 @@ class GPSStatus : public Status
|
|||||||
|
|
||||||
bool getIsConnected() const { return isConnected; }
|
bool getIsConnected() const { return isConnected; }
|
||||||
|
|
||||||
|
bool getIsPowerSaving() const { return isPowerSaving;}
|
||||||
|
|
||||||
int32_t getLatitude() const
|
int32_t getLatitude() const
|
||||||
{
|
{
|
||||||
if (config.position.fixed_position) {
|
if (config.position.fixed_position) {
|
||||||
@ -94,7 +99,7 @@ class GPSStatus : public Status
|
|||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
|
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
|
||||||
#endif
|
#endif
|
||||||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
|
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->isPowerSaving !=isPowerSaving ||
|
||||||
newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i ||
|
newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i ||
|
||||||
newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
|
newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
|
||||||
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||
|
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||
|
||||||
|
@ -270,21 +270,30 @@ bool GPS::setup()
|
|||||||
pinMode(PIN_GPS_EN, OUTPUT);
|
pinMode(PIN_GPS_EN, OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_PMU
|
||||||
|
if(config.position.gps_enabled){
|
||||||
|
setGPSPower(true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PIN_GPS_RESET
|
#ifdef PIN_GPS_RESET
|
||||||
digitalWrite(PIN_GPS_RESET, 1); // assert for 10ms
|
digitalWrite(PIN_GPS_RESET, 1); // assert for 10ms
|
||||||
pinMode(PIN_GPS_RESET, OUTPUT);
|
pinMode(PIN_GPS_RESET, OUTPUT);
|
||||||
delay(10);
|
delay(10);
|
||||||
digitalWrite(PIN_GPS_RESET, 0);
|
digitalWrite(PIN_GPS_RESET, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setAwake(true); // Wake GPS power before doing any init
|
setAwake(true); // Wake GPS power before doing any init
|
||||||
bool ok = setupGPS();
|
bool ok = setupGPS();
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
notifySleepObserver.observe(¬ifySleep);
|
notifySleepObserver.observe(¬ifySleep);
|
||||||
notifyDeepSleepObserver.observe(¬ifyDeepSleep);
|
notifyDeepSleepObserver.observe(¬ifyDeepSleep);
|
||||||
|
notifyGPSSleepObserver.observe(¬ifyGPSSleep);
|
||||||
|
}
|
||||||
|
if (config.position.gps_enabled==false) {
|
||||||
|
setAwake(false);
|
||||||
|
doGPSpowersave(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,6 +302,7 @@ GPS::~GPS()
|
|||||||
// we really should unregister our sleep observer
|
// we really should unregister our sleep observer
|
||||||
notifySleepObserver.unobserve(¬ifySleep);
|
notifySleepObserver.unobserve(¬ifySleep);
|
||||||
notifyDeepSleepObserver.unobserve(¬ifyDeepSleep);
|
notifyDeepSleepObserver.unobserve(¬ifyDeepSleep);
|
||||||
|
notifyGPSSleepObserver.observe(¬ifyGPSSleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPS::hasLock()
|
bool GPS::hasLock()
|
||||||
@ -405,7 +415,7 @@ void GPS::publishUpdate()
|
|||||||
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, hasLock());
|
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, hasLock());
|
||||||
|
|
||||||
// Notify any status instances that are observing us
|
// Notify any status instances that are observing us
|
||||||
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), p);
|
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), isPowerSaving(), p);
|
||||||
newStatus.notifyObservers(&status);
|
newStatus.notifyObservers(&status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -416,7 +426,7 @@ int32_t GPS::runOnce()
|
|||||||
// if we have received valid NMEA claim we are connected
|
// if we have received valid NMEA claim we are connected
|
||||||
setConnected();
|
setConnected();
|
||||||
} else {
|
} else {
|
||||||
if(gnssModel == GNSS_MODEL_UBLOX){
|
if((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)){
|
||||||
// reset the GPS on next bootup
|
// reset the GPS on next bootup
|
||||||
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
|
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
|
||||||
DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n");
|
DEBUG_MSG("GPS is not communicating, trying factory reset on next bootup.\n");
|
||||||
@ -518,6 +528,7 @@ int GPS::prepareDeepSleep(void *unused)
|
|||||||
DEBUG_MSG("GPS deep sleep!\n");
|
DEBUG_MSG("GPS deep sleep!\n");
|
||||||
|
|
||||||
// For deep sleep we also want abandon any lock attempts (because we want minimum power)
|
// For deep sleep we also want abandon any lock attempts (because we want minimum power)
|
||||||
|
getSleepTime();
|
||||||
setAwake(false);
|
setAwake(false);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -653,6 +664,11 @@ GPS *createGps()
|
|||||||
return new_gps;
|
return new_gps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
GPS *new_gps = new NMEAGPS();
|
||||||
|
new_gps->setup();
|
||||||
|
return new_gps;
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ class GPS : private concurrency::OSThread
|
|||||||
|
|
||||||
CallbackObserver<GPS, void *> notifySleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareSleep);
|
CallbackObserver<GPS, void *> notifySleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareSleep);
|
||||||
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
||||||
|
CallbackObserver<GPS, void *> notifyGPSSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** If !NULL we will use this serial port to construct our GPS */
|
/** If !NULL we will use this serial port to construct our GPS */
|
||||||
@ -77,6 +78,8 @@ class GPS : private concurrency::OSThread
|
|||||||
/// Return true if we are connected to a GPS
|
/// Return true if we are connected to a GPS
|
||||||
bool isConnected() const { return hasGPS; }
|
bool isConnected() const { return hasGPS; }
|
||||||
|
|
||||||
|
bool isPowerSaving() const { return !config.position.gps_enabled;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restart our lock attempt - try to get and broadcast a GPS reading ASAP
|
* Restart our lock attempt - try to get and broadcast a GPS reading ASAP
|
||||||
* called after the CPU wakes from light-sleep state
|
* called after the CPU wakes from light-sleep state
|
||||||
|
@ -512,6 +512,22 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Draw status when gps is disabled by PMU
|
||||||
|
static void drawGPSpowerstat(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps){
|
||||||
|
String displayLine = "";
|
||||||
|
displayLine = "GPS disabled";
|
||||||
|
int16_t xPos = display->getStringWidth(displayLine);
|
||||||
|
#ifdef HAS_PMU
|
||||||
|
if (!config.position.gps_enabled){
|
||||||
|
display->drawString(x + xPos, y, displayLine);
|
||||||
|
#ifdef GPS_POWER_TOGGLE
|
||||||
|
display->drawString(x + xPos, y - 2 + FONT_HEIGHT_SMALL, " by button");
|
||||||
|
#endif
|
||||||
|
//display->drawString(x + xPos, y + 2, displayLine);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
|
static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
|
||||||
{
|
{
|
||||||
String displayLine = "";
|
String displayLine = "";
|
||||||
@ -1384,7 +1400,16 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
// Display nodes status
|
// Display nodes status
|
||||||
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus);
|
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus);
|
||||||
// Display GPS status
|
// Display GPS status
|
||||||
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 3, gpsStatus);
|
if (!config.position.gps_enabled){
|
||||||
|
int16_t yPos = y + 2;
|
||||||
|
#ifdef GPS_POWER_TOGGLE
|
||||||
|
yPos = (y + 10 + FONT_HEIGHT_SMALL);
|
||||||
|
#endif
|
||||||
|
drawGPSpowerstat(display, x, yPos, gpsStatus);
|
||||||
|
} else {
|
||||||
|
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 2, gpsStatus);
|
||||||
|
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 3, gpsStatus);
|
||||||
|
}
|
||||||
|
|
||||||
display->setColor(WHITE);
|
display->setColor(WHITE);
|
||||||
// Draw the channel name
|
// Draw the channel name
|
||||||
@ -1643,7 +1668,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
char chUtil[13];
|
char chUtil[13];
|
||||||
sprintf(chUtil, "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
|
sprintf(chUtil, "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
|
||||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
|
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
|
||||||
|
if (config.position.gps_enabled) {
|
||||||
// Line 3
|
// Line 3
|
||||||
if (config.display.gps_format !=
|
if (config.display.gps_format !=
|
||||||
Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
|
Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
|
||||||
@ -1651,7 +1676,9 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
|
|
||||||
// Line 4
|
// Line 4
|
||||||
drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
|
drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
|
||||||
|
} else {
|
||||||
|
drawGPSpowerstat(display, x - (SCREEN_WIDTH / 4), y + FONT_HEIGHT_SMALL * 2, gpsStatus);
|
||||||
|
}
|
||||||
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
|
||||||
#ifdef SHOW_REDRAWS
|
#ifdef SHOW_REDRAWS
|
||||||
if (heartbeat)
|
if (heartbeat)
|
||||||
|
@ -29,7 +29,9 @@ Observable<void *> preflightSleep;
|
|||||||
|
|
||||||
/// Called to tell observers we are now entering sleep and you should prepare. Must return 0
|
/// Called to tell observers we are now entering sleep and you should prepare. Must return 0
|
||||||
/// notifySleep will be called for light or deep sleep, notifyDeepSleep is only called for deep sleep
|
/// notifySleep will be called for light or deep sleep, notifyDeepSleep is only called for deep sleep
|
||||||
|
/// notifyGPSSleep will be called when config.position.gps_enabled is set to 0 or from buttonthread when GPS_POWER_TOGGLE is enabled.
|
||||||
Observable<void *> notifySleep, notifyDeepSleep;
|
Observable<void *> notifySleep, notifyDeepSleep;
|
||||||
|
Observable<void *> notifyGPSSleep;
|
||||||
|
|
||||||
// deep sleep support
|
// deep sleep support
|
||||||
RTC_DATA_ATTR int bootCount = 0;
|
RTC_DATA_ATTR int bootCount = 0;
|
||||||
@ -167,6 +169,36 @@ static void waitEnterSleep()
|
|||||||
notifySleep.notifyObservers(NULL);
|
notifySleep.notifyObservers(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void doGPSpowersave(bool on)
|
||||||
|
{
|
||||||
|
#ifdef HAS_PMU
|
||||||
|
if (on)
|
||||||
|
{
|
||||||
|
DEBUG_MSG("Turning GPS back on\n");
|
||||||
|
gps->forceWake(1);
|
||||||
|
setGPSPower(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_MSG("Turning off GPS chip\n");
|
||||||
|
notifyGPSSleep.notifyObservers(NULL);
|
||||||
|
setGPSPower(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef PIN_GPS_WAKE
|
||||||
|
if (on)
|
||||||
|
{
|
||||||
|
DEBUG_MSG("Waking GPS");
|
||||||
|
gps->forceWake(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_MSG("GPS entering sleep");
|
||||||
|
notifyGPSSleep.notifyObservers(NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void doDeepSleep(uint64_t msecToWake)
|
void doDeepSleep(uint64_t msecToWake)
|
||||||
{
|
{
|
||||||
DEBUG_MSG("Entering deep sleep for %lu seconds\n", msecToWake / 1000);
|
DEBUG_MSG("Entering deep sleep for %lu seconds\n", msecToWake / 1000);
|
||||||
|
@ -13,7 +13,7 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t msecToWake);
|
|||||||
extern esp_sleep_source_t wakeCause;
|
extern esp_sleep_source_t wakeCause;
|
||||||
#endif
|
#endif
|
||||||
void setGPSPower(bool on);
|
void setGPSPower(bool on);
|
||||||
|
void doGPSpowersave(bool on);
|
||||||
// Perform power on init that we do on each wake from deep sleep
|
// Perform power on init that we do on each wake from deep sleep
|
||||||
void initDeepSleep();
|
void initDeepSleep();
|
||||||
|
|
||||||
@ -37,4 +37,6 @@ extern Observable<void *> notifySleep;
|
|||||||
/// Called to tell observers we are now entering (deep) sleep and you should prepare. Must return 0
|
/// Called to tell observers we are now entering (deep) sleep and you should prepare. Must return 0
|
||||||
extern Observable<void *> notifyDeepSleep;
|
extern Observable<void *> notifyDeepSleep;
|
||||||
|
|
||||||
|
/// Called to tell GPS thread to enter deep sleep independently of LoRa/MCU sleep, prior to full poweroff. Must return 0
|
||||||
|
extern Observable<void *> notifyGPSSleep;
|
||||||
void enableModemSleep();
|
void enableModemSleep();
|
@ -6,4 +6,5 @@ lib_deps =
|
|||||||
${esp32_base.lib_deps}
|
${esp32_base.lib_deps}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags} -D TBEAM_V10 -I variants/tbeam
|
${esp32_base.build_flags} -D TBEAM_V10 -I variants/tbeam
|
||||||
|
-DGPS_POWER_TOGGLE ; comment this line to disable double press function on the user button to turn off gps entirely.
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
|
Loading…
Reference in New Issue
Block a user