diff --git a/variants/t1000-e/LocationProvider.h b/variants/t1000-e/LocationProvider.h new file mode 100644 index 00000000..b5ac5812 --- /dev/null +++ b/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(); +}; diff --git a/variants/t1000-e/MicroNMEALocationProvider.h b/variants/t1000-e/MicroNMEALocationProvider.h new file mode 100644 index 00000000..da9f74f6 --- /dev/null +++ b/variants/t1000-e/MicroNMEALocationProvider.h @@ -0,0 +1,80 @@ +#pragma once + +#include "LocationProvider.h" +#include +#include + +#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); + } + } +}; \ No newline at end of file diff --git a/variants/t1000-e/platformio.ini b/variants/t1000-e/platformio.ini index e5c0d11c..aac367fe 100644 --- a/variants/t1000-e/platformio.ini +++ b/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 diff --git a/variants/t1000-e/target.cpp b/variants/t1000-e/target.cpp index 45c48fb9..770227f1 100644 --- a/variants/t1000-e/target.cpp +++ b/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; + } } diff --git a/variants/t1000-e/target.h b/variants/t1000-e/target.h index a47d05b2..a8cbcb84 100644 --- a/variants/t1000-e/target.h +++ b/variants/t1000-e/target.h @@ -1,5 +1,7 @@ #pragma once +#include "MicroNMEALocationProvider.h" + #define RADIOLIB_STATIC_ONLY 1 #include #include @@ -8,13 +10,18 @@ #include #include -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;