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 13:30:33 2016 +0000
Revision:
1:9163a9f5fc36
Parent:
0:3407bd06cfae
added a "Binary" version of the lat and lng; Binary representation of the double;

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 1:9163a9f5fc36 64 int32_t lngBinary();
Sir_Binky 1:9163a9f5fc36 65 int32_t latBinary();
Sir_Binky 0:3407bd06cfae 66
Sir_Binky 0:3407bd06cfae 67 TinyGPSLocation() : valid(false), updated(false)
Sir_Binky 0:3407bd06cfae 68 {}
Sir_Binky 0:3407bd06cfae 69
Sir_Binky 0:3407bd06cfae 70 private:
Sir_Binky 0:3407bd06cfae 71 bool valid, updated;
Sir_Binky 0:3407bd06cfae 72 RawDegrees rawLatData, rawLngData, rawNewLatData, rawNewLngData;
Sir_Binky 0:3407bd06cfae 73 uint32_t lastCommitTime;
Sir_Binky 0:3407bd06cfae 74 void commit();
Sir_Binky 0:3407bd06cfae 75 void setLatitude(const char *term);
Sir_Binky 0:3407bd06cfae 76 void setLongitude(const char *term);
Sir_Binky 0:3407bd06cfae 77 };
Sir_Binky 0:3407bd06cfae 78
Sir_Binky 0:3407bd06cfae 79 struct TinyGPSDate
Sir_Binky 0:3407bd06cfae 80 {
Sir_Binky 0:3407bd06cfae 81 friend class TinyGPSPlus;
Sir_Binky 0:3407bd06cfae 82 public:
Sir_Binky 0:3407bd06cfae 83 bool isValid() const { return valid; }
Sir_Binky 0:3407bd06cfae 84 bool isUpdated() const { return updated; }
Sir_Binky 0:3407bd06cfae 85 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
Sir_Binky 0:3407bd06cfae 86
Sir_Binky 0:3407bd06cfae 87 uint32_t value() { updated = false; return date; }
Sir_Binky 0:3407bd06cfae 88 uint16_t year();
Sir_Binky 0:3407bd06cfae 89 uint8_t month();
Sir_Binky 0:3407bd06cfae 90 uint8_t day();
Sir_Binky 0:3407bd06cfae 91
Sir_Binky 0:3407bd06cfae 92 TinyGPSDate() : valid(false), updated(false), date(0)
Sir_Binky 0:3407bd06cfae 93 {}
Sir_Binky 0:3407bd06cfae 94
Sir_Binky 0:3407bd06cfae 95 private:
Sir_Binky 0:3407bd06cfae 96 bool valid, updated;
Sir_Binky 0:3407bd06cfae 97 uint32_t date, newDate;
Sir_Binky 0:3407bd06cfae 98 uint32_t lastCommitTime;
Sir_Binky 0:3407bd06cfae 99 void commit();
Sir_Binky 0:3407bd06cfae 100 void setDate(const char *term);
Sir_Binky 0:3407bd06cfae 101 };
Sir_Binky 0:3407bd06cfae 102
Sir_Binky 0:3407bd06cfae 103 struct TinyGPSTime
Sir_Binky 0:3407bd06cfae 104 {
Sir_Binky 0:3407bd06cfae 105 friend class TinyGPSPlus;
Sir_Binky 0:3407bd06cfae 106 public:
Sir_Binky 0:3407bd06cfae 107 bool isValid() const { return valid; }
Sir_Binky 0:3407bd06cfae 108 bool isUpdated() const { return updated; }
Sir_Binky 0:3407bd06cfae 109 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
Sir_Binky 0:3407bd06cfae 110
Sir_Binky 0:3407bd06cfae 111 uint32_t value() { updated = false; return time; }
Sir_Binky 0:3407bd06cfae 112 uint8_t hour();
Sir_Binky 0:3407bd06cfae 113 uint8_t minute();
Sir_Binky 0:3407bd06cfae 114 uint8_t second();
Sir_Binky 0:3407bd06cfae 115 uint8_t centisecond();
Sir_Binky 0:3407bd06cfae 116
Sir_Binky 0:3407bd06cfae 117 TinyGPSTime() : valid(false), updated(false), time(0)
Sir_Binky 0:3407bd06cfae 118 {}
Sir_Binky 0:3407bd06cfae 119
Sir_Binky 0:3407bd06cfae 120 private:
Sir_Binky 0:3407bd06cfae 121 bool valid, updated;
Sir_Binky 0:3407bd06cfae 122 uint32_t time, newTime;
Sir_Binky 0:3407bd06cfae 123 uint32_t lastCommitTime;
Sir_Binky 0:3407bd06cfae 124 void commit();
Sir_Binky 0:3407bd06cfae 125 void setTime(const char *term);
Sir_Binky 0:3407bd06cfae 126 };
Sir_Binky 0:3407bd06cfae 127
Sir_Binky 0:3407bd06cfae 128 struct TinyGPSDecimal
Sir_Binky 0:3407bd06cfae 129 {
Sir_Binky 0:3407bd06cfae 130 friend class TinyGPSPlus;
Sir_Binky 0:3407bd06cfae 131 public:
Sir_Binky 0:3407bd06cfae 132 bool isValid() const { return valid; }
Sir_Binky 0:3407bd06cfae 133 bool isUpdated() const { return updated; }
Sir_Binky 0:3407bd06cfae 134 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
Sir_Binky 0:3407bd06cfae 135 int32_t value() { updated = false; return val; }
Sir_Binky 0:3407bd06cfae 136
Sir_Binky 0:3407bd06cfae 137 TinyGPSDecimal() : valid(false), updated(false), val(0)
Sir_Binky 0:3407bd06cfae 138 {}
Sir_Binky 0:3407bd06cfae 139
Sir_Binky 0:3407bd06cfae 140 private:
Sir_Binky 0:3407bd06cfae 141 bool valid, updated;
Sir_Binky 0:3407bd06cfae 142 uint32_t lastCommitTime;
Sir_Binky 0:3407bd06cfae 143 int32_t val, newval;
Sir_Binky 0:3407bd06cfae 144 void commit();
Sir_Binky 0:3407bd06cfae 145 void set(const char *term);
Sir_Binky 0:3407bd06cfae 146 };
Sir_Binky 0:3407bd06cfae 147
Sir_Binky 0:3407bd06cfae 148 struct TinyGPSInteger
Sir_Binky 0:3407bd06cfae 149 {
Sir_Binky 0:3407bd06cfae 150 friend class TinyGPSPlus;
Sir_Binky 0:3407bd06cfae 151 public:
Sir_Binky 0:3407bd06cfae 152 bool isValid() const { return valid; }
Sir_Binky 0:3407bd06cfae 153 bool isUpdated() const { return updated; }
Sir_Binky 0:3407bd06cfae 154 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
Sir_Binky 0:3407bd06cfae 155 uint32_t value() { updated = false; return val; }
Sir_Binky 0:3407bd06cfae 156
Sir_Binky 0:3407bd06cfae 157 TinyGPSInteger() : valid(false), updated(false), val(0)
Sir_Binky 0:3407bd06cfae 158 {}
Sir_Binky 0:3407bd06cfae 159
Sir_Binky 0:3407bd06cfae 160 private:
Sir_Binky 0:3407bd06cfae 161 bool valid, updated;
Sir_Binky 0:3407bd06cfae 162 uint32_t lastCommitTime;
Sir_Binky 0:3407bd06cfae 163 uint32_t val, newval;
Sir_Binky 0:3407bd06cfae 164 void commit();
Sir_Binky 0:3407bd06cfae 165 void set(const char *term);
Sir_Binky 0:3407bd06cfae 166 };
Sir_Binky 0:3407bd06cfae 167
Sir_Binky 0:3407bd06cfae 168 struct TinyGPSSpeed : TinyGPSDecimal
Sir_Binky 0:3407bd06cfae 169 {
Sir_Binky 0:3407bd06cfae 170 double knots() { return value() / 100.0; }
Sir_Binky 0:3407bd06cfae 171 double mph() { return _GPS_MPH_PER_KNOT * value() / 100.0; }
Sir_Binky 0:3407bd06cfae 172 double mps() { return _GPS_MPS_PER_KNOT * value() / 100.0; }
Sir_Binky 0:3407bd06cfae 173 double kmph() { return _GPS_KMPH_PER_KNOT * value() / 100.0; }
Sir_Binky 0:3407bd06cfae 174 };
Sir_Binky 0:3407bd06cfae 175
Sir_Binky 0:3407bd06cfae 176 struct TinyGPSCourse : public TinyGPSDecimal
Sir_Binky 0:3407bd06cfae 177 {
Sir_Binky 0:3407bd06cfae 178 double deg() { return value() / 100.0; }
Sir_Binky 0:3407bd06cfae 179 };
Sir_Binky 0:3407bd06cfae 180
Sir_Binky 0:3407bd06cfae 181 struct TinyGPSAltitude : TinyGPSDecimal
Sir_Binky 0:3407bd06cfae 182 {
Sir_Binky 0:3407bd06cfae 183 double meters() { return value() / 100.0; }
Sir_Binky 0:3407bd06cfae 184 double miles() { return _GPS_MILES_PER_METER * value() / 100.0; }
Sir_Binky 0:3407bd06cfae 185 double kilometers() { return _GPS_KM_PER_METER * value() / 100.0; }
Sir_Binky 0:3407bd06cfae 186 double feet() { return _GPS_FEET_PER_METER * value() / 100.0; }
Sir_Binky 0:3407bd06cfae 187 };
Sir_Binky 0:3407bd06cfae 188
Sir_Binky 0:3407bd06cfae 189 class TinyGPSPlus;
Sir_Binky 0:3407bd06cfae 190 class TinyGPSCustom
Sir_Binky 0:3407bd06cfae 191 {
Sir_Binky 0:3407bd06cfae 192 public:
Sir_Binky 0:3407bd06cfae 193 TinyGPSCustom() {};
Sir_Binky 0:3407bd06cfae 194 TinyGPSCustom(TinyGPSPlus &gps, const char *sentenceName, int termNumber);
Sir_Binky 0:3407bd06cfae 195 void begin(TinyGPSPlus &gps, const char *_sentenceName, int _termNumber);
Sir_Binky 0:3407bd06cfae 196
Sir_Binky 0:3407bd06cfae 197 bool isUpdated() const { return updated; }
Sir_Binky 0:3407bd06cfae 198 bool isValid() const { return valid; }
Sir_Binky 0:3407bd06cfae 199 uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }
Sir_Binky 0:3407bd06cfae 200 const char *value() { updated = false; return buffer; }
Sir_Binky 0:3407bd06cfae 201
Sir_Binky 0:3407bd06cfae 202 private:
Sir_Binky 0:3407bd06cfae 203 void commit();
Sir_Binky 0:3407bd06cfae 204 void set(const char *term);
Sir_Binky 0:3407bd06cfae 205
Sir_Binky 0:3407bd06cfae 206 char stagingBuffer[_GPS_MAX_FIELD_SIZE + 1];
Sir_Binky 0:3407bd06cfae 207 char buffer[_GPS_MAX_FIELD_SIZE + 1];
Sir_Binky 0:3407bd06cfae 208 unsigned long lastCommitTime;
Sir_Binky 0:3407bd06cfae 209 bool valid, updated;
Sir_Binky 0:3407bd06cfae 210 const char *sentenceName;
Sir_Binky 0:3407bd06cfae 211 int termNumber;
Sir_Binky 0:3407bd06cfae 212 friend class TinyGPSPlus;
Sir_Binky 0:3407bd06cfae 213 TinyGPSCustom *next;
Sir_Binky 0:3407bd06cfae 214 };
Sir_Binky 0:3407bd06cfae 215
Sir_Binky 0:3407bd06cfae 216 class TinyGPSPlus
Sir_Binky 0:3407bd06cfae 217 {
Sir_Binky 0:3407bd06cfae 218 public:
Sir_Binky 0:3407bd06cfae 219 TinyGPSPlus();
Sir_Binky 0:3407bd06cfae 220 bool encode(char c); // process one character received from GPS
Sir_Binky 0:3407bd06cfae 221 TinyGPSPlus &operator << (char c) {encode(c); return *this;}
Sir_Binky 0:3407bd06cfae 222
Sir_Binky 0:3407bd06cfae 223 TinyGPSLocation location;
Sir_Binky 0:3407bd06cfae 224 TinyGPSDate date;
Sir_Binky 0:3407bd06cfae 225 TinyGPSTime time;
Sir_Binky 0:3407bd06cfae 226 TinyGPSSpeed speed;
Sir_Binky 0:3407bd06cfae 227 TinyGPSCourse course;
Sir_Binky 0:3407bd06cfae 228 TinyGPSAltitude altitude;
Sir_Binky 0:3407bd06cfae 229 TinyGPSInteger satellites;
Sir_Binky 0:3407bd06cfae 230 TinyGPSDecimal hdop;
Sir_Binky 0:3407bd06cfae 231
Sir_Binky 0:3407bd06cfae 232 static const char *libraryVersion() { return _GPS_VERSION; }
Sir_Binky 0:3407bd06cfae 233
Sir_Binky 0:3407bd06cfae 234 static double distanceBetween(double lat1, double long1, double lat2, double long2);
Sir_Binky 0:3407bd06cfae 235 static double courseTo(double lat1, double long1, double lat2, double long2);
Sir_Binky 0:3407bd06cfae 236 static const char *cardinal(double course);
Sir_Binky 0:3407bd06cfae 237
Sir_Binky 0:3407bd06cfae 238 static int32_t parseDecimal(const char *term);
Sir_Binky 0:3407bd06cfae 239 static void parseDegrees(const char *term, RawDegrees &deg);
Sir_Binky 0:3407bd06cfae 240
Sir_Binky 0:3407bd06cfae 241 uint32_t charsProcessed() const { return encodedCharCount; }
Sir_Binky 0:3407bd06cfae 242 uint32_t sentencesWithFix() const { return sentencesWithFixCount; }
Sir_Binky 0:3407bd06cfae 243 uint32_t failedChecksum() const { return failedChecksumCount; }
Sir_Binky 0:3407bd06cfae 244 uint32_t passedChecksum() const { return passedChecksumCount; }
Sir_Binky 0:3407bd06cfae 245
Sir_Binky 0:3407bd06cfae 246 private:
Sir_Binky 0:3407bd06cfae 247 enum {GPS_SENTENCE_GPGGA, GPS_SENTENCE_GPRMC, GPS_SENTENCE_OTHER};
Sir_Binky 0:3407bd06cfae 248
Sir_Binky 0:3407bd06cfae 249 // parsing state variables
Sir_Binky 0:3407bd06cfae 250 uint8_t parity;
Sir_Binky 0:3407bd06cfae 251 bool isChecksumTerm;
Sir_Binky 0:3407bd06cfae 252 char term[_GPS_MAX_FIELD_SIZE];
Sir_Binky 0:3407bd06cfae 253 uint8_t curSentenceType;
Sir_Binky 0:3407bd06cfae 254 uint8_t curTermNumber;
Sir_Binky 0:3407bd06cfae 255 uint8_t curTermOffset;
Sir_Binky 0:3407bd06cfae 256 bool sentenceHasFix;
Sir_Binky 0:3407bd06cfae 257
Sir_Binky 0:3407bd06cfae 258 // custom element support
Sir_Binky 0:3407bd06cfae 259 friend class TinyGPSCustom;
Sir_Binky 0:3407bd06cfae 260 TinyGPSCustom *customElts;
Sir_Binky 0:3407bd06cfae 261 TinyGPSCustom *customCandidates;
Sir_Binky 0:3407bd06cfae 262 void insertCustom(TinyGPSCustom *pElt, const char *sentenceName, int index);
Sir_Binky 0:3407bd06cfae 263
Sir_Binky 0:3407bd06cfae 264 // statistics
Sir_Binky 0:3407bd06cfae 265 uint32_t encodedCharCount;
Sir_Binky 0:3407bd06cfae 266 uint32_t sentencesWithFixCount;
Sir_Binky 0:3407bd06cfae 267 uint32_t failedChecksumCount;
Sir_Binky 0:3407bd06cfae 268 uint32_t passedChecksumCount;
Sir_Binky 0:3407bd06cfae 269
Sir_Binky 0:3407bd06cfae 270 // internal utilities
Sir_Binky 0:3407bd06cfae 271 int fromHex(char a);
Sir_Binky 0:3407bd06cfae 272 bool endOfTermHandler();
Sir_Binky 0:3407bd06cfae 273 };
Sir_Binky 0:3407bd06cfae 274
Sir_Binky 0:3407bd06cfae 275 #endif // def(__TinyGPSPlus_h)