A port of Mikal Hart's TinyGPS++ version 1.0.2 to mbed.
Dependents: TinyGPSPlus-example PROJ515_GPS PROJ515_USS_GPS example-ttn-workshop
TinyGPSPlus.h@0:6d3813637f20, 2019-02-02 (annotated)
- 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?
User | Revision | Line number | New 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 °); |
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) |