diff --git a/variants/nano_g2_ultra/nano-g2.cpp b/variants/nano_g2_ultra/nano-g2.cpp index 731fa873..8088ddd0 100644 --- a/variants/nano_g2_ultra/nano-g2.cpp +++ b/variants/nano_g2_ultra/nano-g2.cpp @@ -27,11 +27,10 @@ void NanoG2Ultra::begin() // for future use, sub-classes SHOULD call this from their begin() startup_reason = BD_STARTUP_NORMAL; + // set user button pinMode(PIN_BUTTON1, INPUT); + // the external notification circuit is shared for both buzzer and led - // need to find out the switch state or somehow write a function that can - // sound the buzzer or signal the led. the led will stay on once brought HIGH - // and can be then brought LOW. It turns off with a hardware btn. pinMode(EXT_NOTIFY_OUT, OUTPUT); digitalWrite(EXT_NOTIFY_OUT, LOW); diff --git a/variants/nano_g2_ultra/platformio.ini b/variants/nano_g2_ultra/platformio.ini index dc8e81ac..af652e3e 100644 --- a/variants/nano_g2_ultra/platformio.ini +++ b/variants/nano_g2_ultra/platformio.ini @@ -53,4 +53,4 @@ lib_deps = densaugeo/base64 @ ~1.4.0 adafruit/Adafruit SH110X @ ~2.1.13 adafruit/Adafruit GFX Library @ ^1.12.1 - + stevemarple/MicroNMEA @ ^2.0.6 diff --git a/variants/nano_g2_ultra/target.cpp b/variants/nano_g2_ultra/target.cpp index d8c5ef8e..33824f62 100644 --- a/variants/nano_g2_ultra/target.cpp +++ b/variants/nano_g2_ultra/target.cpp @@ -1,6 +1,7 @@ #include #include "target.h" #include +#include NanoG2Ultra board; @@ -10,10 +11,11 @@ WRAPPER_CLASS radio_driver(radio, board); VolatileRTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); -SensorManager sensors; +MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); +NanoG2UltraSensorManager sensors = NanoG2UltraSensorManager(nmea); #ifdef DISPLAY_CLASS - DISPLAY_CLASS display; +DISPLAY_CLASS display; #endif #ifndef LORA_CR @@ -73,6 +75,107 @@ void radio_set_tx_power(uint8_t dbm) radio.setOutputPower(dbm); } +void NanoG2UltraSensorManager::start_gps() +{ + if (!gps_active) + { + MESH_DEBUG_PRINTLN("starting GPS"); + digitalWrite(PIN_GPS_STANDBY, HIGH); + gps_active = true; + } +} + +void NanoG2UltraSensorManager::stop_gps() +{ + if (gps_active) + { + MESH_DEBUG_PRINTLN("stopping GPS"); + digitalWrite(PIN_GPS_STANDBY, LOW); + gps_active = false; + } +} + +bool NanoG2UltraSensorManager::begin() +{ + Serial1.setPins(PIN_GPS_TX, PIN_GPS_RX); // be sure to tx into rx and rx into tx + Serial1.begin(115200); + + pinMode(PIN_GPS_STANDBY, OUTPUT); + digitalWrite(PIN_GPS_STANDBY, HIGH); // Wake GPS from standby + delay(500); + + // We'll consider GPS detected if we see any data on Serial1 + if (Serial1.available() > 0) + { + MESH_DEBUG_PRINTLN("GPS detected"); + } + else + { + MESH_DEBUG_PRINTLN("No GPS detected"); + } + digitalWrite(GPS_EN, LOW); // Put GPS back into standby mode + return true; +} + +bool NanoG2UltraSensorManager::querySensors(uint8_t requester_permissions, CayenneLPP &telemetry) +{ + if (requester_permissions & TELEM_PERM_LOCATION) + { // does requester have permission? + telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude); + } + return true; +} + +void NanoG2UltraSensorManager::loop() +{ + static long next_gps_update = 0; + _location->loop(); + if (millis() > next_gps_update && gps_active) // don't bother if gps position is not enabled + { + if (_location->isValid()) + { + node_lat = ((double)_location->getLatitude()) / 1000000.; + node_lon = ((double)_location->getLongitude()) / 1000000.; + node_altitude = ((double)_location->getAltitude()) / 1000.0; + MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon); + } + next_gps_update = millis() + (1000 * 60); // after initial update, only check every minute TODO: should be configurable + } +} + +int NanoG2UltraSensorManager::getNumSettings() const { return 1; } // just one supported: "gps" (power switch) + +const char *NanoG2UltraSensorManager::getSettingName(int i) const +{ + return i == 0 ? "gps" : NULL; +} + +const char *NanoG2UltraSensorManager::getSettingValue(int i) const +{ + if (i == 0) + { + return gps_active ? "1" : "0"; + } + return NULL; +} + +bool NanoG2UltraSensorManager::setSettingValue(const char *name, const char *value) +{ + if (strcmp(name, "gps") == 0) + { + if (strcmp(value, "0") == 0) + { + stop_gps(); + } + else + { + start_gps(); + } + return true; + } + return false; // not supported +} + mesh::LocalIdentity radio_new_identity() { RadioNoiseListener rng(radio); diff --git a/variants/nano_g2_ultra/target.h b/variants/nano_g2_ultra/target.h index b0af0a8d..e0d891e9 100644 --- a/variants/nano_g2_ultra/target.h +++ b/variants/nano_g2_ultra/target.h @@ -8,16 +8,36 @@ #include #include #ifdef DISPLAY_CLASS - #include +#include #endif +#include + +class NanoG2UltraSensorManager : public SensorManager +{ + bool gps_active = false; + LocationProvider *_location; + + void start_gps(); + void stop_gps(); + +public: + NanoG2UltraSensorManager(LocationProvider &location) : _location(&location) {} + bool begin() override; + bool querySensors(uint8_t requester_permissions, CayenneLPP &telemetry) override; + void loop() override; + int getNumSettings() const override; + const char *getSettingName(int i) const override; + const char *getSettingValue(int i) const override; + bool setSettingValue(const char *name, const char *value) override; +}; extern NanoG2Ultra board; extern WRAPPER_CLASS radio_driver; extern AutoDiscoverRTCClock rtc_clock; -extern SensorManager sensors; +extern NanoG2UltraSensorManager sensors; #ifdef DISPLAY_CLASS - extern DISPLAY_CLASS display; +extern DISPLAY_CLASS display; #endif bool radio_init(); diff --git a/variants/nano_g2_ultra/variant.h b/variants/nano_g2_ultra/variant.h index b0cc3100..b8a53fcf 100644 --- a/variants/nano_g2_ultra/variant.h +++ b/variants/nano_g2_ultra/variant.h @@ -130,11 +130,15 @@ External serial flash W25Q16JV_IQ * GPS pins */ +#define HAS_GPS 1 #define GPS_L76K #define PIN_GPS_STANDBY (0 + 13) // An output to wake GPS, low means allow sleep, high means force wake STANDBY #define PIN_GPS_TX (0 + 9) // This is for bits going TOWARDS the CPU #define PIN_GPS_RX (0 + 10) // This is for bits going TOWARDS the GPS +#define GPS_RX_PIN PIN_GPS_RX +#define GPS_TX_PIN PIN_GPS_TX + // #define GPS_THREAD_INTERVAL 50