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

1.2-legacy
geeksville 2020-02-21 12:24:35 -08:00
rodzic 598023f5db
commit aebcbf767f
5 zmienionych plików z 47 dodań i 7 usunięć

Wyświetl plik

@ -2,6 +2,7 @@
Items to complete before the first alpha release.
* have gps implement canSleep(), print nmea for debugging and discard buffers on the way into sleep
* implement CustomRF95::canSleep
* document rules for sleep wrt lora/bluetooth/screen/gps. also: if I have text messages (only) for the phone, then give a few seconds in the hopes BLE can get it across before we have to go back to sleep.
* make gps prevent light sleep if we are waiting for data

Wyświetl plik

@ -66,6 +66,7 @@ For a nice Heltec 3D printable case see this [design](https://www.thingiverse.co
This project is still pretty young but moving at a pretty good pace. Not all features are fully implemented in the current alpha builds.
Most of these problems should be solved by the beta release:
* We don't make these devices and they haven't been tested by UL or the FCC. If you use them you are experimenting and we can't promise they won't burn your house down ;-)
* Encryption is turned off for now
* A number of (straightforward) software work items have to be completed before battery life matches our measurements, currently battery life is about two days. Join us on chat if you want the spreadsheet of power measurements/calculations.
* The current Android GUI is pretty ugly still

Wyświetl plik

@ -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()

Wyświetl plik

@ -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();
};

Wyświetl plik

@ -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
{