GPS/NMEA Parser that has been ported from Arduino to mbed tested with BufferedSerial original from here : http://arduiniana.org/libraries/tinygpsplus/

Dependents:   WNC_Pubnub_obd2b_ign_em506SoftSerial_RESETFE2 mbed_xbeetest

A Full-featured GPS/NMEA Parser that has been tested with BufferedSerial

TinyGPS++ is a library for parsing NMEA data streams provided by GPS modules. Like its predecessor, TinyGPS, this library provides compact and easy-to-use methods for extracting position, date, time, altitude, speed, and course from consumer GPS devices. However, TinyGPS++’s programmer interface is considerably simpler to use than TinyGPS,

The library can extract arbitrary data from any of the myriad NMEA sentences out there, even proprietary ones

from here : http://arduiniana.org/libraries/tinygpsplus/

Committer:
Sir_Binky
Date:
Fri Jan 22 08:42:46 2016 +0000
Revision:
0:3407bd06cfae
Child:
1:9163a9f5fc36
First port of tinyGPS++ by Mikal Hart

Who changed what in which revision?

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