| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #pragma once
- #include "LocationProvider.h"
- #include <MicroNMEA.h>
- #include <RTClib.h>
- #include <helpers/RefCountedDigitalPin.h>
- #ifndef GPS_EN
- #ifdef PIN_GPS_EN
- #define GPS_EN PIN_GPS_EN
- #else
- #define GPS_EN (-1)
- #endif
- #endif
- #ifndef PIN_GPS_EN_ACTIVE
- #define PIN_GPS_EN_ACTIVE HIGH
- #endif
- #ifndef GPS_RESET
- #ifdef PIN_GPS_RESET
- #define GPS_RESET PIN_GPS_RESET
- #else
- #define GPS_RESET (-1)
- #endif
- #endif
- #ifndef GPS_RESET_FORCE
- #ifdef PIN_GPS_RESET_ACTIVE
- #define GPS_RESET_FORCE PIN_GPS_RESET_ACTIVE
- #else
- #define GPS_RESET_FORCE LOW
- #endif
- #endif
- class MicroNMEALocationProvider : public LocationProvider {
- char _nmeaBuffer[100];
- MicroNMEA nmea;
- mesh::RTCClock* _clock;
- Stream* _gps_serial;
- RefCountedDigitalPin* _peripher_power;
- int _pin_reset;
- int _pin_en;
- long next_check = 0;
- long time_valid = 0;
- public :
- MicroNMEALocationProvider(Stream& ser, mesh::RTCClock* clock = NULL, int pin_reset = GPS_RESET, int pin_en = GPS_EN,RefCountedDigitalPin* peripher_power=NULL) :
- _gps_serial(&ser), nmea(_nmeaBuffer, sizeof(_nmeaBuffer)), _pin_reset(pin_reset), _pin_en(pin_en), _clock(clock), _peripher_power(peripher_power) {
- 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 (_peripher_power) _peripher_power->claim();
- if (_pin_en != -1) {
- digitalWrite(_pin_en, PIN_GPS_EN_ACTIVE);
- }
- if (_pin_reset != -1) {
- digitalWrite(_pin_reset, !GPS_RESET_FORCE);
- }
- }
- void reset() override {
- if (_pin_reset != -1) {
- digitalWrite(_pin_reset, GPS_RESET_FORCE);
- delay(10);
- digitalWrite(_pin_reset, !GPS_RESET_FORCE);
- }
- }
- void stop() override {
- if (_pin_en != -1) {
- digitalWrite(_pin_en, !PIN_GPS_EN_ACTIVE);
- }
- if (_peripher_power) _peripher_power->release();
- }
- void syncTime() override { nmea.clear(); LocationProvider::syncTime(); }
- long getLatitude() override { return nmea.getLatitude(); }
- long getLongitude() override { return nmea.getLongitude(); }
- long getAltitude() override {
- long alt = 0;
- nmea.getAltitude(alt);
- return alt;
- }
- long satellitesCount() override { return nmea.getNumSatellites(); }
- 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 sendSentence(const char *sentence) override {
- nmea.sendSentence(*_gps_serial, sentence);
- }
- void loop() override {
- while (_gps_serial->available()) {
- char c = _gps_serial->read();
- #ifdef GPS_NMEA_DEBUG
- Serial.print(c);
- #endif
- nmea.process(c);
- }
- if (!isValid()) time_valid = 0;
- if (millis() > next_check) {
- next_check = millis() + 1000;
- if (_time_sync_needed && time_valid > 2) {
- if (_clock != NULL) {
- _clock->setCurrentTime(getTimestamp());
- _time_sync_needed = false;
- }
- }
- if (isValid()) {
- time_valid ++;
- }
- }
- }
- };
|