From 6018d523a2dee945bb8eaf160812885fd7e80e64 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 22 Feb 2020 17:40:31 -0800 Subject: [PATCH] blink the led very briefly every 5 secs while in light sleep --- TODO.md | 12 +++++++----- src/GPS.cpp | 8 ++++++-- src/PowerFSM.cpp | 24 ++++++++++++++++++++---- src/screen.cpp | 7 ------- src/sleep.cpp | 6 +++--- 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/TODO.md b/TODO.md index 7e6aa3ef8..bb972c2fd 100644 --- a/TODO.md +++ b/TODO.md @@ -2,12 +2,10 @@ Items to complete before the first alpha release. -* implement sleep state machine +* scrolling between screens based on press is busted +* have state machine properly enter deep sleep based on loss of mesh and phone comms * have gps implement canSleep(), print nmea for debugging and discard buffers on the way into sleep * implement CustomRF95::canSleep -* make gps prevent light sleep if we are waiting for data -* wake from light sleep as needed for our next scheduled periodic task (needed for gps position broadcasts etc) -* turn bluetooth off based on our sleep policy * if the phone doesn't read fromradio mailbox within X seconds, assume the phone is gone and we can stop queing location msgs for it (because it will redownload the nodedb when it comes back) * don't enter light sleep while the screen is on @@ -25,6 +23,7 @@ for it (because it will redownload the nodedb when it comes back) Items to complete before the first beta release. +* use gps sleep mode instead of killing its power (to allow fast position when we wake) * leave lora receiver always on * rx signal measurements -3 marginal, -9 bad, 10 great, -10 means almost unusable. So scale this into % signal strength. preferably as a graph, with an X indicating loss of comms. * assign every "channel" a random shared 8 bit sync word (per 4.2.13.6 of datasheet) - use that word to filter packets before even checking CRC. This will ensure our CPU will only wake for packets on our "channel" @@ -162,4 +161,7 @@ Items after the first final candidate release. * post sample video to signal forum * support non US frequencies * send pr https://github.com/ThingPulse/esp8266-oled-ssd1306 to tell them about this project -* 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. \ No newline at end of file +* 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. +* wake from light sleep as needed for our next scheduled periodic task (needed for gps position broadcasts etc) +* turn bluetooth off based on our sleep policy +* blink LED while in LS sleep mode \ No newline at end of file diff --git a/src/GPS.cpp b/src/GPS.cpp index 4b75901a3..730b235e8 100644 --- a/src/GPS.cpp +++ b/src/GPS.cpp @@ -2,6 +2,7 @@ #include "GPS.h" #include "time.h" #include +#include "configuration.h" // stuff that really should be in in the instance instead... HardwareSerial _serial_gps(GPS_SERIAL_NUM); @@ -12,7 +13,7 @@ RTC_DATA_ATTR bool timeSetFromGPS; // We only reset our time once per _boot_ aft GPS gps; bool hasValidLocation; // default to false, until we complete our first read -bool wantNewLocation = true; +bool wantNewLocation = true; GPS::GPS() : PeriodicTask() { @@ -98,12 +99,15 @@ void GPS::doTask() while (_serial_gps.available()) { encode(_serial_gps.read()); + // DEBUG_MSG("Got GPS response\n"); } if (!timeSetFromGPS && time.isValid() && date.isValid()) { struct timeval tv; + DEBUG_MSG("Got time from GPS\n"); + /* Convert to unix time The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). */ @@ -137,7 +141,7 @@ void GPS::doTask() setPeriod(hasValidLocation && !wantNewLocation ? 30 * 1000 : 100); } -void GPS::startLock() +void GPS::startLock() { DEBUG_MSG("Looking for GPS lock\n"); wantNewLocation = true; diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 8f4b1bb8f..fef3ae418 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -43,11 +43,27 @@ static void lsEnter() static void lsIdle() { - doLightSleep(radioConfig.preferences.ls_secs * 1000LL); - - // FIXME - blink led when we occasionally wake from timer, then go back to light sleep + uint32_t secsSlept = 0; + esp_sleep_source_t wakeCause = ESP_SLEEP_WAKEUP_UNDEFINED; - // Regardless of why we woke (for now) just transition to NB + while (secsSlept < radioConfig.preferences.ls_secs) + { + // Briefly come out of sleep long enough to blink the led once every few seconds + uint32_t sleepTime = 5; + + setLed(false); // Never leave led on while in light sleep + wakeCause = doLightSleep(sleepTime * 1000LL); + if (wakeCause != ESP_SLEEP_WAKEUP_TIMER) + break; + + setLed(true); // briefly turn on led + doLightSleep(1); + if (wakeCause != ESP_SLEEP_WAKEUP_TIMER) + break; + } + setLed(false); + + // Regardless of why we woke (for now) just transition to NB (and that state will handle stuff like IRQs etc) powerFSM.trigger(EVENT_WAKE_TIMER); } diff --git a/src/screen.cpp b/src/screen.cpp index b0920da45..41dfbc2cb 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -651,13 +651,6 @@ void Screen::doTask() nodeDB.updateGUI = false; nodeDB.updateTextMessage = false; } - -/* - if (millis() - lastPressMs > SCREEN_SLEEP_MS) - { - DEBUG_MSG("screen timeout, turn it off for now...\n"); - screen.setOn(false); - } */ } } diff --git a/src/sleep.cpp b/src/sleep.cpp index 4769e91cb..31d634940 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -209,11 +209,11 @@ void setBluetoothEnable(bool on) */ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more reasonable default { - DEBUG_MSG("Enter light sleep\n"); + //DEBUG_MSG("Enter light sleep\n"); uint64_t sleepUsec = sleepMsec * 1000LL; + Serial.flush(); // send all our characters before we stop cpu clock setBluetoothEnable(false); // has to be off before calling light sleep - setLed(false); // Never leave led on while in light sleep // NOTE! ESP docs say we must disable bluetooth and wifi before light sleep @@ -228,7 +228,7 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r assert(esp_sleep_enable_gpio_wakeup() == ESP_OK); assert(esp_sleep_enable_timer_wakeup(sleepUsec) == ESP_OK); assert(esp_light_sleep_start() == ESP_OK); - DEBUG_MSG("Exit light sleep\n"); + //DEBUG_MSG("Exit light sleep\n"); return esp_sleep_get_wakeup_cause(); }