GPS works better now with light-sleep but not quite done.

This commit is contained in:
geeksville
2020-02-21 12:24:35 -08:00
parent 598023f5db
commit aebcbf767f
5 changed files with 47 additions and 7 deletions

View File

@@ -8,12 +8,13 @@ HardwareSerial _serial_gps(GPS_SERIAL_NUM);
uint32_t timeStartMsec; // Once we have a GPS lock, this is where we hold the initial msec clock that corresponds to that time
uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only updated once on initial lock
RTC_DATA_ATTR bool timeSetFromGPS; // We only reset our time once per _boot_ after that point just run from the internal clock (even across sleeps)
RTC_DATA_ATTR bool timeSetFromGPS; // We only reset our time once per _boot_ after that point just run from the internal clock (even across sleeps)
GPS gps;
bool hasValidLocation; // default to false, until we complete our first read
bool wantNewLocation;
GPS::GPS() : PeriodicTask()
GPS::GPS() : PeriodicTask()
{
}
@@ -70,6 +71,25 @@ uint32_t GPS::getValidTime()
return timeSetFromGPS ? getTime() : 0;
}
/// Returns true if we think the board can enter deep or light sleep now (we might be trying to get a GPS lock)
bool GPS::canSleep()
{
return !wantNewLocation;
}
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
void GPS::prepareSleep()
{
// discard all rx serial bytes so we don't try to parse them when we come back
while (_serial_gps.available())
{
_serial_gps.read();
}
// make the parser bail on whatever it was parsing
encode('\n');
}
void GPS::doTask()
{
#ifdef GPS_RX_PIN
@@ -107,11 +127,14 @@ void GPS::doTask()
{ // we only notify if position has changed
// DEBUG_MSG("new gps pos\n");
hasValidLocation = true;
wantNewLocation = false;
notifyObservers();
}
else // we didn't get a location update, go back to sleep and hope the characters show up
wantNewLocation = true;
// Once we have sent a location we only poll the GPS rarely, otherwise check back every 100ms until we have something over the serial
setPeriod(hasValidLocation ? 30 * 1000 : 100);
// Once we have sent a location once we only poll the GPS rarely, otherwise check back every 100ms until we have something over the serial
setPeriod(hasValidLocation && !wantNewLocation ? 30 * 1000 : 100);
}
String GPS::getTimeStr()

View File

@@ -32,6 +32,12 @@ public:
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
void perhapsSetRTC(const struct timeval *tv);
/// Returns true if we think the board can enter deep or light sleep now (we might be trying to get a GPS lock)
bool canSleep();
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
void prepareSleep();
private:
void readFromRTC();
};

View File

@@ -88,6 +88,14 @@ static void setLed(bool ledOn)
#endif
}
void setGPSPower(bool on)
{
#ifdef T_BEAM_V10
if (axp192_found)
axp.setPowerOutPut(AXP192_LDO3, on ? AXP202_ON : AXP202_OFF); // GPS main power
#endif
}
void doDeepSleep(uint64_t msecToWake)
{
DEBUG_MSG("Entering deep sleep for %llu seconds\n", msecToWake / 1000);
@@ -126,7 +134,7 @@ void doDeepSleep(uint64_t msecToWake)
// axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // LORA radio
axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); // GPS main power
setGPSPower(false);
}
#endif
@@ -213,7 +221,8 @@ void doLightSleep(uint32_t sleepMsec = 20 * 1000) // FIXME, use a more reasonabl
DEBUG_MSG("Enter light sleep\n");
uint64_t sleepUsec = sleepMsec * 1000LL;
setLed(false); // Never leave led on while in light sleep
gps.prepareSleep(); // abandon in-process parsing
setLed(false); // Never leave led on while in light sleep
// NOTE! ESP docs say we must disable bluetooth and wifi before light sleep
@@ -621,7 +630,7 @@ void loop()
// while we have bluetooth on, we can't do light sleep, but once off stay in light_sleep all the time
// we will wake from light sleep on button press or interrupt from the RF95 radio
if (!bluetoothOn && !is_screen_on() && service.radio.rf95.canSleep())
if (!bluetoothOn && !is_screen_on() && service.radio.rf95.canSleep() && gps.canSleep())
doLightSleep(60 * 1000); // FIXME, wake up to briefly flash led, then go back to sleep (without repowering bluetooth)
else
{