begin cleanup on gps code

1.2-legacy
geeksville 2020-02-06 07:39:21 -08:00
rodzic 0050e4b05a
commit 0b226132b8
10 zmienionych plików z 180 dodań i 78 usunięć

Wyświetl plik

@ -33,8 +33,17 @@
* How do avalanche beacons work? Could this do that as well? possibly by using beacon mode feature of the RF95? * How do avalanche beacons work? Could this do that as well? possibly by using beacon mode feature of the RF95?
* use std::map<BLECharacteristic*, std::string> in node db * use std::map<BLECharacteristic*, std::string> in node db
# Low power consumption tasks
* stop using loop() instead use a job queue and let cpu sleep
* move lora rx/tx to own thread and block on IO
* measure power consumption and calculate battery life assuming no deep sleep
* do lowest sleep level possible where BT still works during normal sleeping, make sure cpu stays in that mode unless lora rx packet happens, bt rx packet happens or button press happens
* optionally do lora messaging only during special scheduled intervals (unless nodes are told to go to low latency mode), then deep sleep except during those intervals - before implementing calculate what battery life would be with this feature
# Pre-beta priority # Pre-beta priority
* use variable length arduino Strings in protobufs (instead of current fixed buffers)
* don't even power on bluetooth until we have some data to send to the android phone. Most of the time we should be sleeping in a lowpower "listening for lora" only mode. Once we have some packets for the phone, then power on bluetooth * don't even power on bluetooth until we have some data to send to the android phone. Most of the time we should be sleeping in a lowpower "listening for lora" only mode. Once we have some packets for the phone, then power on bluetooth
until the phone pulls those packets. Ever so often power on bluetooth just so we can see if the phone wants to send some packets. Possibly might need ULP processor to help with this wake process. until the phone pulls those packets. Ever so often power on bluetooth just so we can see if the phone wants to send some packets. Possibly might need ULP processor to help with this wake process.
* do hibernation mode to get power draw down to 2.5uA https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/ * do hibernation mode to get power draw down to 2.5uA https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/

Wyświetl plik

@ -20,7 +20,7 @@ framework = arduino
board_build.partitions = partition-table.csv board_build.partitions = partition-table.csv
; note: we add src to our include search path so that lmic_project_config can override ; note: we add src to our include search path so that lmic_project_config can override
build_flags = -Wall -Wextra -Wno-missing-field-initializers -Isrc -O3 -Wl,-Map,.pio/build/esp32/output.map -DAXP_DEBUG_PORT=Serial build_flags = -Wall -Wextra -Wno-missing-field-initializers -Isrc -Os -Wl,-Map,.pio/build/esp32/output.map -DAXP_DEBUG_PORT=Serial
; not needed included in ttgo-t-beam board file ; not needed included in ttgo-t-beam board file
; also to use PSRAM https://docs.platformio.org/en/latest/platforms/espressif32.html#external-ram-psram ; also to use PSRAM https://docs.platformio.org/en/latest/platforms/espressif32.html#external-ram-psram

42
src/GPS.cpp 100644
Wyświetl plik

@ -0,0 +1,42 @@
#include "GPS.h"
HardwareSerial _serial_gps(GPS_SERIAL_NUM);
GPS gps;
GPS::GPS() : PeriodicTask(30 * 1000)
{
}
void GPS::setup()
{
#ifdef GPS_RX_PIN
_serial_gps.begin(GPS_BAUDRATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
#endif
}
void GPS::loop()
{
PeriodicTask::loop();
#ifdef GPX_RX_PIN
while (_serial_gps.available())
{
_gps.encode(_serial_gps.read());
}
#endif
}
void GPS::doTask()
{
}
String GPS::getTime()
{
static char t[12]; // used to sprintf for Serial output
snprintf(t, sizeof(t), "%02d:%02d:%02d", time.hour(), time.minute(), time.second());
return t;
}

26
src/GPS.h 100644
Wyświetl plik

@ -0,0 +1,26 @@
#pragma once
#include <TinyGPS++.h>
#include "PeriodicTask.h"
#include "Observer.h"
/**
* A gps class that only reads from the GPS periodically (and FIXME - eventually keeps the gps powered down except when reading)
*
* When new data is available it will notify observers.
*/
class GPS : public PeriodicTask, public Observable, public TinyGPSPlus
{
public:
GPS();
String getTime();
void setup();
virtual void loop();
virtual void doTask();
};
extern GPS gps;

13
src/Observer.cpp 100644
Wyświetl plik

@ -0,0 +1,13 @@
#include "Observer.h"
Observer::~Observer()
{
if (observed)
observed->removeObserver(this);
observed = NULL;
}
void Observer::observe(Observable *o)
{
o->addObserver(this);
}

46
src/Observer.h 100644
Wyświetl plik

@ -0,0 +1,46 @@
#pragma once
#include <Arduino.h>
#include <list>
class Observable;
class Observer
{
Observable *observed;
public:
Observer() : observed(NULL) {}
virtual ~Observer();
void observe(Observable *o);
virtual void onNotify(Observable *o) = 0;
};
class Observable
{
std::list<Observer *> observers;
public:
void notifyObservers()
{
for (std::list<Observer *>::const_iterator iterator = observers.begin(); iterator != observers.end(); ++iterator)
{
(*iterator)->onNotify(this);
}
}
void addObserver(Observer *o)
{
observers.push_back(o);
}
void removeObserver(Observer *o)
{
observers.remove(o);
}
};

36
src/PeriodicTask.h 100644
Wyświetl plik

@ -0,0 +1,36 @@
#pragma once
#include <Arduino.h>
#include "configuration.h"
class PeriodicTask
{
/// we use prevMsec rather than nextMsec because it is easier to handle the uint32 rollover in that case, also changes in periodMsec take effect immediately
uint32_t prevMsec;
public:
uint32_t periodMsec;
virtual ~PeriodicTask() {}
PeriodicTask(uint32_t period) : periodMsec(period)
{
prevMsec = millis();
}
/// call this from loop
virtual void loop()
{
uint32_t now = millis();
if (now > (prevMsec + periodMsec))
{
// FIXME, this lets period slightly drift based on scheduling - not sure if that is always good
prevMsec = now;
DEBUG_MSG("Calling periodic task\n");
doTask();
}
}
virtual void doTask() = 0;
};

Wyświetl plik

@ -1,70 +0,0 @@
/*
GPS module
Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <TinyGPS++.h>
uint32_t LatitudeBinary;
uint32_t LongitudeBinary;
uint16_t altitudeGps;
uint8_t hdopGps;
uint8_t sats;
char t[32]; // used to sprintf for Serial output
TinyGPSPlus _gps;
HardwareSerial _serial_gps(GPS_SERIAL_NUM);
void gps_time(char * buffer, uint8_t size) {
snprintf(buffer, size, "%02d:%02d:%02d", _gps.time.hour(), _gps.time.minute(), _gps.time.second());
}
float gps_latitude() {
return _gps.location.lat();
}
float gps_longitude() {
return _gps.location.lng();
}
float gps_altitude() {
return _gps.altitude.meters();
}
float gps_hdop() {
return _gps.hdop.hdop();
}
uint8_t gps_sats() {
return _gps.satellites.value();
}
void gps_setup() {
#ifdef GPS_RX_PIN
_serial_gps.begin(GPS_BAUDRATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
#endif
}
static void gps_loop() {
#ifdef GPX_RX_PIN
while (_serial_gps.available()) {
_gps.encode(_serial_gps.read());
}
#endif
}

Wyświetl plik

@ -29,6 +29,7 @@
#include "BluetoothUtil.h" #include "BluetoothUtil.h"
#include "MeshBluetoothService.h" #include "MeshBluetoothService.h"
#include "MeshService.h" #include "MeshService.h"
#include "GPS.h"
#ifdef T_BEAM_V10 #ifdef T_BEAM_V10
#include "axp20x.h" #include "axp20x.h"
@ -348,7 +349,7 @@ void setup()
screen_setup(); screen_setup();
// Init GPS // Init GPS
gps_setup(); gps.setup();
// Show logo on first boot after removing battery // Show logo on first boot after removing battery
//if (bootCount == 0) { //if (bootCount == 0) {
@ -371,7 +372,7 @@ void setup()
void loop() void loop()
{ {
gps_loop(); gps.loop();
screen_loop(); screen_loop();
service.loop(); service.loop();
loopBLE(); loopBLE();

Wyświetl plik

@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "OLEDDisplay.h" #include "OLEDDisplay.h"
#include "images.h" #include "images.h"
#include "fonts.h" #include "fonts.h"
#include "GPS.h"
#define SCREEN_HEADER_HEIGHT 14 #define SCREEN_HEADER_HEIGHT 14
@ -34,21 +35,19 @@ uint8_t _screen_line = SCREEN_HEADER_HEIGHT - 1;
void _screen_header() { void _screen_header() {
if(!display) return; if(!display) return;
char buffer[20];
// Message count // Message count
//snprintf(buffer, sizeof(buffer), "#%03d", ttn_get_count() % 1000); //snprintf(buffer, sizeof(buffer), "#%03d", ttn_get_count() % 1000);
//display->setTextAlignment(TEXT_ALIGN_LEFT); //display->setTextAlignment(TEXT_ALIGN_LEFT);
//display->drawString(0, 2, buffer); //display->drawString(0, 2, buffer);
// Datetime // Datetime
gps_time(buffer, sizeof(buffer));
display->setTextAlignment(TEXT_ALIGN_CENTER); display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(display->getWidth()/2, 2, buffer); display->drawString(display->getWidth()/2, 2, gps.getTime());
// Satellite count // Satellite count
display->setTextAlignment(TEXT_ALIGN_RIGHT); display->setTextAlignment(TEXT_ALIGN_RIGHT);
display->drawString(display->getWidth() - SATELLITE_IMAGE_WIDTH - 4, 2, itoa(gps_sats(), buffer, 10)); char buffer[10];
display->drawString(display->getWidth() - SATELLITE_IMAGE_WIDTH - 4, 2, itoa(gps.satellites.value(), buffer, 10));
display->drawXbm(display->getWidth() - SATELLITE_IMAGE_WIDTH, 0, SATELLITE_IMAGE_WIDTH, SATELLITE_IMAGE_HEIGHT, SATELLITE_IMAGE); display->drawXbm(display->getWidth() - SATELLITE_IMAGE_WIDTH, 0, SATELLITE_IMAGE_WIDTH, SATELLITE_IMAGE_HEIGHT, SATELLITE_IMAGE);
} }