Merge pull request #2019 from code8buster/gps-toggle-final

Adds a flag to turn the GPS power rail off entirely on tbeam
raytac-diy
Thomas Göttgens 2022-12-17 23:32:20 +01:00
rodzic 941786669b
commit 220859d0aa
8 zmienionych plików z 111 dodań i 12 usunięć

Wyświetl plik

@ -51,6 +51,7 @@ class ButtonThread : public concurrency::OSThread
pinMode(BUTTON_PIN, INPUT_PULLUP_SENSE);
#endif
userButton.attachClick(userButtonPressed);
userButton.setClickTicks(300);
userButton.attachDuringLongPress(userButtonPressedLong);
userButton.attachDoubleClick(userButtonDoublePressed);
userButton.attachMultiClick(userButtonMultiPressed);
@ -159,9 +160,21 @@ class ButtonThread : public concurrency::OSThread
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);
#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()

Wyświetl plik

@ -20,16 +20,19 @@ class GPSStatus : public Status
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 isPowerSaving = false; //Are we in power saving state
Position p = Position_init_default;
public:
GPSStatus() { statusType = STATUS_TYPE_GPS; }
// 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->isConnected = isConnected;
this->isPowerSaving = isPowerSaving;
// all-in-one struct copy
this->p = pos;
@ -44,6 +47,8 @@ class GPSStatus : public Status
bool getIsConnected() const { return isConnected; }
bool getIsPowerSaving() const { return isPowerSaving;}
int32_t getLatitude() const
{
if (config.position.fixed_position) {
@ -94,7 +99,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
#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.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||

Wyświetl plik

@ -270,21 +270,30 @@ bool GPS::setup()
pinMode(PIN_GPS_EN, OUTPUT);
#endif
#ifdef HAS_PMU
if(config.position.gps_enabled){
setGPSPower(true);
}
#endif
#ifdef PIN_GPS_RESET
digitalWrite(PIN_GPS_RESET, 1); // assert for 10ms
pinMode(PIN_GPS_RESET, OUTPUT);
delay(10);
digitalWrite(PIN_GPS_RESET, 0);
#endif
setAwake(true); // Wake GPS power before doing any init
bool ok = setupGPS();
if (ok) {
notifySleepObserver.observe(&notifySleep);
notifyDeepSleepObserver.observe(&notifyDeepSleep);
notifyGPSSleepObserver.observe(&notifyGPSSleep);
}
if (config.position.gps_enabled==false) {
setAwake(false);
doGPSpowersave(false);
}
return ok;
}
@ -293,6 +302,7 @@ GPS::~GPS()
// we really should unregister our sleep observer
notifySleepObserver.unobserve(&notifySleep);
notifyDeepSleepObserver.unobserve(&notifyDeepSleep);
notifyGPSSleepObserver.observe(&notifyGPSSleep);
}
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());
// 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);
}
}
@ -416,7 +426,7 @@ int32_t GPS::runOnce()
// if we have received valid NMEA claim we are connected
setConnected();
} else {
if(gnssModel == GNSS_MODEL_UBLOX){
if((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)){
// reset the GPS on next bootup
if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
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");
// For deep sleep we also want abandon any lock attempts (because we want minimum power)
getSleepTime();
setAwake(false);
return 0;
@ -653,6 +664,11 @@ GPS *createGps()
return new_gps;
}
}
else{
GPS *new_gps = new NMEAGPS();
new_gps->setup();
return new_gps;
}
return nullptr;
#endif
}

Wyświetl plik

@ -49,6 +49,7 @@ class GPS : private concurrency::OSThread
CallbackObserver<GPS, void *> notifySleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareSleep);
CallbackObserver<GPS, void *> notifyDeepSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
CallbackObserver<GPS, void *> notifyGPSSleepObserver = CallbackObserver<GPS, void *>(this, &GPS::prepareDeepSleep);
public:
/** 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
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
* called after the CPU wakes from light-sleep state

Wyświetl plik

@ -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)
{
String displayLine = "";
@ -1384,7 +1400,16 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// Display nodes status
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus);
// 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);
// Draw the channel name
@ -1643,7 +1668,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
char chUtil[13];
sprintf(chUtil, "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
if (config.position.gps_enabled) {
// Line 3
if (config.display.gps_format !=
Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
@ -1651,7 +1676,9 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// Line 4
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 */
#ifdef SHOW_REDRAWS
if (heartbeat)

Wyświetl plik

@ -29,7 +29,9 @@ Observable<void *> preflightSleep;
/// 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
/// 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 *> notifyGPSSleep;
// deep sleep support
RTC_DATA_ATTR int bootCount = 0;
@ -167,6 +169,36 @@ static void waitEnterSleep()
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)
{
DEBUG_MSG("Entering deep sleep for %lu seconds\n", msecToWake / 1000);

Wyświetl plik

@ -13,7 +13,7 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t msecToWake);
extern esp_sleep_source_t wakeCause;
#endif
void setGPSPower(bool on);
void doGPSpowersave(bool on);
// Perform power on init that we do on each wake from deep sleep
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
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();

Wyświetl plik

@ -6,4 +6,5 @@ lib_deps =
${esp32_base.lib_deps}
build_flags =
${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