From 3c1c11e4391eccae500e69b29cdb6f0fbcd9f3bb Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Mon, 5 Oct 2020 15:29:26 +0800 Subject: [PATCH] bug #376 wip - we now kill gps power when it is supposed to be asleep --- docs/software/gps-todo.txt | 4 +- src/gps/GPS.cpp | 9 ++-- src/gps/GPS.h | 4 +- src/gps/NMEAGPS.cpp | 3 +- src/gps/NMEAGPS.h | 2 +- src/gps/UBloxGPS.cpp | 96 ++++++++++++++++++++------------------ src/gps/UBloxGPS.h | 11 +++-- 7 files changed, 69 insertions(+), 60 deletions(-) diff --git a/docs/software/gps-todo.txt b/docs/software/gps-todo.txt index f2d39d02..dc74f8df 100644 --- a/docs/software/gps-todo.txt +++ b/docs/software/gps-todo.txt @@ -3,14 +3,14 @@ gps todo - bug 376 for taiwan region: bin/run.sh --set region 8 +after sleep we declare success without real new data + handle the various GPS modes fix poll interval for sending commands to ublox handle maxint parameters -handle loss of lock at end of wake (gotLocThisTime) - if not sharing location, don't even power up the GPS if we go to sleep without getting a location set hasValidLocation to false diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 018b2dc1..188d4e98 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -95,9 +95,13 @@ uint32_t getValidTime() bool GPS::setup() { - notifySleepObserver.observe(¬ifySleep); + setAwake(true); // Wake GPS power before doing any init + bool ok = setupGPS(); - return true; + if (ok) + notifySleepObserver.observe(¬ifySleep); + + return ok; } /** @@ -175,7 +179,6 @@ void GPS::loop() // If we are overdue for an update, turn on the GPS and at least publish the current status uint32_t now = millis(); - bool mustPublishUpdate = false; if ((now - lastSleepStartMsec) > getSleepTime() && !isAwake) { // We now want to be awake - so wake up the GPS diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 858a318c..d4abfd11 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -79,6 +79,9 @@ class GPS void forceWake(bool on); protected: + /// Do gps chipset specific init, return true for success + virtual bool setupGPS() = 0; + /// If possible force the GPS into sleep/low power mode virtual void sleep() {} @@ -134,7 +137,6 @@ class GPS * Tell users we have new GPS readings */ void publishUpdate(); - }; extern GPS *gps; diff --git a/src/gps/NMEAGPS.cpp b/src/gps/NMEAGPS.cpp index ef17ee05..1b6bb1b3 100644 --- a/src/gps/NMEAGPS.cpp +++ b/src/gps/NMEAGPS.cpp @@ -10,14 +10,13 @@ static int32_t toDegInt(RawDegrees d) return r; } -bool NMEAGPS::setup() +bool NMEAGPS::setupGPS() { #ifdef PIN_GPS_PPS // pulse per second // FIXME - move into shared GPS code pinMode(PIN_GPS_PPS, INPUT); #endif - GPS::setup(); return true; } diff --git a/src/gps/NMEAGPS.h b/src/gps/NMEAGPS.h index 48472823..f411e4d1 100644 --- a/src/gps/NMEAGPS.h +++ b/src/gps/NMEAGPS.h @@ -15,7 +15,7 @@ class NMEAGPS : public GPS TinyGPSPlus reader; public: - virtual bool setup(); + virtual bool setupGPS(); protected: /** Subclasses should look for serial rx characters here and feed it to their GPS parser diff --git a/src/gps/UBloxGPS.cpp b/src/gps/UBloxGPS.cpp index 05f93b9b..dbe55da4 100644 --- a/src/gps/UBloxGPS.cpp +++ b/src/gps/UBloxGPS.cpp @@ -1,5 +1,6 @@ #include "UBloxGPS.h" #include "error.h" +#include "sleep.h" #include UBloxGPS::UBloxGPS() {} @@ -22,7 +23,7 @@ bool UBloxGPS::tryConnect() return isConnected; } -bool UBloxGPS::setup() +bool UBloxGPS::setupGPS() { if (_serial_gps) { #ifdef GPS_RX_PIN @@ -33,12 +34,6 @@ bool UBloxGPS::setup() // _serial_gps.setRxBufferSize(1024); // the default is 256 } -#ifdef GPS_POWER_EN - pinMode(GPS_POWER_EN, OUTPUT); - digitalWrite(GPS_POWER_EN, 1); - delay(200); // Give time for the GPS to startup after we gave power -#endif - ublox.enableDebugging(Serial); // try a second time, the ublox lib serial parsing is buggy? @@ -49,15 +44,11 @@ bool UBloxGPS::setup() if (isConnected) { DEBUG_MSG("Connected to UBLOX GPS successfully\n"); - GPS::setup(); - if (!setUBXMode()) recordCriticalError(UBloxInitFailed); // Don't halt the boot if saving the config fails, but do report the bug return true; } else { - // Note: we do not call superclass setup in this case, because we dont want sleep observer registered - return false; } } @@ -134,24 +125,28 @@ void UBloxGPS::whileActive() */ bool UBloxGPS::lookForTime() { - if (fixType >= 2 && ublox.getT(maxWait())) { - /* 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). - */ - struct tm t; - t.tm_sec = ublox.getSecond(0); - t.tm_min = ublox.getMinute(0); - t.tm_hour = ublox.getHour(0); - t.tm_mday = ublox.getDay(0); - t.tm_mon = ublox.getMonth(0) - 1; - t.tm_year = ublox.getYear(0) - 1900; - t.tm_isdst = false; - perhapsSetRTC(t); - return true; - } else { - return false; + if (fixType >= 2) { + if (ublox.moduleQueried.gpsSecond) { + /* 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). + */ + struct tm t; + t.tm_sec = ublox.getSecond(0); + t.tm_min = ublox.getMinute(0); + t.tm_hour = ublox.getHour(0); + t.tm_mday = ublox.getDay(0); + t.tm_mon = ublox.getMonth(0) - 1; + t.tm_year = ublox.getYear(0) - 1900; + t.tm_isdst = false; + perhapsSetRTC(t); + return true; + } else { + ublox.getT(maxWait()); // ask for new time data - hopefully ready when we come back + } } + + return false; } /** @@ -165,19 +160,24 @@ bool UBloxGPS::lookForLocation() bool foundLocation = false; // we only notify if position has changed due to a new fix - if ((fixType >= 3 && fixType <= 4) && ublox.getP(maxWait())) // rd fixes only - { - latitude = ublox.getLatitude(0); - longitude = ublox.getLongitude(0); - altitude = ublox.getAltitudeMSL(0) / 1000; // in mm convert to meters - dop = ublox.getPDOP(0); // PDOP (an accuracy metric) is reported in 10^2 units so we have to scale down when we use it - heading = ublox.getHeading(0); - numSatellites = ublox.getSIV(0); + if ((fixType >= 3 && fixType <= 4)) { + if (ublox.moduleQueried.latitude) // rd fixes only + { + latitude = ublox.getLatitude(0); + longitude = ublox.getLongitude(0); + altitude = ublox.getAltitudeMSL(0) / 1000; // in mm convert to meters + dop = ublox.getPDOP(0); // PDOP (an accuracy metric) is reported in 10^2 units so we have to scale down when we use it + heading = ublox.getHeading(0); + numSatellites = ublox.getSIV(0); - // bogus lat lon is reported as 0 or 0 (can be bogus just for one) - // Also: apparently when the GPS is initially reporting lock it can output a bogus latitude > 90 deg! - foundLocation = - (latitude != 0) && (longitude != 0) && (latitude <= 900000000 && latitude >= -900000000) && (numSatellites > 0); + // bogus lat lon is reported as 0 or 0 (can be bogus just for one) + // Also: apparently when the GPS is initially reporting lock it can output a bogus latitude > 90 deg! + foundLocation = + (latitude != 0) && (longitude != 0) && (latitude <= 900000000 && latitude >= -900000000) && (numSatellites > 0); + } else { + // Ask for a new position fix - hopefully it will have results ready by next time + ublox.getP(maxWait()); + } } return foundLocation; @@ -193,10 +193,14 @@ bool UBloxGPS::whileIdle() /// Note: ublox doesn't need a wake method, because as soon as we send chars to the GPS it will wake up void UBloxGPS::sleep() { - if (isConnected) { - DEBUG_MSG("FIXME, enter low power mode\n"); - - // won't work on 6M - // ublox.powerOff(); - } + // won't work on 6M + // ublox.powerOff(); + setGPSPower(false); } + +void UBloxGPS::wake() +{ + setGPSPower(true); + // Give time for the GPS to boot + delay(200); +} \ No newline at end of file diff --git a/src/gps/UBloxGPS.h b/src/gps/UBloxGPS.h index 74ce2004..9fda4bd0 100644 --- a/src/gps/UBloxGPS.h +++ b/src/gps/UBloxGPS.h @@ -17,11 +17,6 @@ class UBloxGPS : public GPS public: UBloxGPS(); - /** - * Returns true if we succeeded - */ - virtual bool setup(); - /** * Reset our GPS back to factory settings * @@ -30,6 +25,11 @@ class UBloxGPS : public GPS bool factoryReset(); protected: + /** + * Returns true if we succeeded + */ + virtual bool setupGPS(); + /** Subclasses should look for serial rx characters here and feed it to their GPS parser * * Return true if we received a valid message from the GPS @@ -57,6 +57,7 @@ class UBloxGPS : public GPS /// If possible force the GPS into sleep/low power mode virtual void sleep(); + virtual void wake(); private: /// Attempt to connect to our GPS, returns false if no gps is present