ソースを参照

add GPS for nano g2

hardcoded interval of 1 minute after first fix obtained
Rob Loranger 1 年間 前
コミット
4a90042b08

+ 2 - 3
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);
 

+ 1 - 1
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

+ 105 - 2
variants/nano_g2_ultra/target.cpp

@@ -1,6 +1,7 @@
 #include <Arduino.h>
 #include "target.h"
 #include <helpers/ArduinoHelpers.h>
+#include <helpers/sensors/MicroNMEALocationProvider.h>
 
 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);

+ 23 - 3
variants/nano_g2_ultra/target.h

@@ -8,16 +8,36 @@
 #include <helpers/AutoDiscoverRTCClock.h>
 #include <helpers/SensorManager.h>
 #ifdef DISPLAY_CLASS
-  #include <helpers/ui/SH1106Display.h>
+#include <helpers/ui/SH1106Display.h>
 #endif
+#include <helpers/sensors/LocationProvider.h>
+
+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();

+ 4 - 0
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