Ver Fonte

t1000e quick and dirty integration of gps into telemetry framework

Florent há 1 ano atrás
pai
commit
933e7ba847

+ 17 - 0
variants/t1000-e/LocationProvider.h

@@ -0,0 +1,17 @@
+#pragma once
+
+#include "Mesh.h"
+
+
+class LocationProvider {
+
+public:
+    virtual long getLatitude() = 0;
+    virtual long getLongitude() = 0;
+    virtual bool isValid() = 0;
+    virtual long getTimestamp() = 0;
+    virtual void reset();
+    virtual void begin();
+    virtual void stop();
+    virtual void loop();
+};

+ 80 - 0
variants/t1000-e/MicroNMEALocationProvider.h

@@ -0,0 +1,80 @@
+#pragma once
+
+#include "LocationProvider.h"
+#include <MicroNMEA.h>
+#include <RTClib.h>
+
+#ifndef GPS_EN
+#define GPS_EN (-1)
+#endif
+
+#ifndef GPS_RESET
+#define GPS_RESET (-1)
+#endif
+
+#ifndef GPS_RESET_FORCE
+#define GPS_RESET_FORCE LOW
+#endif
+
+class MicroNMEALocationProvider : public LocationProvider {
+    char _nmeaBuffer[100];
+    MicroNMEA nmea;
+    Stream* _gps_serial;
+    int _pin_reset;
+    int _pin_en;
+
+public :
+    MicroNMEALocationProvider(Stream& ser, int pin_reset = GPS_RESET, int pin_en = GPS_EN) :
+    _gps_serial(&ser), nmea(_nmeaBuffer, sizeof(_nmeaBuffer)), _pin_reset(pin_reset), _pin_en(pin_en) {
+        if (_pin_reset != -1) {
+            pinMode(_pin_reset, OUTPUT);
+            digitalWrite(_pin_reset, GPS_RESET_FORCE);
+        }
+        if (_pin_en != -1) {
+            pinMode(_pin_en, OUTPUT);
+            digitalWrite(_pin_en, LOW);
+        }
+    }
+
+    void begin() override {
+        if (_pin_reset != -1) {
+            digitalWrite(_pin_reset, !GPS_RESET_FORCE);
+        }
+        if (_pin_en != -1) {
+            digitalWrite(_pin_en, HIGH);
+        }
+    }
+
+    void reset() override {
+        if (_pin_reset != -1) {
+            digitalWrite(_pin_reset, GPS_RESET_FORCE);
+            delay(100);
+            digitalWrite(_pin_reset, !GPS_RESET_FORCE);
+        }
+    }
+
+    void stop() override {
+        if (_pin_en != -1) {
+            digitalWrite(_pin_en, LOW);
+        }        
+    }
+
+    long getLatitude() override { return nmea.getLatitude(); }
+    long getLongitude() override { return nmea.getLongitude(); }
+    bool isValid() override { return nmea.isValid(); }
+
+    long getTimestamp() override { 
+        DateTime dt(nmea.getYear(), nmea.getMonth(),nmea.getDay(),nmea.getHour(),nmea.getMinute(),nmea.getSecond());
+        return dt.unixtime();
+    } 
+
+    void loop() override {
+        while (_gps_serial->available()) {
+            char c = _gps_serial->read();
+            #ifdef GPS_NMEA_DEBUG
+            Serial.print(c);
+            #endif
+            nmea.process(c);
+        }
+    }
+};

+ 1 - 0
variants/t1000-e/platformio.ini

@@ -51,3 +51,4 @@ build_src_filter = ${t1000-e.build_src_filter}
   +<../examples/companion_radio/*.cpp>
 lib_deps = ${t1000-e.lib_deps}
   densaugeo/base64 @ ~1.4.0
+  stevemarple/MicroNMEA @ ^2.0.6

+ 76 - 1
variants/t1000-e/target.cpp

@@ -8,7 +8,8 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU
 WRAPPER_CLASS radio_driver(radio, board);
 
 VolatileRTCClock rtc_clock;
-T1000SensorManager sensors;
+MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
+T1000SensorManager sensors = T1000SensorManager(nmea);
 
 #ifndef LORA_CR
   #define LORA_CR      5
@@ -86,8 +87,70 @@ mesh::LocalIdentity radio_new_identity() {
   return mesh::LocalIdentity(&rng);  // create new random identity
 }
 
+void T1000SensorManager::start_gps() {
+  gps_active = true;
+  //_nmea->begin();
+  // this init sequence should be better 
+  // comes from seeed examples and deals with all gps pins
+  pinMode(GPS_EN, OUTPUT);
+  digitalWrite(GPS_EN, HIGH);
+  delay(10);
+  pinMode(GPS_VRTC_EN, OUTPUT);
+  digitalWrite(GPS_VRTC_EN, HIGH);
+  delay(10);
+       
+  pinMode(GPS_RESET, OUTPUT);
+  digitalWrite(GPS_RESET, HIGH);
+  delay(10);
+  digitalWrite(GPS_RESET, LOW);
+       
+  pinMode(GPS_SLEEP_INT, OUTPUT);
+  digitalWrite(GPS_SLEEP_INT, HIGH);
+  pinMode(GPS_RTC_INT, OUTPUT);
+  digitalWrite(GPS_RTC_INT, LOW);
+  pinMode(GPS_RESETB, INPUT_PULLUP);
+}
+
+void T1000SensorManager::sleep_gps() {
+  gps_active = false;
+  digitalWrite(GPS_VRTC_EN, HIGH);
+  digitalWrite(GPS_EN, LOW);
+  digitalWrite(GPS_RESET, HIGH);
+  digitalWrite(GPS_SLEEP_INT, HIGH);
+  digitalWrite(GPS_RTC_INT, LOW);
+  pinMode(GPS_RESETB, OUTPUT);
+  digitalWrite(GPS_RESETB, LOW);
+  //_nmea->stop();
+}
+
+void T1000SensorManager::stop_gps() {
+  gps_active = false;
+  digitalWrite(GPS_VRTC_EN, LOW);
+  digitalWrite(GPS_EN, LOW);
+  digitalWrite(GPS_RESET, HIGH);
+  digitalWrite(GPS_SLEEP_INT, HIGH);
+  digitalWrite(GPS_RTC_INT, LOW);
+  pinMode(GPS_RESETB, OUTPUT);
+  digitalWrite(GPS_RESETB, LOW);
+  //_nmea->stop();
+}
+
+
 bool T1000SensorManager::begin() {
   // TODO: init GPS
+  Serial1.begin(115200);
+
+  // make sure gps pin are off
+  digitalWrite(GPS_VRTC_EN, LOW);
+  digitalWrite(GPS_RESET, LOW);
+  digitalWrite(GPS_SLEEP_INT, LOW);
+  digitalWrite(GPS_RTC_INT, LOW);
+  pinMode(GPS_RESETB, OUTPUT);
+  digitalWrite(GPS_RESETB, LOW);
+
+  start_gps();
+
+
   return true;
 }
 
@@ -100,4 +163,16 @@ bool T1000SensorManager::querySensors(uint8_t requester_permissions, CayenneLPP&
 
 void T1000SensorManager::loop() {
   // TODO: poll GPS serial,  set _lat, _lon, _alt
+  static long next_gps_update = 0;
+
+  _nmea->loop();
+
+  if (millis() > next_gps_update) {
+    if (_nmea->isValid()) {
+      _lat = ((double)_nmea->getLatitude())/1000000.;
+      _lon = ((double)_nmea->getLongitude())/1000000.;
+      //Serial.printf("lat %f lon %f\r\n", _lat, _lon);
+    }
+    next_gps_update = millis() + 5000;
+  }
 }

+ 9 - 2
variants/t1000-e/target.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include "MicroNMEALocationProvider.h"
+
 #define RADIOLIB_STATIC_ONLY 1
 #include <RadioLib.h>
 #include <helpers/RadioLibWrappers.h>
@@ -8,13 +10,18 @@
 #include <helpers/ArduinoHelpers.h>
 #include <helpers/SensorManager.h>
 
-class T1000SensorManager : public SensorManager {
+class T1000SensorManager: public SensorManager {
   float _lat, _lon, _alt;
+  bool gps_active = false;
+  LocationProvider * _nmea;
 public:
-  T1000SensorManager(): _lat(0), _lon(0), _alt(0) { }
+  T1000SensorManager(LocationProvider &nmea): _nmea(&nmea), _lat(0), _lon(0), _alt(0) { }
   bool begin() override;
   bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
   void loop() override;
+  void start_gps();
+  void sleep_gps();
+  void stop_gps();
 };
 
 extern T1000eBoard board;