A port of Mikal Hart's TinyGPS++ version 1.0.2 to mbed.

Dependents:   TinyGPSPlus-example PROJ515_GPS PROJ515_USS_GPS example-ttn-workshop

Committer:
aoba
Date:
Sat Feb 02 06:47:02 2019 +0000
Revision:
0:6d3813637f20
ported version 1.0.2 into Mbed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aoba 0:6d3813637f20 1 /*
aoba 0:6d3813637f20 2 TinyGPS++ - a small GPS library for Arduino providing universal NMEA parsing
aoba 0:6d3813637f20 3 Based on work by and "distanceBetween" and "courseTo" courtesy of Maarten Lamers.
aoba 0:6d3813637f20 4 Suggestion to add satellites, courseTo(), and cardinal() by Matt Monson.
aoba 0:6d3813637f20 5 Location precision improvements suggested by Wayne Holder.
aoba 0:6d3813637f20 6 Copyright (C) 2008-2013 Mikal Hart
aoba 0:6d3813637f20 7 All rights reserved.
aoba 0:6d3813637f20 8
aoba 0:6d3813637f20 9 This library is free software; you can redistribute it and/or
aoba 0:6d3813637f20 10 modify it under the terms of the GNU Lesser General Public
aoba 0:6d3813637f20 11 License as published by the Free Software Foundation; either
aoba 0:6d3813637f20 12 version 2.1 of the License, or (at your option) any later version.
aoba 0:6d3813637f20 13
aoba 0:6d3813637f20 14 This library is distributed in the hope that it will be useful,
aoba 0:6d3813637f20 15 but WITHOUT ANY WARRANTY; without even the implied warranty of
aoba 0:6d3813637f20 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
aoba 0:6d3813637f20 17 Lesser General Public License for more details.
aoba 0:6d3813637f20 18
aoba 0:6d3813637f20 19 You should have received a copy of the GNU Lesser General Public
aoba 0:6d3813637f20 20 License along with this library; if not, write to the Free Software
aoba 0:6d3813637f20 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
aoba 0:6d3813637f20 22 */
aoba 0:6d3813637f20 23
aoba 0:6d3813637f20 24 #ifndef __TinyGPSPlus_h
aoba 0:6d3813637f20 25 #define __TinyGPSPlus_h
aoba 0:6d3813637f20 26
aoba 0:6d3813637f20 27 #include <inttypes.h>
aoba 0:6d3813637f20 28 unsigned long millis(void);
aoba 0:6d3813637f20 29
aoba 0:6d3813637f20 30 #include <limits.h>
aoba 0:6d3813637f20 31
aoba 0:6d3813637f20 32 #define _GPS_VERSION "1.0.2" // software version of this library
aoba 0:6d3813637f20 33 #define _GPS_MPH_PER_KNOT 1.15077945
aoba 0:6d3813637f20 34 #define _GPS_MPS_PER_KNOT 0.51444444
aoba 0:6d3813637f20 35 #define _GPS_KMPH_PER_KNOT 1.852
aoba 0:6d3813637f20 36 #define _GPS_MILES_PER_METER 0.00062137112
aoba 0:6d3813637f20 37 #define _GPS_KM_PER_METER 0.001
aoba 0:6d3813637f20 38 #define _GPS_FEET_PER_METER 3.2808399
aoba 0:6d3813637f20 39 #define _GPS_MAX_FIELD_SIZE 15
aoba 0:6d3813637f20 40
aoba 0:6d3813637f20 41 struct RawDegrees
aoba 0:6d3813637f20 42 {
aoba 0:6d3813637f20 43 uint16_t deg;
aoba 0:6d3813637f20 44 uint32_t billionths;
aoba 0:6d3813637f20 45 bool negative;
aoba 0:6d3813637f20 46 public:
aoba 0:6d3813637f20 47 RawDegrees() : deg(0), billionths(0), negative(false)
aoba 0:6d3813637f20 48 {}
aoba 0:6d3813637f20 49 };
aoba 0:6d3813637f20 50
aoba 0:6d3813637f20 51 struct TinyGPSLocation
aoba 0:6d3813637f20 52 {
aoba 0:6d3813637f20 53 friend class TinyGPSPlus;
aoba 0:6d3813637f20 54 public:
aoba 0:6d3813637f20 55 bool isValid() const { return valid; }
aoba 0:6d3813637f20 56 bool isUpdated() const { return updated; }
aoba 0:6d3813637f20 57 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
aoba 0:6d3813637f20 58 const RawDegrees &rawLat() { updated = false; return rawLatData; }
aoba 0:6d3813637f20 59 const RawDegrees &rawLng() { updated = false; return rawLngData; }
aoba 0:6d3813637f20 60 double lat();
aoba 0:6d3813637f20 61 double lng();
aoba 0:6d3813637f20 62
aoba 0:6d3813637f20 63 TinyGPSLocation() : valid(false), updated(false)
aoba 0:6d3813637f20 64 {}
aoba 0:6d3813637f20 65
aoba 0:6d3813637f20 66 private:
aoba 0:6d3813637f20 67 bool valid, updated;
aoba 0:6d3813637f20 68 RawDegrees rawLatData, rawLngData, rawNewLatData, rawNewLngData;
aoba 0:6d3813637f20 69 uint32_t lastCommitTime;
aoba 0:6d3813637f20 70 void commit();
aoba 0:6d3813637f20 71 void setLatitude(const char *term);
aoba 0:6d3813637f20 72 void setLongitude(const char *term);
aoba 0:6d3813637f20 73 };
aoba 0:6d3813637f20 74
aoba 0:6d3813637f20 75 struct TinyGPSDate
aoba 0:6d3813637f20 76 {
aoba 0:6d3813637f20 77 friend class TinyGPSPlus;
aoba 0:6d3813637f20 78 public:
aoba 0:6d3813637f20 79 bool isValid() const { return valid; }
aoba 0:6d3813637f20 80 bool isUpdated() const { return updated; }
aoba 0:6d3813637f20 81 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
aoba 0:6d3813637f20 82
aoba 0:6d3813637f20 83 uint32_t value() { updated = false; return date; }
aoba 0:6d3813637f20 84 uint16_t year();
aoba 0:6d3813637f20 85 uint8_t month();
aoba 0:6d3813637f20 86 uint8_t day();
aoba 0:6d3813637f20 87
aoba 0:6d3813637f20 88 TinyGPSDate() : valid(false), updated(false), date(0)
aoba 0:6d3813637f20 89 {}
aoba 0:6d3813637f20 90
aoba 0:6d3813637f20 91 private:
aoba 0:6d3813637f20 92 bool valid, updated;
aoba 0:6d3813637f20 93 uint32_t date, newDate;
aoba 0:6d3813637f20 94 uint32_t lastCommitTime;
aoba 0:6d3813637f20 95 void commit();
aoba 0:6d3813637f20 96 void setDate(const char *term);
aoba 0:6d3813637f20 97 };
aoba 0:6d3813637f20 98
aoba 0:6d3813637f20 99 struct TinyGPSTime
aoba 0:6d3813637f20 100 {
aoba 0:6d3813637f20 101 friend class TinyGPSPlus;
aoba 0:6d3813637f20 102 public:
aoba 0:6d3813637f20 103 bool isValid() const { return valid; }
aoba 0:6d3813637f20 104 bool isUpdated() const { return updated; }
aoba 0:6d3813637f20 105 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
aoba 0:6d3813637f20 106
aoba 0:6d3813637f20 107 uint32_t value() { updated = false; return time; }
aoba 0:6d3813637f20 108 uint8_t hour();
aoba 0:6d3813637f20 109 uint8_t minute();
aoba 0:6d3813637f20 110 uint8_t second();
aoba 0:6d3813637f20 111 uint8_t centisecond();
aoba 0:6d3813637f20 112
aoba 0:6d3813637f20 113 TinyGPSTime() : valid(false), updated(false), time(0)
aoba 0:6d3813637f20 114 {}
aoba 0:6d3813637f20 115
aoba 0:6d3813637f20 116 private:
aoba 0:6d3813637f20 117 bool valid, updated;
aoba 0:6d3813637f20 118 uint32_t time, newTime;
aoba 0:6d3813637f20 119 uint32_t lastCommitTime;
aoba 0:6d3813637f20 120 void commit();
aoba 0:6d3813637f20 121 void setTime(const char *term);
aoba 0:6d3813637f20 122 };
aoba 0:6d3813637f20 123
aoba 0:6d3813637f20 124 struct TinyGPSDecimal
aoba 0:6d3813637f20 125 {
aoba 0:6d3813637f20 126 friend class TinyGPSPlus;
aoba 0:6d3813637f20 127 public:
aoba 0:6d3813637f20 128 bool isValid() const { return valid; }
aoba 0:6d3813637f20 129 bool isUpdated() const { return updated; }
aoba 0:6d3813637f20 130 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
aoba 0:6d3813637f20 131 int32_t value() { updated = false; return val; }
aoba 0:6d3813637f20 132
aoba 0:6d3813637f20 133 TinyGPSDecimal() : valid(false), updated(false), val(0)
aoba 0:6d3813637f20 134 {}
aoba 0:6d3813637f20 135
aoba 0:6d3813637f20 136 private:
aoba 0:6d3813637f20 137 bool valid, updated;
aoba 0:6d3813637f20 138 uint32_t lastCommitTime;
aoba 0:6d3813637f20 139 int32_t val, newval;
aoba 0:6d3813637f20 140 void commit();
aoba 0:6d3813637f20 141 void set(const char *term);
aoba 0:6d3813637f20 142 };
aoba 0:6d3813637f20 143
aoba 0:6d3813637f20 144 struct TinyGPSInteger
aoba 0:6d3813637f20 145 {
aoba 0:6d3813637f20 146 friend class TinyGPSPlus;
aoba 0:6d3813637f20 147 public:
aoba 0:6d3813637f20 148 bool isValid() const { return valid; }
aoba 0:6d3813637f20 149 bool isUpdated() const { return updated; }
aoba 0:6d3813637f20 150 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
aoba 0:6d3813637f20 151 uint32_t value() { updated = false; return val; }
aoba 0:6d3813637f20 152
aoba 0:6d3813637f20 153 TinyGPSInteger() : valid(false), updated(false), val(0)
aoba 0:6d3813637f20 154 {}
aoba 0:6d3813637f20 155
aoba 0:6d3813637f20 156 private:
aoba 0:6d3813637f20 157 bool valid, updated;
aoba 0:6d3813637f20 158 uint32_t lastCommitTime;
aoba 0:6d3813637f20 159 uint32_t val, newval;
aoba 0:6d3813637f20 160 void commit();
aoba 0:6d3813637f20 161 void set(const char *term);
aoba 0:6d3813637f20 162 };
aoba 0:6d3813637f20 163
aoba 0:6d3813637f20 164 struct TinyGPSSpeed : TinyGPSDecimal
aoba 0:6d3813637f20 165 {
aoba 0:6d3813637f20 166 double knots() { return value() / 100.0; }
aoba 0:6d3813637f20 167 double mph() { return _GPS_MPH_PER_KNOT * value() / 100.0; }
aoba 0:6d3813637f20 168 double mps() { return _GPS_MPS_PER_KNOT * value() / 100.0; }
aoba 0:6d3813637f20 169 double kmph() { return _GPS_KMPH_PER_KNOT * value() / 100.0; }
aoba 0:6d3813637f20 170 };
aoba 0:6d3813637f20 171
aoba 0:6d3813637f20 172 struct TinyGPSCourse : public TinyGPSDecimal
aoba 0:6d3813637f20 173 {
aoba 0:6d3813637f20 174 double deg() { return value() / 100.0; }
aoba 0:6d3813637f20 175 };
aoba 0:6d3813637f20 176
aoba 0:6d3813637f20 177 struct TinyGPSAltitude : TinyGPSDecimal
aoba 0:6d3813637f20 178 {
aoba 0:6d3813637f20 179 double meters() { return value() / 100.0; }
aoba 0:6d3813637f20 180 double miles() { return _GPS_MILES_PER_METER * value() / 100.0; }
aoba 0:6d3813637f20 181 double kilometers() { return _GPS_KM_PER_METER * value() / 100.0; }
aoba 0:6d3813637f20 182 double feet() { return _GPS_FEET_PER_METER * value() / 100.0; }
aoba 0:6d3813637f20 183 };
aoba 0:6d3813637f20 184
aoba 0:6d3813637f20 185 struct TinyGPSHDOP : TinyGPSDecimal
aoba 0:6d3813637f20 186 {
aoba 0:6d3813637f20 187 double hdop() { return value() / 100.0; }
aoba 0:6d3813637f20 188 };
aoba 0:6d3813637f20 189
aoba 0:6d3813637f20 190 class TinyGPSPlus;
aoba 0:6d3813637f20 191 class TinyGPSCustom
aoba 0:6d3813637f20 192 {
aoba 0:6d3813637f20 193 public:
aoba 0:6d3813637f20 194 TinyGPSCustom() {};
aoba 0:6d3813637f20 195 TinyGPSCustom(TinyGPSPlus &gps, const char *sentenceName, int termNumber);
aoba 0:6d3813637f20 196 void begin(TinyGPSPlus &gps, const char *_sentenceName, int _termNumber);
aoba 0:6d3813637f20 197
aoba 0:6d3813637f20 198 bool isUpdated() const { return updated; }
aoba 0:6d3813637f20 199 bool isValid() const { return valid; }
aoba 0:6d3813637f20 200 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
aoba 0:6d3813637f20 201 const char *value() { updated = false; return buffer; }
aoba 0:6d3813637f20 202
aoba 0:6d3813637f20 203 private:
aoba 0:6d3813637f20 204 void commit();
aoba 0:6d3813637f20 205 void set(const char *term);
aoba 0:6d3813637f20 206
aoba 0:6d3813637f20 207 char stagingBuffer[_GPS_MAX_FIELD_SIZE + 1];
aoba 0:6d3813637f20 208 char buffer[_GPS_MAX_FIELD_SIZE + 1];
aoba 0:6d3813637f20 209 unsigned long lastCommitTime;
aoba 0:6d3813637f20 210 bool valid, updated;
aoba 0:6d3813637f20 211 const char *sentenceName;
aoba 0:6d3813637f20 212 int termNumber;
aoba 0:6d3813637f20 213 friend class TinyGPSPlus;
aoba 0:6d3813637f20 214 TinyGPSCustom *next;
aoba 0:6d3813637f20 215 };
aoba 0:6d3813637f20 216
aoba 0:6d3813637f20 217 class TinyGPSPlus
aoba 0:6d3813637f20 218 {
aoba 0:6d3813637f20 219 public:
aoba 0:6d3813637f20 220 TinyGPSPlus();
aoba 0:6d3813637f20 221 bool encode(char c); // process one character received from GPS
aoba 0:6d3813637f20 222 TinyGPSPlus &operator << (char c) {encode(c); return *this;}
aoba 0:6d3813637f20 223
aoba 0:6d3813637f20 224 TinyGPSLocation location;
aoba 0:6d3813637f20 225 TinyGPSDate date;
aoba 0:6d3813637f20 226 TinyGPSTime time;
aoba 0:6d3813637f20 227 TinyGPSSpeed speed;
aoba 0:6d3813637f20 228 TinyGPSCourse course;
aoba 0:6d3813637f20 229 TinyGPSAltitude altitude;
aoba 0:6d3813637f20 230 TinyGPSInteger satellites;
aoba 0:6d3813637f20 231 TinyGPSHDOP hdop;
aoba 0:6d3813637f20 232
aoba 0:6d3813637f20 233 static const char *libraryVersion() { return _GPS_VERSION; }
aoba 0:6d3813637f20 234
aoba 0:6d3813637f20 235 static double distanceBetween(double lat1, double long1, double lat2, double long2);
aoba 0:6d3813637f20 236 static double courseTo(double lat1, double long1, double lat2, double long2);
aoba 0:6d3813637f20 237 static const char *cardinal(double course);
aoba 0:6d3813637f20 238
aoba 0:6d3813637f20 239 static int32_t parseDecimal(const char *term);
aoba 0:6d3813637f20 240 static void parseDegrees(const char *term, RawDegrees &deg);
aoba 0:6d3813637f20 241
aoba 0:6d3813637f20 242 uint32_t charsProcessed() const { return encodedCharCount; }
aoba 0:6d3813637f20 243 uint32_t sentencesWithFix() const { return sentencesWithFixCount; }
aoba 0:6d3813637f20 244 uint32_t failedChecksum() const { return failedChecksumCount; }
aoba 0:6d3813637f20 245 uint32_t passedChecksum() const { return passedChecksumCount; }
aoba 0:6d3813637f20 246
aoba 0:6d3813637f20 247 private:
aoba 0:6d3813637f20 248 enum {GPS_SENTENCE_GPGGA, GPS_SENTENCE_GPRMC, GPS_SENTENCE_OTHER};
aoba 0:6d3813637f20 249
aoba 0:6d3813637f20 250 // parsing state variables
aoba 0:6d3813637f20 251 uint8_t parity;
aoba 0:6d3813637f20 252 bool isChecksumTerm;
aoba 0:6d3813637f20 253 char term[_GPS_MAX_FIELD_SIZE];
aoba 0:6d3813637f20 254 uint8_t curSentenceType;
aoba 0:6d3813637f20 255 uint8_t curTermNumber;
aoba 0:6d3813637f20 256 uint8_t curTermOffset;
aoba 0:6d3813637f20 257 bool sentenceHasFix;
aoba 0:6d3813637f20 258
aoba 0:6d3813637f20 259 // custom element support
aoba 0:6d3813637f20 260 friend class TinyGPSCustom;
aoba 0:6d3813637f20 261 TinyGPSCustom *customElts;
aoba 0:6d3813637f20 262 TinyGPSCustom *customCandidates;
aoba 0:6d3813637f20 263 void insertCustom(TinyGPSCustom *pElt, const char *sentenceName, int index);
aoba 0:6d3813637f20 264
aoba 0:6d3813637f20 265 // statistics
aoba 0:6d3813637f20 266 uint32_t encodedCharCount;
aoba 0:6d3813637f20 267 uint32_t sentencesWithFixCount;
aoba 0:6d3813637f20 268 uint32_t failedChecksumCount;
aoba 0:6d3813637f20 269 uint32_t passedChecksumCount;
aoba 0:6d3813637f20 270
aoba 0:6d3813637f20 271 // internal utilities
aoba 0:6d3813637f20 272 int fromHex(char a);
aoba 0:6d3813637f20 273 bool endOfTermHandler();
aoba 0:6d3813637f20 274 };
aoba 0:6d3813637f20 275
aoba 0:6d3813637f20 276 #endif // def(__TinyGPSPlus_h)