Переглянути джерело

added serial GPS support to EnvironmentSensorClass

based on T114 serial GPS and EnvironmentSensorClass.
taco 1 рік тому
батько
коміт
a466d3cf80

+ 92 - 1
src/helpers/sensors/EnvironmentSensorManager.cpp

@@ -1,5 +1,8 @@
 #include "EnvironmentSensorManager.h"
 
+
+#include <helpers/sensors/LocationProvider.h>
+
 static Adafruit_AHTX0 AHTX0;
 static Adafruit_BME280 BME280;
 static Adafruit_INA3221 INA3221;
@@ -44,11 +47,14 @@ bool EnvironmentSensorManager::begin() {
       BME280_initialized = false;
       MESH_DEBUG_PRINTLN("BME280 was not found at I2C address %02X", TELEM_BME280_ADDRESS);
   }
-
+  initSerialGPS();
   return true;
 }
 
 bool EnvironmentSensorManager::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, 0.0f);
+  }
   next_available_channel = TELEM_CHANNEL_SELF + 1;
   if (requester_permissions & TELEM_PERM_ENVIRONMENT) {
     if (INA3221_initialized) {
@@ -86,5 +92,90 @@ bool EnvironmentSensorManager::querySensors(uint8_t requester_permissions, Cayen
     }
   }
 
+  initSerialGPS();
+
   return true;
+}
+
+
+int EnvironmentSensorManager::getNumSettings() const {
+  return gps_detected ? 1 : 0;  // only show GPS setting if GPS is detected
+}
+
+const char* EnvironmentSensorManager::getSettingName(int i) const {
+  return (gps_detected && i == 0) ? "gps" : NULL;
+}
+
+const char* EnvironmentSensorManager::getSettingValue(int i) const {
+  if (gps_detected && i == 0) {
+    return gps_active ? "1" : "0";
+  }
+  return NULL;
+}
+
+bool EnvironmentSensorManager::setSettingValue(const char* name, const char* value) {
+  if (gps_detected && strcmp(name, "gps") == 0) {
+    if (strcmp(value, "0") == 0) {
+      stop_gps();
+    } else {
+      start_gps();
+    }
+    return true;
+  }
+  return false;  // not supported
+}
+
+
+
+
+void EnvironmentSensorManager::initSerialGPS() {
+  Serial1.setPins(PIN_GPS_TX, PIN_GPS_RX);
+  Serial1.begin(9600);
+
+  // Try to detect if GPS is physically connected to determine if we should expose the setting
+  pinMode(PIN_GPS_EN, OUTPUT);
+  digitalWrite(PIN_GPS_EN, HIGH);  // Power on GPS
+
+  // Give GPS a moment to power up and send data
+  delay(1000);
+
+  // We'll consider GPS detected if we see any data on Serial1
+  gps_detected = (Serial1.available() > 0);
+
+  if (gps_detected) {
+    MESH_DEBUG_PRINTLN("GPS detected");
+    digitalWrite(PIN_GPS_EN, LOW);  // Power off GPS until the setting is changed
+  } else {
+    MESH_DEBUG_PRINTLN("No GPS detected");
+    digitalWrite(PIN_GPS_EN, LOW);
+  }
+
+}
+
+
+void EnvironmentSensorManager::start_gps() {
+  gps_active = true;
+  pinMode(PIN_GPS_EN, OUTPUT);
+  digitalWrite(PIN_GPS_EN, HIGH);
+}
+
+void EnvironmentSensorManager::stop_gps() {
+  gps_active = false;
+  pinMode(PIN_GPS_EN, OUTPUT);
+  digitalWrite(PIN_GPS_EN, LOW);
+}
+
+void EnvironmentSensorManager::loop() {
+  static long next_gps_update = 0;
+
+  _location->loop();
+
+  if (millis() > next_gps_update) {
+    if (_location->isValid()) {
+      node_lat = ((double)_location->getLatitude())/1000000.;
+      node_lon = ((double)_location->getLongitude())/1000000.;
+      MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon);
+    }
+    next_gps_update = millis() + 1000;
+  }
 }

+ 17 - 2
src/helpers/sensors/EnvironmentSensorManager.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include <helpers/SensorManager.h>
+#include <helpers/sensors/LocationProvider.h>
 #include <Mesh.h>
 #include <Adafruit_INA3221.h>
 #include <Adafruit_INA219.h>
@@ -25,8 +26,22 @@ protected:
   bool INA219_initialized = false;
   bool BME280_initialized = false;
   bool AHTX0_initialized = false;
+  
+  bool gps_active = false;
+  bool gps_detected = false;
+  LocationProvider* _location;
+
+  void start_gps();
+  void stop_gps();
+  void initSerialGPS();
+
 public:
-  EnvironmentSensorManager(){};
+  EnvironmentSensorManager(LocationProvider &location): _location(&location){};
   bool begin() override;
-  bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) 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;
 };

+ 5 - 1
variants/promicro/platformio.ini

@@ -13,6 +13,9 @@ build_flags = ${nrf52840_base.build_flags}
   -D PIN_BOARD_SDA=8
   -D PIN_OLED_RESET=-1
   -D PIN_USER_BTN=6
+  -D PIN_GPS_RX=3
+  -D PIN_GPS_TX=4
+  -D PIN_GPS_EN=5
 build_src_filter = ${nrf52840_base.build_src_filter}
   +<helpers/nrf52/PromicroBoard.cpp>
   +<helpers/sensors>  
@@ -23,7 +26,8 @@ lib_deps= ${nrf52840_base.lib_deps}
   adafruit/Adafruit INA219 @ ^1.2.3
   adafruit/Adafruit AHTX0 @ ^2.0.5
   adafruit/Adafruit BME280 Library @ ^2.3.0  
-
+  stevemarple/MicroNMEA @ ^2.0.6
+  
 [env:Faketec_Repeater]
 extends = Faketec
 build_src_filter = ${Faketec.build_src_filter}

+ 3 - 1
variants/promicro/target.cpp

@@ -1,6 +1,7 @@
 #include <Arduino.h>
 #include "target.h"
 #include <helpers/ArduinoHelpers.h>
+#include <helpers/sensors/MicroNMEALocationProvider.h>
 
 PromicroBoard board;
 
@@ -10,7 +11,8 @@ WRAPPER_CLASS radio_driver(radio, board);
 
 VolatileRTCClock fallback_clock;
 AutoDiscoverRTCClock rtc_clock(fallback_clock);
-EnvironmentSensorManager sensors;
+MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
+EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
 
 #ifdef DISPLAY_CLASS
   DISPLAY_CLASS display;