MicroNMEALocationProvider.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #pragma once
  2. #include "LocationProvider.h"
  3. #include <MicroNMEA.h>
  4. #include <RTClib.h>
  5. #include <helpers/RefCountedDigitalPin.h>
  6. #ifndef GPS_EN
  7. #ifdef PIN_GPS_EN
  8. #define GPS_EN PIN_GPS_EN
  9. #else
  10. #define GPS_EN (-1)
  11. #endif
  12. #endif
  13. #ifndef PIN_GPS_EN_ACTIVE
  14. #define PIN_GPS_EN_ACTIVE HIGH
  15. #endif
  16. #ifndef GPS_RESET
  17. #ifdef PIN_GPS_RESET
  18. #define GPS_RESET PIN_GPS_RESET
  19. #else
  20. #define GPS_RESET (-1)
  21. #endif
  22. #endif
  23. #ifndef GPS_RESET_FORCE
  24. #ifdef PIN_GPS_RESET_ACTIVE
  25. #define GPS_RESET_FORCE PIN_GPS_RESET_ACTIVE
  26. #else
  27. #define GPS_RESET_FORCE LOW
  28. #endif
  29. #endif
  30. class MicroNMEALocationProvider : public LocationProvider {
  31. char _nmeaBuffer[100];
  32. MicroNMEA nmea;
  33. mesh::RTCClock* _clock;
  34. Stream* _gps_serial;
  35. RefCountedDigitalPin* _peripher_power;
  36. int _pin_reset;
  37. int _pin_en;
  38. long next_check = 0;
  39. long time_valid = 0;
  40. public :
  41. MicroNMEALocationProvider(Stream& ser, mesh::RTCClock* clock = NULL, int pin_reset = GPS_RESET, int pin_en = GPS_EN,RefCountedDigitalPin* peripher_power=NULL) :
  42. _gps_serial(&ser), nmea(_nmeaBuffer, sizeof(_nmeaBuffer)), _pin_reset(pin_reset), _pin_en(pin_en), _clock(clock), _peripher_power(peripher_power) {
  43. if (_pin_reset != -1) {
  44. pinMode(_pin_reset, OUTPUT);
  45. digitalWrite(_pin_reset, GPS_RESET_FORCE);
  46. }
  47. if (_pin_en != -1) {
  48. pinMode(_pin_en, OUTPUT);
  49. digitalWrite(_pin_en, LOW);
  50. }
  51. }
  52. void begin() override {
  53. if (_peripher_power) _peripher_power->claim();
  54. if (_pin_en != -1) {
  55. digitalWrite(_pin_en, PIN_GPS_EN_ACTIVE);
  56. }
  57. if (_pin_reset != -1) {
  58. digitalWrite(_pin_reset, !GPS_RESET_FORCE);
  59. }
  60. }
  61. void reset() override {
  62. if (_pin_reset != -1) {
  63. digitalWrite(_pin_reset, GPS_RESET_FORCE);
  64. delay(10);
  65. digitalWrite(_pin_reset, !GPS_RESET_FORCE);
  66. }
  67. }
  68. void stop() override {
  69. if (_pin_en != -1) {
  70. digitalWrite(_pin_en, !PIN_GPS_EN_ACTIVE);
  71. }
  72. if (_peripher_power) _peripher_power->release();
  73. }
  74. void syncTime() override { nmea.clear(); LocationProvider::syncTime(); }
  75. long getLatitude() override { return nmea.getLatitude(); }
  76. long getLongitude() override { return nmea.getLongitude(); }
  77. long getAltitude() override {
  78. long alt = 0;
  79. nmea.getAltitude(alt);
  80. return alt;
  81. }
  82. long satellitesCount() override { return nmea.getNumSatellites(); }
  83. bool isValid() override { return nmea.isValid(); }
  84. long getTimestamp() override {
  85. DateTime dt(nmea.getYear(), nmea.getMonth(),nmea.getDay(),nmea.getHour(),nmea.getMinute(),nmea.getSecond());
  86. return dt.unixtime();
  87. }
  88. void sendSentence(const char *sentence) override {
  89. nmea.sendSentence(*_gps_serial, sentence);
  90. }
  91. void loop() override {
  92. while (_gps_serial->available()) {
  93. char c = _gps_serial->read();
  94. #ifdef GPS_NMEA_DEBUG
  95. Serial.print(c);
  96. #endif
  97. nmea.process(c);
  98. }
  99. if (!isValid()) time_valid = 0;
  100. if (millis() > next_check) {
  101. next_check = millis() + 1000;
  102. if (_time_sync_needed && time_valid > 2) {
  103. if (_clock != NULL) {
  104. _clock->setCurrentTime(getTimestamp());
  105. _time_sync_needed = false;
  106. }
  107. }
  108. if (isValid()) {
  109. time_valid ++;
  110. }
  111. }
  112. }
  113. };