Refatorado

Committer:
renanbmx123
Date:
Sun Apr 04 14:38:47 2021 +0000
Revision:
0:9678e357caf9
Refatorado

Who changed what in which revision?

UserRevisionLine numberNew contents of line
renanbmx123 0:9678e357caf9 1 /*
renanbmx123 0:9678e357caf9 2 TinyGPS++ - a small GPS library for Arduino providing universal NMEA parsing
renanbmx123 0:9678e357caf9 3 Based on work by and "distanceBetween" and "courseTo" courtesy of Maarten Lamers.
renanbmx123 0:9678e357caf9 4 Suggestion to add satellites, courseTo(), and cardinal() by Matt Monson.
renanbmx123 0:9678e357caf9 5 Location precision improvements suggested by Wayne Holder.
renanbmx123 0:9678e357caf9 6 Copyright (C) 2008-2013 Mikal Hart
renanbmx123 0:9678e357caf9 7 All rights reserved.
renanbmx123 0:9678e357caf9 8
renanbmx123 0:9678e357caf9 9 This library is free software; you can redistribute it and/or
renanbmx123 0:9678e357caf9 10 modify it under the terms of the GNU Lesser General Public
renanbmx123 0:9678e357caf9 11 License as published by the Free Software Foundation; either
renanbmx123 0:9678e357caf9 12 version 2.1 of the License, or (at your option) any later version.
renanbmx123 0:9678e357caf9 13
renanbmx123 0:9678e357caf9 14 This library is distributed in the hope that it will be useful,
renanbmx123 0:9678e357caf9 15 but WITHOUT ANY WARRANTY; without even the implied warranty of
renanbmx123 0:9678e357caf9 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
renanbmx123 0:9678e357caf9 17 Lesser General Public License for more details.
renanbmx123 0:9678e357caf9 18
renanbmx123 0:9678e357caf9 19 You should have received a copy of the GNU Lesser General Public
renanbmx123 0:9678e357caf9 20 License along with this library; if not, write to the Free Software
renanbmx123 0:9678e357caf9 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
renanbmx123 0:9678e357caf9 22
renanbmx123 0:9678e357caf9 23 MBED port by Kalevi Anders, but heavily inspired by Sergey Drobyshevskiy (dROb)
renanbmx123 0:9678e357caf9 24 */
renanbmx123 0:9678e357caf9 25
renanbmx123 0:9678e357caf9 26 #include "TinyGPSPlus.h"
renanbmx123 0:9678e357caf9 27
renanbmx123 0:9678e357caf9 28 #include <string.h>
renanbmx123 0:9678e357caf9 29 #include <ctype.h>
renanbmx123 0:9678e357caf9 30 #include <stdlib.h>
renanbmx123 0:9678e357caf9 31
renanbmx123 0:9678e357caf9 32 #define _GPRMCterm "GPRMC"
renanbmx123 0:9678e357caf9 33 #define _GPGGAterm "GPGGA"
renanbmx123 0:9678e357caf9 34
renanbmx123 0:9678e357caf9 35 TinyGPSPlus::TinyGPSPlus()
renanbmx123 0:9678e357caf9 36 : parity(0)
renanbmx123 0:9678e357caf9 37 , isChecksumTerm(false)
renanbmx123 0:9678e357caf9 38 , curSentenceType(GPS_SENTENCE_OTHER)
renanbmx123 0:9678e357caf9 39 , curTermNumber(0)
renanbmx123 0:9678e357caf9 40 , curTermOffset(0)
renanbmx123 0:9678e357caf9 41 , sentenceHasFix(false)
renanbmx123 0:9678e357caf9 42 , customElts(0)
renanbmx123 0:9678e357caf9 43 , customCandidates(0)
renanbmx123 0:9678e357caf9 44 , encodedCharCount(0)
renanbmx123 0:9678e357caf9 45 , sentencesWithFixCount(0)
renanbmx123 0:9678e357caf9 46 , failedChecksumCount(0)
renanbmx123 0:9678e357caf9 47 , passedChecksumCount(0)
renanbmx123 0:9678e357caf9 48 {
renanbmx123 0:9678e357caf9 49 term[0] = '\0';
renanbmx123 0:9678e357caf9 50 }
renanbmx123 0:9678e357caf9 51
renanbmx123 0:9678e357caf9 52 //
renanbmx123 0:9678e357caf9 53 // public methods
renanbmx123 0:9678e357caf9 54 //
renanbmx123 0:9678e357caf9 55
renanbmx123 0:9678e357caf9 56 bool TinyGPSPlus::encode(char c)
renanbmx123 0:9678e357caf9 57 {
renanbmx123 0:9678e357caf9 58 ++encodedCharCount;
renanbmx123 0:9678e357caf9 59 switch(c)
renanbmx123 0:9678e357caf9 60 {
renanbmx123 0:9678e357caf9 61 case ',': // term terminators
renanbmx123 0:9678e357caf9 62 parity ^= (uint8_t)c;
renanbmx123 0:9678e357caf9 63
renanbmx123 0:9678e357caf9 64 case '\r':
renanbmx123 0:9678e357caf9 65 case '\n':
renanbmx123 0:9678e357caf9 66 case '*':
renanbmx123 0:9678e357caf9 67 {
renanbmx123 0:9678e357caf9 68 bool isValidSentence = false;
renanbmx123 0:9678e357caf9 69 if (curTermOffset < sizeof(term))
renanbmx123 0:9678e357caf9 70 {
renanbmx123 0:9678e357caf9 71 term[curTermOffset] = 0;
renanbmx123 0:9678e357caf9 72 isValidSentence = endOfTermHandler();
renanbmx123 0:9678e357caf9 73 }
renanbmx123 0:9678e357caf9 74 ++curTermNumber;
renanbmx123 0:9678e357caf9 75 curTermOffset = 0;
renanbmx123 0:9678e357caf9 76 isChecksumTerm = c == '*';
renanbmx123 0:9678e357caf9 77 return isValidSentence;
renanbmx123 0:9678e357caf9 78 }
renanbmx123 0:9678e357caf9 79 break;
renanbmx123 0:9678e357caf9 80
renanbmx123 0:9678e357caf9 81 case '$': // sentence begin
renanbmx123 0:9678e357caf9 82 curTermNumber = curTermOffset = 0;
renanbmx123 0:9678e357caf9 83 parity = 0;
renanbmx123 0:9678e357caf9 84 curSentenceType = GPS_SENTENCE_OTHER;
renanbmx123 0:9678e357caf9 85 isChecksumTerm = false;
renanbmx123 0:9678e357caf9 86 sentenceHasFix = false;
renanbmx123 0:9678e357caf9 87 return false;
renanbmx123 0:9678e357caf9 88
renanbmx123 0:9678e357caf9 89 default: // ordinary characters
renanbmx123 0:9678e357caf9 90 if (curTermOffset < sizeof(term) - 1)
renanbmx123 0:9678e357caf9 91 term[curTermOffset++] = c;
renanbmx123 0:9678e357caf9 92 if (!isChecksumTerm)
renanbmx123 0:9678e357caf9 93 parity ^= c;
renanbmx123 0:9678e357caf9 94 return false;
renanbmx123 0:9678e357caf9 95 }
renanbmx123 0:9678e357caf9 96
renanbmx123 0:9678e357caf9 97 return false;
renanbmx123 0:9678e357caf9 98 }
renanbmx123 0:9678e357caf9 99
renanbmx123 0:9678e357caf9 100 //
renanbmx123 0:9678e357caf9 101 // internal utilities
renanbmx123 0:9678e357caf9 102 //
renanbmx123 0:9678e357caf9 103 int TinyGPSPlus::fromHex(char a)
renanbmx123 0:9678e357caf9 104 {
renanbmx123 0:9678e357caf9 105 if (a >= 'A' && a <= 'F')
renanbmx123 0:9678e357caf9 106 return a - 'A' + 10;
renanbmx123 0:9678e357caf9 107 else if (a >= 'a' && a <= 'f')
renanbmx123 0:9678e357caf9 108 return a - 'a' + 10;
renanbmx123 0:9678e357caf9 109 else
renanbmx123 0:9678e357caf9 110 return a - '0';
renanbmx123 0:9678e357caf9 111 }
renanbmx123 0:9678e357caf9 112
renanbmx123 0:9678e357caf9 113 // static
renanbmx123 0:9678e357caf9 114 // Parse a (potentially negative) number with up to 2 decimal digits -xxxx.yy
renanbmx123 0:9678e357caf9 115 int32_t TinyGPSPlus::parseDecimal(const char *term)
renanbmx123 0:9678e357caf9 116 {
renanbmx123 0:9678e357caf9 117 bool negative = *term == '-';
renanbmx123 0:9678e357caf9 118 if (negative) ++term;
renanbmx123 0:9678e357caf9 119 int32_t ret = 100 * (int32_t)atol(term);
renanbmx123 0:9678e357caf9 120 while (isdigit(*term)) ++term;
renanbmx123 0:9678e357caf9 121 if (*term == '.' && isdigit(term[1]))
renanbmx123 0:9678e357caf9 122 {
renanbmx123 0:9678e357caf9 123 ret += 10 * (term[1] - '0');
renanbmx123 0:9678e357caf9 124 if (isdigit(term[2]))
renanbmx123 0:9678e357caf9 125 ret += term[2] - '0';
renanbmx123 0:9678e357caf9 126 }
renanbmx123 0:9678e357caf9 127 return negative ? -ret : ret;
renanbmx123 0:9678e357caf9 128 }
renanbmx123 0:9678e357caf9 129
renanbmx123 0:9678e357caf9 130 // static
renanbmx123 0:9678e357caf9 131 // Parse degrees in that funny NMEA format DDMM.MMMM
renanbmx123 0:9678e357caf9 132 void TinyGPSPlus::parseDegrees(const char *term, RawDegrees &deg)
renanbmx123 0:9678e357caf9 133 {
renanbmx123 0:9678e357caf9 134 uint32_t leftOfDecimal = (uint32_t)atol(term);
renanbmx123 0:9678e357caf9 135 uint16_t minutes = (uint16_t)(leftOfDecimal % 100);
renanbmx123 0:9678e357caf9 136 uint32_t multiplier = 10000000UL;
renanbmx123 0:9678e357caf9 137 uint32_t tenMillionthsOfMinutes = minutes * multiplier;
renanbmx123 0:9678e357caf9 138
renanbmx123 0:9678e357caf9 139 deg.deg = (int16_t)(leftOfDecimal / 100);
renanbmx123 0:9678e357caf9 140
renanbmx123 0:9678e357caf9 141 while (isdigit(*term))
renanbmx123 0:9678e357caf9 142 ++term;
renanbmx123 0:9678e357caf9 143
renanbmx123 0:9678e357caf9 144 if (*term == '.')
renanbmx123 0:9678e357caf9 145 while (isdigit(*++term))
renanbmx123 0:9678e357caf9 146 {
renanbmx123 0:9678e357caf9 147 multiplier /= 10;
renanbmx123 0:9678e357caf9 148 tenMillionthsOfMinutes += (*term - '0') * multiplier;
renanbmx123 0:9678e357caf9 149 }
renanbmx123 0:9678e357caf9 150
renanbmx123 0:9678e357caf9 151 deg.billionths = (5 * tenMillionthsOfMinutes + 1) / 3;
renanbmx123 0:9678e357caf9 152 deg.negative = false;
renanbmx123 0:9678e357caf9 153 }
renanbmx123 0:9678e357caf9 154
renanbmx123 0:9678e357caf9 155 #define COMBINE(sentence_type, term_number) (((unsigned)(sentence_type) << 5) | term_number)
renanbmx123 0:9678e357caf9 156
renanbmx123 0:9678e357caf9 157 // Processes a just-completed term
renanbmx123 0:9678e357caf9 158 // Returns true if new sentence has just passed checksum test and is validated
renanbmx123 0:9678e357caf9 159 bool TinyGPSPlus::endOfTermHandler()
renanbmx123 0:9678e357caf9 160 {
renanbmx123 0:9678e357caf9 161 // If it's the checksum term, and the checksum checks out, commit
renanbmx123 0:9678e357caf9 162 if (isChecksumTerm)
renanbmx123 0:9678e357caf9 163 {
renanbmx123 0:9678e357caf9 164 byte checksum = 16 * fromHex(term[0]) + fromHex(term[1]);
renanbmx123 0:9678e357caf9 165 if (checksum == parity)
renanbmx123 0:9678e357caf9 166 {
renanbmx123 0:9678e357caf9 167 passedChecksumCount++;
renanbmx123 0:9678e357caf9 168 if (sentenceHasFix)
renanbmx123 0:9678e357caf9 169 ++sentencesWithFixCount;
renanbmx123 0:9678e357caf9 170
renanbmx123 0:9678e357caf9 171 switch(curSentenceType)
renanbmx123 0:9678e357caf9 172 {
renanbmx123 0:9678e357caf9 173 case GPS_SENTENCE_GPRMC:
renanbmx123 0:9678e357caf9 174 date.commit();
renanbmx123 0:9678e357caf9 175 time.commit();
renanbmx123 0:9678e357caf9 176 if (sentenceHasFix)
renanbmx123 0:9678e357caf9 177 {
renanbmx123 0:9678e357caf9 178 location.commit();
renanbmx123 0:9678e357caf9 179 speed.commit();
renanbmx123 0:9678e357caf9 180 course.commit();
renanbmx123 0:9678e357caf9 181 }
renanbmx123 0:9678e357caf9 182 break;
renanbmx123 0:9678e357caf9 183 case GPS_SENTENCE_GPGGA:
renanbmx123 0:9678e357caf9 184 time.commit();
renanbmx123 0:9678e357caf9 185 if (sentenceHasFix)
renanbmx123 0:9678e357caf9 186 {
renanbmx123 0:9678e357caf9 187 location.commit();
renanbmx123 0:9678e357caf9 188 altitude.commit();
renanbmx123 0:9678e357caf9 189 }
renanbmx123 0:9678e357caf9 190 satellites.commit();
renanbmx123 0:9678e357caf9 191 hdop.commit();
renanbmx123 0:9678e357caf9 192 break;
renanbmx123 0:9678e357caf9 193 }
renanbmx123 0:9678e357caf9 194
renanbmx123 0:9678e357caf9 195 // Commit all custom listeners of this sentence type
renanbmx123 0:9678e357caf9 196 for (TinyGPSCustom *p = customCandidates; p != NULL && strcmp(p->sentenceName, customCandidates->sentenceName) == 0; p = p->next)
renanbmx123 0:9678e357caf9 197 p->commit();
renanbmx123 0:9678e357caf9 198 return true;
renanbmx123 0:9678e357caf9 199 }
renanbmx123 0:9678e357caf9 200
renanbmx123 0:9678e357caf9 201 else
renanbmx123 0:9678e357caf9 202 {
renanbmx123 0:9678e357caf9 203 ++failedChecksumCount;
renanbmx123 0:9678e357caf9 204 }
renanbmx123 0:9678e357caf9 205
renanbmx123 0:9678e357caf9 206 return false;
renanbmx123 0:9678e357caf9 207 }
renanbmx123 0:9678e357caf9 208
renanbmx123 0:9678e357caf9 209 // the first term determines the sentence type
renanbmx123 0:9678e357caf9 210 if (curTermNumber == 0)
renanbmx123 0:9678e357caf9 211 {
renanbmx123 0:9678e357caf9 212 if (!strcmp(term, _GPRMCterm))
renanbmx123 0:9678e357caf9 213 curSentenceType = GPS_SENTENCE_GPRMC;
renanbmx123 0:9678e357caf9 214 else if (!strcmp(term, _GPGGAterm))
renanbmx123 0:9678e357caf9 215 curSentenceType = GPS_SENTENCE_GPGGA;
renanbmx123 0:9678e357caf9 216 else
renanbmx123 0:9678e357caf9 217 curSentenceType = GPS_SENTENCE_OTHER;
renanbmx123 0:9678e357caf9 218
renanbmx123 0:9678e357caf9 219 // Any custom candidates of this sentence type?
renanbmx123 0:9678e357caf9 220 for (customCandidates = customElts; customCandidates != NULL && strcmp(customCandidates->sentenceName, term) < 0; customCandidates = customCandidates->next);
renanbmx123 0:9678e357caf9 221 if (customCandidates != NULL && strcmp(customCandidates->sentenceName, term) > 0)
renanbmx123 0:9678e357caf9 222 customCandidates = NULL;
renanbmx123 0:9678e357caf9 223
renanbmx123 0:9678e357caf9 224 return false;
renanbmx123 0:9678e357caf9 225 }
renanbmx123 0:9678e357caf9 226
renanbmx123 0:9678e357caf9 227 if (curSentenceType != GPS_SENTENCE_OTHER && term[0])
renanbmx123 0:9678e357caf9 228 switch(COMBINE(curSentenceType, curTermNumber))
renanbmx123 0:9678e357caf9 229 {
renanbmx123 0:9678e357caf9 230 case COMBINE(GPS_SENTENCE_GPRMC, 1): // Time in both sentences
renanbmx123 0:9678e357caf9 231 case COMBINE(GPS_SENTENCE_GPGGA, 1):
renanbmx123 0:9678e357caf9 232 time.setTime(term);
renanbmx123 0:9678e357caf9 233 break;
renanbmx123 0:9678e357caf9 234 case COMBINE(GPS_SENTENCE_GPRMC, 2): // GPRMC validity
renanbmx123 0:9678e357caf9 235 sentenceHasFix = term[0] == 'A';
renanbmx123 0:9678e357caf9 236 break;
renanbmx123 0:9678e357caf9 237 case COMBINE(GPS_SENTENCE_GPRMC, 3): // Latitude
renanbmx123 0:9678e357caf9 238 case COMBINE(GPS_SENTENCE_GPGGA, 2):
renanbmx123 0:9678e357caf9 239 location.setLatitude(term);
renanbmx123 0:9678e357caf9 240 break;
renanbmx123 0:9678e357caf9 241 case COMBINE(GPS_SENTENCE_GPRMC, 4): // N/S
renanbmx123 0:9678e357caf9 242 case COMBINE(GPS_SENTENCE_GPGGA, 3):
renanbmx123 0:9678e357caf9 243 location.rawNewLatData.negative = term[0] == 'S';
renanbmx123 0:9678e357caf9 244 NorthSouth = term[0];
renanbmx123 0:9678e357caf9 245 break;
renanbmx123 0:9678e357caf9 246 case COMBINE(GPS_SENTENCE_GPRMC, 5): // Longitude
renanbmx123 0:9678e357caf9 247 case COMBINE(GPS_SENTENCE_GPGGA, 4):
renanbmx123 0:9678e357caf9 248 location.setLongitude(term);
renanbmx123 0:9678e357caf9 249 break;
renanbmx123 0:9678e357caf9 250 case COMBINE(GPS_SENTENCE_GPRMC, 6): // E/W
renanbmx123 0:9678e357caf9 251 case COMBINE(GPS_SENTENCE_GPGGA, 5):
renanbmx123 0:9678e357caf9 252 location.rawNewLngData.negative = term[0] == 'W';
renanbmx123 0:9678e357caf9 253 EastWest = term[0];
renanbmx123 0:9678e357caf9 254 break;
renanbmx123 0:9678e357caf9 255 case COMBINE(GPS_SENTENCE_GPRMC, 7): // Speed (GPRMC)
renanbmx123 0:9678e357caf9 256 speed.set(term);
renanbmx123 0:9678e357caf9 257 break;
renanbmx123 0:9678e357caf9 258 case COMBINE(GPS_SENTENCE_GPRMC, 8): // Course (GPRMC)
renanbmx123 0:9678e357caf9 259 course.set(term);
renanbmx123 0:9678e357caf9 260 break;
renanbmx123 0:9678e357caf9 261 case COMBINE(GPS_SENTENCE_GPRMC, 9): // Date (GPRMC)
renanbmx123 0:9678e357caf9 262 date.setDate(term);
renanbmx123 0:9678e357caf9 263 break;
renanbmx123 0:9678e357caf9 264 case COMBINE(GPS_SENTENCE_GPGGA, 6): // Fix data (GPGGA)
renanbmx123 0:9678e357caf9 265 sentenceHasFix = term[0] > '0';
renanbmx123 0:9678e357caf9 266 break;
renanbmx123 0:9678e357caf9 267 case COMBINE(GPS_SENTENCE_GPGGA, 7): // Satellites used (GPGGA)
renanbmx123 0:9678e357caf9 268 satellites.set(term);
renanbmx123 0:9678e357caf9 269 break;
renanbmx123 0:9678e357caf9 270 case COMBINE(GPS_SENTENCE_GPGGA, 8): // HDOP
renanbmx123 0:9678e357caf9 271 hdop.set(term);
renanbmx123 0:9678e357caf9 272 break;
renanbmx123 0:9678e357caf9 273 case COMBINE(GPS_SENTENCE_GPGGA, 9): // Altitude (GPGGA)
renanbmx123 0:9678e357caf9 274 altitude.set(term);
renanbmx123 0:9678e357caf9 275 break;
renanbmx123 0:9678e357caf9 276 }
renanbmx123 0:9678e357caf9 277
renanbmx123 0:9678e357caf9 278 // Set custom values as needed
renanbmx123 0:9678e357caf9 279 for (TinyGPSCustom *p = customCandidates; p != NULL && strcmp(p->sentenceName, customCandidates->sentenceName) == 0 && p->termNumber <= curTermNumber; p = p->next)
renanbmx123 0:9678e357caf9 280 if (p->termNumber == curTermNumber)
renanbmx123 0:9678e357caf9 281 p->set(term);
renanbmx123 0:9678e357caf9 282
renanbmx123 0:9678e357caf9 283 return false;
renanbmx123 0:9678e357caf9 284 }
renanbmx123 0:9678e357caf9 285
renanbmx123 0:9678e357caf9 286 /* static */
renanbmx123 0:9678e357caf9 287 double TinyGPSPlus::distanceBetween(double lat1, double long1, double lat2, double long2)
renanbmx123 0:9678e357caf9 288 {
renanbmx123 0:9678e357caf9 289 // returns distance in meters between two positions, both specified
renanbmx123 0:9678e357caf9 290 // as signed decimal-degrees latitude and longitude. Uses great-circle
renanbmx123 0:9678e357caf9 291 // distance computation for hypothetical sphere of radius 6372795 meters.
renanbmx123 0:9678e357caf9 292 // Because Earth is no exact sphere, rounding errors may be up to 0.5%.
renanbmx123 0:9678e357caf9 293 // Courtesy of Maarten Lamers
renanbmx123 0:9678e357caf9 294 double delta = radians(long1-long2);
renanbmx123 0:9678e357caf9 295 double sdlong = sin(delta);
renanbmx123 0:9678e357caf9 296 double cdlong = cos(delta);
renanbmx123 0:9678e357caf9 297 lat1 = radians(lat1);
renanbmx123 0:9678e357caf9 298 lat2 = radians(lat2);
renanbmx123 0:9678e357caf9 299 double slat1 = sin(lat1);
renanbmx123 0:9678e357caf9 300 double clat1 = cos(lat1);
renanbmx123 0:9678e357caf9 301 double slat2 = sin(lat2);
renanbmx123 0:9678e357caf9 302 double clat2 = cos(lat2);
renanbmx123 0:9678e357caf9 303 delta = (clat1 * slat2) - (slat1 * clat2 * cdlong);
renanbmx123 0:9678e357caf9 304 delta = sq(delta);
renanbmx123 0:9678e357caf9 305 delta += sq(clat2 * sdlong);
renanbmx123 0:9678e357caf9 306 delta = sqrt(delta);
renanbmx123 0:9678e357caf9 307 double denom = (slat1 * slat2) + (clat1 * clat2 * cdlong);
renanbmx123 0:9678e357caf9 308 delta = atan2(delta, denom);
renanbmx123 0:9678e357caf9 309 return delta * 6372795;
renanbmx123 0:9678e357caf9 310 }
renanbmx123 0:9678e357caf9 311
renanbmx123 0:9678e357caf9 312 double TinyGPSPlus::courseTo(double lat1, double long1, double lat2, double long2)
renanbmx123 0:9678e357caf9 313 {
renanbmx123 0:9678e357caf9 314 // returns course in degrees (North=0, West=270) from position 1 to position 2,
renanbmx123 0:9678e357caf9 315 // both specified as signed decimal-degrees latitude and longitude.
renanbmx123 0:9678e357caf9 316 // Because Earth is no exact sphere, calculated course may be off by a tiny fraction.
renanbmx123 0:9678e357caf9 317 // Courtesy of Maarten Lamers
renanbmx123 0:9678e357caf9 318 double dlon = radians(long2-long1);
renanbmx123 0:9678e357caf9 319 lat1 = radians(lat1);
renanbmx123 0:9678e357caf9 320 lat2 = radians(lat2);
renanbmx123 0:9678e357caf9 321 double a1 = sin(dlon) * cos(lat2);
renanbmx123 0:9678e357caf9 322 double a2 = sin(lat1) * cos(lat2) * cos(dlon);
renanbmx123 0:9678e357caf9 323 a2 = cos(lat1) * sin(lat2) - a2;
renanbmx123 0:9678e357caf9 324 a2 = atan2(a1, a2);
renanbmx123 0:9678e357caf9 325 if (a2 < 0.0)
renanbmx123 0:9678e357caf9 326 {
renanbmx123 0:9678e357caf9 327 a2 += TWO_PI;
renanbmx123 0:9678e357caf9 328 }
renanbmx123 0:9678e357caf9 329 return degrees(a2);
renanbmx123 0:9678e357caf9 330 }
renanbmx123 0:9678e357caf9 331
renanbmx123 0:9678e357caf9 332 const char *TinyGPSPlus::cardinal(double course)
renanbmx123 0:9678e357caf9 333 {
renanbmx123 0:9678e357caf9 334 static const char* directions[] = {"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"};
renanbmx123 0:9678e357caf9 335 int direction = (int)((course + 11.25f) / 22.5f);
renanbmx123 0:9678e357caf9 336 return directions[direction % 16];
renanbmx123 0:9678e357caf9 337 }
renanbmx123 0:9678e357caf9 338
renanbmx123 0:9678e357caf9 339 void TinyGPSLocation::commit()
renanbmx123 0:9678e357caf9 340 {
renanbmx123 0:9678e357caf9 341 rawLatData = rawNewLatData;
renanbmx123 0:9678e357caf9 342 rawLngData = rawNewLngData;
renanbmx123 0:9678e357caf9 343 lastCommitTime = millis();
renanbmx123 0:9678e357caf9 344 valid = updated = true;
renanbmx123 0:9678e357caf9 345 }
renanbmx123 0:9678e357caf9 346
renanbmx123 0:9678e357caf9 347 void TinyGPSLocation::setLatitude(const char *term)
renanbmx123 0:9678e357caf9 348 {
renanbmx123 0:9678e357caf9 349 TinyGPSPlus::parseDegrees(term, rawNewLatData);
renanbmx123 0:9678e357caf9 350 }
renanbmx123 0:9678e357caf9 351
renanbmx123 0:9678e357caf9 352 void TinyGPSLocation::setLongitude(const char *term)
renanbmx123 0:9678e357caf9 353 {
renanbmx123 0:9678e357caf9 354 TinyGPSPlus::parseDegrees(term, rawNewLngData);
renanbmx123 0:9678e357caf9 355 }
renanbmx123 0:9678e357caf9 356
renanbmx123 0:9678e357caf9 357 double TinyGPSLocation::lat()
renanbmx123 0:9678e357caf9 358 {
renanbmx123 0:9678e357caf9 359 updated = false;
renanbmx123 0:9678e357caf9 360 double ret = rawLatData.deg + rawLatData.billionths / 1000000000.0;
renanbmx123 0:9678e357caf9 361 return rawLatData.negative ? -ret : ret;
renanbmx123 0:9678e357caf9 362 }
renanbmx123 0:9678e357caf9 363
renanbmx123 0:9678e357caf9 364 double TinyGPSLocation::lng()
renanbmx123 0:9678e357caf9 365 {
renanbmx123 0:9678e357caf9 366 updated = false;
renanbmx123 0:9678e357caf9 367 double ret = rawLngData.deg + rawLngData.billionths / 1000000000.0;
renanbmx123 0:9678e357caf9 368 return rawLngData.negative ? -ret : ret;
renanbmx123 0:9678e357caf9 369 }
renanbmx123 0:9678e357caf9 370
renanbmx123 0:9678e357caf9 371 void TinyGPSDate::commit()
renanbmx123 0:9678e357caf9 372 {
renanbmx123 0:9678e357caf9 373 date = newDate;
renanbmx123 0:9678e357caf9 374 lastCommitTime = millis();
renanbmx123 0:9678e357caf9 375 valid = updated = true;
renanbmx123 0:9678e357caf9 376 }
renanbmx123 0:9678e357caf9 377
renanbmx123 0:9678e357caf9 378 void TinyGPSTime::commit()
renanbmx123 0:9678e357caf9 379 {
renanbmx123 0:9678e357caf9 380 time = newTime;
renanbmx123 0:9678e357caf9 381 lastCommitTime = millis();
renanbmx123 0:9678e357caf9 382 valid = updated = true;
renanbmx123 0:9678e357caf9 383 }
renanbmx123 0:9678e357caf9 384
renanbmx123 0:9678e357caf9 385 void TinyGPSTime::setTime(const char *term)
renanbmx123 0:9678e357caf9 386 {
renanbmx123 0:9678e357caf9 387 newTime = (uint32_t)TinyGPSPlus::parseDecimal(term);
renanbmx123 0:9678e357caf9 388 }
renanbmx123 0:9678e357caf9 389
renanbmx123 0:9678e357caf9 390 void TinyGPSDate::setDate(const char *term)
renanbmx123 0:9678e357caf9 391 {
renanbmx123 0:9678e357caf9 392 newDate = atol(term);
renanbmx123 0:9678e357caf9 393 }
renanbmx123 0:9678e357caf9 394
renanbmx123 0:9678e357caf9 395 uint16_t TinyGPSDate::year()
renanbmx123 0:9678e357caf9 396 {
renanbmx123 0:9678e357caf9 397 updated = false;
renanbmx123 0:9678e357caf9 398 uint16_t year = date % 100;
renanbmx123 0:9678e357caf9 399 return year + 2000;
renanbmx123 0:9678e357caf9 400 }
renanbmx123 0:9678e357caf9 401
renanbmx123 0:9678e357caf9 402 uint8_t TinyGPSDate::month()
renanbmx123 0:9678e357caf9 403 {
renanbmx123 0:9678e357caf9 404 updated = false;
renanbmx123 0:9678e357caf9 405 return (date / 100) % 100;
renanbmx123 0:9678e357caf9 406 }
renanbmx123 0:9678e357caf9 407
renanbmx123 0:9678e357caf9 408 uint8_t TinyGPSDate::day()
renanbmx123 0:9678e357caf9 409 {
renanbmx123 0:9678e357caf9 410 updated = false;
renanbmx123 0:9678e357caf9 411 return date / 10000;
renanbmx123 0:9678e357caf9 412 }
renanbmx123 0:9678e357caf9 413
renanbmx123 0:9678e357caf9 414 uint8_t TinyGPSTime::hour()
renanbmx123 0:9678e357caf9 415 {
renanbmx123 0:9678e357caf9 416 updated = false;
renanbmx123 0:9678e357caf9 417 return time / 1000000;
renanbmx123 0:9678e357caf9 418 }
renanbmx123 0:9678e357caf9 419
renanbmx123 0:9678e357caf9 420 uint8_t TinyGPSTime::minute()
renanbmx123 0:9678e357caf9 421 {
renanbmx123 0:9678e357caf9 422 updated = false;
renanbmx123 0:9678e357caf9 423 return (time / 10000) % 100;
renanbmx123 0:9678e357caf9 424 }
renanbmx123 0:9678e357caf9 425
renanbmx123 0:9678e357caf9 426 uint8_t TinyGPSTime::second()
renanbmx123 0:9678e357caf9 427 {
renanbmx123 0:9678e357caf9 428 updated = false;
renanbmx123 0:9678e357caf9 429 return (time / 100) % 100;
renanbmx123 0:9678e357caf9 430 }
renanbmx123 0:9678e357caf9 431
renanbmx123 0:9678e357caf9 432 uint8_t TinyGPSTime::centisecond()
renanbmx123 0:9678e357caf9 433 {
renanbmx123 0:9678e357caf9 434 updated = false;
renanbmx123 0:9678e357caf9 435 return time % 100;
renanbmx123 0:9678e357caf9 436 }
renanbmx123 0:9678e357caf9 437
renanbmx123 0:9678e357caf9 438 void TinyGPSDecimal::commit()
renanbmx123 0:9678e357caf9 439 {
renanbmx123 0:9678e357caf9 440 val = newval;
renanbmx123 0:9678e357caf9 441 lastCommitTime = millis();
renanbmx123 0:9678e357caf9 442 valid = updated = true;
renanbmx123 0:9678e357caf9 443 }
renanbmx123 0:9678e357caf9 444
renanbmx123 0:9678e357caf9 445 void TinyGPSDecimal::set(const char *term)
renanbmx123 0:9678e357caf9 446 {
renanbmx123 0:9678e357caf9 447 newval = TinyGPSPlus::parseDecimal(term);
renanbmx123 0:9678e357caf9 448 }
renanbmx123 0:9678e357caf9 449
renanbmx123 0:9678e357caf9 450 void TinyGPSInteger::commit()
renanbmx123 0:9678e357caf9 451 {
renanbmx123 0:9678e357caf9 452 val = newval;
renanbmx123 0:9678e357caf9 453 lastCommitTime = millis();
renanbmx123 0:9678e357caf9 454 valid = updated = true;
renanbmx123 0:9678e357caf9 455 }
renanbmx123 0:9678e357caf9 456
renanbmx123 0:9678e357caf9 457 void TinyGPSInteger::set(const char *term)
renanbmx123 0:9678e357caf9 458 {
renanbmx123 0:9678e357caf9 459 newval = atol(term);
renanbmx123 0:9678e357caf9 460 }
renanbmx123 0:9678e357caf9 461
renanbmx123 0:9678e357caf9 462 TinyGPSCustom::TinyGPSCustom(TinyGPSPlus &gps, const char *_sentenceName, int _termNumber)
renanbmx123 0:9678e357caf9 463 {
renanbmx123 0:9678e357caf9 464 begin(gps, _sentenceName, _termNumber);
renanbmx123 0:9678e357caf9 465 }
renanbmx123 0:9678e357caf9 466
renanbmx123 0:9678e357caf9 467 void TinyGPSCustom::begin(TinyGPSPlus &gps, const char *_sentenceName, int _termNumber)
renanbmx123 0:9678e357caf9 468 {
renanbmx123 0:9678e357caf9 469 lastCommitTime = 0;
renanbmx123 0:9678e357caf9 470 updated = valid = false;
renanbmx123 0:9678e357caf9 471 sentenceName = _sentenceName;
renanbmx123 0:9678e357caf9 472 termNumber = _termNumber;
renanbmx123 0:9678e357caf9 473 memset(stagingBuffer, '\0', sizeof(stagingBuffer));
renanbmx123 0:9678e357caf9 474 memset(buffer, '\0', sizeof(buffer));
renanbmx123 0:9678e357caf9 475
renanbmx123 0:9678e357caf9 476 // Insert this item into the GPS tree
renanbmx123 0:9678e357caf9 477 gps.insertCustom(this, _sentenceName, _termNumber);
renanbmx123 0:9678e357caf9 478 }
renanbmx123 0:9678e357caf9 479
renanbmx123 0:9678e357caf9 480 void TinyGPSCustom::commit()
renanbmx123 0:9678e357caf9 481 {
renanbmx123 0:9678e357caf9 482 strcpy(this->buffer, this->stagingBuffer);
renanbmx123 0:9678e357caf9 483 lastCommitTime = millis();
renanbmx123 0:9678e357caf9 484 valid = updated = true;
renanbmx123 0:9678e357caf9 485 }
renanbmx123 0:9678e357caf9 486
renanbmx123 0:9678e357caf9 487 void TinyGPSCustom::set(const char *term)
renanbmx123 0:9678e357caf9 488 {
renanbmx123 0:9678e357caf9 489 strncpy(this->stagingBuffer, term, sizeof(this->stagingBuffer));
renanbmx123 0:9678e357caf9 490 }
renanbmx123 0:9678e357caf9 491
renanbmx123 0:9678e357caf9 492 void TinyGPSPlus::insertCustom(TinyGPSCustom *pElt, const char *sentenceName, int termNumber)
renanbmx123 0:9678e357caf9 493 {
renanbmx123 0:9678e357caf9 494 TinyGPSCustom **ppelt;
renanbmx123 0:9678e357caf9 495
renanbmx123 0:9678e357caf9 496 for (ppelt = &this->customElts; *ppelt != NULL; ppelt = &(*ppelt)->next)
renanbmx123 0:9678e357caf9 497 {
renanbmx123 0:9678e357caf9 498 int cmp = strcmp(sentenceName, (*ppelt)->sentenceName);
renanbmx123 0:9678e357caf9 499 if (cmp < 0 || (cmp == 0 && termNumber < (*ppelt)->termNumber))
renanbmx123 0:9678e357caf9 500 break;
renanbmx123 0:9678e357caf9 501 }
renanbmx123 0:9678e357caf9 502
renanbmx123 0:9678e357caf9 503 pElt->next = *ppelt;
renanbmx123 0:9678e357caf9 504 *ppelt = pElt;
renanbmx123 0:9678e357caf9 505 }