A GPS serial interrupt service routine that has an on the fly nmea parser. Works with a STM32F411RE and a Adafruit GPS logger.
Dependents: Bicycl_Computer_NUCLEO-F411RE Bicycl_Computer_NUCLEO-L476RG
Fork of GPS by
main.cpp
#include "mbed.h" #include "GPSISR.h" #define PIN_RX_GPS PA_12 //GPS Shield RX pin #define PIN_TX_GPS PA_11 //GPS Shield TX pin Serial pc(USBTX, USBRX); // Set up serial interrupe service handler for gps characters. GPS MyGPS(PIN_TX_GPS,PIN_RX_GPS, 9600); int main() { while (1) { if (MyGPS.dataready()) { MyGPS.read(); pc.printf("NMEA has valid data"); pc.printf("Sats : %d \n", MyGPS.buffer.satellites); pc.printf("%d-%d-%d\n", MyGPS.buffer.month, MyGPS.buffer.day, MyGPS.buffer.year); pc.printf("%d:%d:%d\n", MyGPS.buffer.hours, MyGPS.buffer.minutes, MyGPS.buffer.seconds); } else { pc.printf("NMEA has no valid data"); } } }
nmea.cpp@6:f0c13bb7d266, 2017-03-01 (annotated)
- Committer:
- trevieze
- Date:
- Wed Mar 01 15:36:05 2017 +0000
- Revision:
- 6:f0c13bb7d266
- Parent:
- 5:c5f700c1e1af
Math error in GPS speed calculation from Knots to Kilometer. Should be ; 1Kn = 1.85Km
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
trevieze | 1:4b5ffae743c0 | 1 | /* |
trevieze | 1:4b5ffae743c0 | 2 | File: nmea.cpp |
trevieze | 1:4b5ffae743c0 | 3 | Version: 0.1.0 |
trevieze | 1:4b5ffae743c0 | 4 | Date: Feb. 23, 2013 |
trevieze | 1:4b5ffae743c0 | 5 | License: GPL v2 |
trevieze | 1:4b5ffae743c0 | 6 | |
trevieze | 1:4b5ffae743c0 | 7 | NMEA GPS content parser |
trevieze | 1:4b5ffae743c0 | 8 | |
trevieze | 1:4b5ffae743c0 | 9 | **************************************************************************** |
trevieze | 1:4b5ffae743c0 | 10 | Copyright (C) 2013 Radu Motisan <radu.motisan@gmail.com> |
trevieze | 1:4b5ffae743c0 | 11 | |
trevieze | 1:4b5ffae743c0 | 12 | http://www.pocketmagic.net |
trevieze | 1:4b5ffae743c0 | 13 | |
trevieze | 1:4b5ffae743c0 | 14 | This program is free software; you can redistribute it and/or modify |
trevieze | 1:4b5ffae743c0 | 15 | it under the terms of the GNU General Public License as published by |
trevieze | 1:4b5ffae743c0 | 16 | the Free Software Foundation; either version 2 of the License, or |
trevieze | 1:4b5ffae743c0 | 17 | (at your option) any later version. |
trevieze | 1:4b5ffae743c0 | 18 | |
trevieze | 1:4b5ffae743c0 | 19 | This program is distributed in the hope that it will be useful, |
trevieze | 1:4b5ffae743c0 | 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
trevieze | 1:4b5ffae743c0 | 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
trevieze | 1:4b5ffae743c0 | 22 | GNU General Public License for more details. |
trevieze | 1:4b5ffae743c0 | 23 | |
trevieze | 1:4b5ffae743c0 | 24 | You should have received a copy of the GNU General Public License |
trevieze | 1:4b5ffae743c0 | 25 | along with this program; if not, write to the Free Software |
trevieze | 1:4b5ffae743c0 | 26 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
trevieze | 1:4b5ffae743c0 | 27 | **************************************************************************** |
trevieze | 1:4b5ffae743c0 | 28 | */ |
trevieze | 1:4b5ffae743c0 | 29 | |
trevieze | 1:4b5ffae743c0 | 30 | #include "nmea.h" |
trevieze | 1:4b5ffae743c0 | 31 | #include <stdio.h> |
trevieze | 1:4b5ffae743c0 | 32 | #include <stdlib.h> |
trevieze | 1:4b5ffae743c0 | 33 | |
trevieze | 1:4b5ffae743c0 | 34 | #include "mbed.h" |
trevieze | 1:4b5ffae743c0 | 35 | #include <stdint.h> |
trevieze | 1:4b5ffae743c0 | 36 | #include <math.h> |
trevieze | 1:4b5ffae743c0 | 37 | #include <ctype.h> |
trevieze | 1:4b5ffae743c0 | 38 | |
trevieze | 1:4b5ffae743c0 | 39 | //#include "../uart/uart.h" |
trevieze | 1:4b5ffae743c0 | 40 | //extern UART uart1; |
trevieze | 1:4b5ffae743c0 | 41 | |
trevieze | 1:4b5ffae743c0 | 42 | |
trevieze | 1:4b5ffae743c0 | 43 | /* |
trevieze | 1:4b5ffae743c0 | 44 | * The serial data is assembled on the fly, without using any redundant buffers. |
trevieze | 1:4b5ffae743c0 | 45 | * When a sentence is complete (one that starts with $, ending in EOL), all processing is done on |
trevieze | 1:4b5ffae743c0 | 46 | * this temporary buffer that we've built: checksum computation, extracting sentence "words" (the CSV values), |
trevieze | 1:4b5ffae743c0 | 47 | * and so on. |
trevieze | 1:4b5ffae743c0 | 48 | * When a new sentence is fully assembled using the fusedata function, the code calls parsedata. |
trevieze | 1:4b5ffae743c0 | 49 | * This function in turn, splits the sentences and interprets the data. Here is part of the parser function, |
trevieze | 1:4b5ffae743c0 | 50 | * handling both the $GPRMC NMEA sentence: |
trevieze | 1:4b5ffae743c0 | 51 | */ |
trevieze | 1:4b5ffae743c0 | 52 | int NMEA::fusedata(char c) { |
trevieze | 1:4b5ffae743c0 | 53 | |
trevieze | 1:4b5ffae743c0 | 54 | if (c == '$') { |
trevieze | 1:4b5ffae743c0 | 55 | m_bFlagRead = true; |
trevieze | 1:4b5ffae743c0 | 56 | // init parser vars |
trevieze | 1:4b5ffae743c0 | 57 | m_bFlagComputedCks = false; |
trevieze | 1:4b5ffae743c0 | 58 | m_nChecksum = 0; |
trevieze | 1:4b5ffae743c0 | 59 | // after getting * we start cuttings the received m_nChecksum |
trevieze | 1:4b5ffae743c0 | 60 | m_bFlagReceivedCks = false; |
trevieze | 1:4b5ffae743c0 | 61 | index_received_checksum = 0; |
trevieze | 1:4b5ffae743c0 | 62 | // word cutting variables |
trevieze | 1:4b5ffae743c0 | 63 | m_nWordIdx = 0; m_nPrevIdx = 0; m_nNowIdx = 0; |
trevieze | 1:4b5ffae743c0 | 64 | } |
trevieze | 1:4b5ffae743c0 | 65 | |
trevieze | 1:4b5ffae743c0 | 66 | if (m_bFlagRead) { |
trevieze | 1:4b5ffae743c0 | 67 | // check ending |
trevieze | 1:4b5ffae743c0 | 68 | if (c == '\r' || c== '\n') { |
trevieze | 1:4b5ffae743c0 | 69 | // catch last ending item too |
trevieze | 1:4b5ffae743c0 | 70 | tmp_words[m_nWordIdx][m_nNowIdx - m_nPrevIdx] = 0; |
trevieze | 1:4b5ffae743c0 | 71 | m_nWordIdx++; |
trevieze | 1:4b5ffae743c0 | 72 | // cut received m_nChecksum |
trevieze | 1:4b5ffae743c0 | 73 | tmp_szChecksum[index_received_checksum] = 0; |
trevieze | 1:4b5ffae743c0 | 74 | // sentence complete, read done |
trevieze | 1:4b5ffae743c0 | 75 | m_bFlagRead = false; |
trevieze | 1:4b5ffae743c0 | 76 | // parse |
trevieze | 1:4b5ffae743c0 | 77 | parsedata(); |
trevieze | 1:4b5ffae743c0 | 78 | } else { |
trevieze | 1:4b5ffae743c0 | 79 | // computed m_nChecksum logic: count all chars between $ and * exclusively |
trevieze | 1:4b5ffae743c0 | 80 | if (m_bFlagComputedCks && c == '*') m_bFlagComputedCks = false; |
trevieze | 1:4b5ffae743c0 | 81 | if (m_bFlagComputedCks) m_nChecksum ^= c; |
trevieze | 1:4b5ffae743c0 | 82 | if (c == '$') m_bFlagComputedCks = true; |
trevieze | 1:4b5ffae743c0 | 83 | // received m_nChecksum |
trevieze | 1:4b5ffae743c0 | 84 | if (m_bFlagReceivedCks) { |
trevieze | 1:4b5ffae743c0 | 85 | tmp_szChecksum[index_received_checksum] = c; |
trevieze | 1:4b5ffae743c0 | 86 | index_received_checksum++; |
trevieze | 1:4b5ffae743c0 | 87 | } |
trevieze | 1:4b5ffae743c0 | 88 | if (c == '*') m_bFlagReceivedCks = true; |
trevieze | 1:4b5ffae743c0 | 89 | // build a word |
trevieze | 1:4b5ffae743c0 | 90 | tmp_words[m_nWordIdx][m_nNowIdx - m_nPrevIdx] = c; |
trevieze | 1:4b5ffae743c0 | 91 | if (c == ',') { |
trevieze | 1:4b5ffae743c0 | 92 | tmp_words[m_nWordIdx][m_nNowIdx - m_nPrevIdx] = 0; |
trevieze | 1:4b5ffae743c0 | 93 | m_nWordIdx++; |
trevieze | 1:4b5ffae743c0 | 94 | m_nPrevIdx = m_nNowIdx; |
trevieze | 1:4b5ffae743c0 | 95 | } |
trevieze | 1:4b5ffae743c0 | 96 | else m_nNowIdx++; |
trevieze | 1:4b5ffae743c0 | 97 | } |
trevieze | 1:4b5ffae743c0 | 98 | } |
trevieze | 1:4b5ffae743c0 | 99 | return m_nWordIdx; |
trevieze | 1:4b5ffae743c0 | 100 | } |
trevieze | 1:4b5ffae743c0 | 101 | |
trevieze | 1:4b5ffae743c0 | 102 | |
trevieze | 1:4b5ffae743c0 | 103 | /* |
trevieze | 1:4b5ffae743c0 | 104 | * parse internal tmp_ structures, fused by pushdata, and set the data flag when done |
trevieze | 1:4b5ffae743c0 | 105 | */ |
trevieze | 1:4b5ffae743c0 | 106 | void NMEA::parsedata() { |
trevieze | 1:4b5ffae743c0 | 107 | int received_cks = 16*digit2dec(tmp_szChecksum[0]) + digit2dec(tmp_szChecksum[1]); |
trevieze | 1:4b5ffae743c0 | 108 | //uart1.Send("seq: [cc:%X][words:%d][rc:%s:%d]\r\n", m_nChecksum,m_nWordIdx, tmp_szChecksum, received_cks); |
trevieze | 1:4b5ffae743c0 | 109 | // check checksum, and return if invalid! |
trevieze | 1:4b5ffae743c0 | 110 | if (m_nChecksum != received_cks) { |
trevieze | 1:4b5ffae743c0 | 111 | //m_bFlagDataReady = false; |
trevieze | 1:4b5ffae743c0 | 112 | return; |
trevieze | 1:4b5ffae743c0 | 113 | } |
trevieze | 1:4b5ffae743c0 | 114 | /* $GPGGA |
trevieze | 1:4b5ffae743c0 | 115 | * $GPGGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh |
trevieze | 1:4b5ffae743c0 | 116 | * ex: $GPGGA,230600.501,4543.8895,N,02112.7238,E,1,03,3.3,96.7,M,39.0,M,,0000*6A, |
trevieze | 1:4b5ffae743c0 | 117 | * |
trevieze | 1:4b5ffae743c0 | 118 | * WORDS: |
trevieze | 1:4b5ffae743c0 | 119 | * 1 = UTC of Position |
trevieze | 1:4b5ffae743c0 | 120 | * 2 = Latitude |
trevieze | 1:4b5ffae743c0 | 121 | * 3 = N or S |
trevieze | 1:4b5ffae743c0 | 122 | * 4 = Longitude |
trevieze | 1:4b5ffae743c0 | 123 | * 5 = E or W |
trevieze | 1:4b5ffae743c0 | 124 | * 6 = GPS quality indicator (0=invalid; 1=GPS fix; 2=Diff. GPS fix) |
trevieze | 1:4b5ffae743c0 | 125 | * 7 = Number of satellites in use [not those in view] |
trevieze | 1:4b5ffae743c0 | 126 | * 8 = Horizontal dilution of position |
trevieze | 1:4b5ffae743c0 | 127 | * 9 = Antenna altitude above/below mean sea level (geoid) |
trevieze | 1:4b5ffae743c0 | 128 | * 10 = Meters (Antenna height unit) |
trevieze | 1:4b5ffae743c0 | 129 | * 11 = Geoidal separation (Diff. between WGS-84 earth ellipsoid and mean sea level. |
trevieze | 1:4b5ffae743c0 | 130 | * -geoid is below WGS-84 ellipsoid) |
trevieze | 1:4b5ffae743c0 | 131 | * 12 = Meters (Units of geoidal separation) |
trevieze | 1:4b5ffae743c0 | 132 | * 13 = Age in seconds since last update from diff. reference station |
trevieze | 1:4b5ffae743c0 | 133 | * 14 = Diff. reference station ID# |
trevieze | 1:4b5ffae743c0 | 134 | * 15 = Checksum |
trevieze | 1:4b5ffae743c0 | 135 | */ |
trevieze | 1:4b5ffae743c0 | 136 | if (mstrcmp(tmp_words[0], "$GPGGA") == 0) { |
trevieze | 1:4b5ffae743c0 | 137 | // Check GPS Fix: 0=no fix, 1=GPS fix, 2=Dif. GPS fix |
trevieze | 1:4b5ffae743c0 | 138 | if (tmp_words[6][0] == '0') { |
trevieze | 1:4b5ffae743c0 | 139 | // clear data |
trevieze | 1:4b5ffae743c0 | 140 | res_fLatitude = 0; |
trevieze | 1:4b5ffae743c0 | 141 | res_fLongitude = 0; |
trevieze | 1:4b5ffae743c0 | 142 | m_bFlagDataReady = false; |
trevieze | 1:4b5ffae743c0 | 143 | return; |
trevieze | 1:4b5ffae743c0 | 144 | } |
trevieze | 1:4b5ffae743c0 | 145 | // parse time |
trevieze | 1:4b5ffae743c0 | 146 | res_nUTCHour = digit2dec(tmp_words[1][0]) * 10 + digit2dec(tmp_words[1][1]); |
trevieze | 1:4b5ffae743c0 | 147 | res_nUTCMin = digit2dec(tmp_words[1][2]) * 10 + digit2dec(tmp_words[1][3]); |
trevieze | 1:4b5ffae743c0 | 148 | res_nUTCSec = digit2dec(tmp_words[1][4]) * 10 + digit2dec(tmp_words[1][5]); |
trevieze | 1:4b5ffae743c0 | 149 | // parse latitude and longitude in NMEA format |
trevieze | 1:4b5ffae743c0 | 150 | res_fLatitude = string2float(tmp_words[2]); |
trevieze | 1:4b5ffae743c0 | 151 | res_fLongitude = string2float(tmp_words[4]); |
trevieze | 1:4b5ffae743c0 | 152 | // get decimal format |
trevieze | 1:4b5ffae743c0 | 153 | if (tmp_words[3][0] == 'S') res_fLatitude *= -1.0; |
trevieze | 1:4b5ffae743c0 | 154 | if (tmp_words[5][0] == 'W') res_fLongitude *= -1.0; |
trevieze | 1:4b5ffae743c0 | 155 | float degrees = trunc(res_fLatitude / 100.0f); |
trevieze | 1:4b5ffae743c0 | 156 | float minutes = res_fLatitude - (degrees * 100.0f); |
trevieze | 1:4b5ffae743c0 | 157 | res_fLatitude = degrees + minutes / 60.0f; |
trevieze | 1:4b5ffae743c0 | 158 | degrees = trunc(res_fLongitude / 100.0f); |
trevieze | 1:4b5ffae743c0 | 159 | minutes = res_fLongitude - (degrees * 100.0f); |
trevieze | 1:4b5ffae743c0 | 160 | res_fLongitude = degrees + minutes / 60.0f; |
trevieze | 1:4b5ffae743c0 | 161 | |
trevieze | 1:4b5ffae743c0 | 162 | // parse number of satellites |
trevieze | 1:4b5ffae743c0 | 163 | res_nSatellitesUsed = (int)string2float(tmp_words[7]); |
trevieze | 1:4b5ffae743c0 | 164 | |
trevieze | 1:4b5ffae743c0 | 165 | // parse altitude |
trevieze | 1:4b5ffae743c0 | 166 | res_fAltitude = string2float(tmp_words[9]); |
trevieze | 1:4b5ffae743c0 | 167 | |
trevieze | 1:4b5ffae743c0 | 168 | // data ready |
trevieze | 1:4b5ffae743c0 | 169 | m_bFlagDataReady = true; |
trevieze | 1:4b5ffae743c0 | 170 | } |
trevieze | 1:4b5ffae743c0 | 171 | |
trevieze | 1:4b5ffae743c0 | 172 | /* $GPRMC |
trevieze | 1:4b5ffae743c0 | 173 | * note: a siRF chipset will not support magnetic headers. |
trevieze | 1:4b5ffae743c0 | 174 | * $GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a*hh |
trevieze | 1:4b5ffae743c0 | 175 | * ex: $GPRMC,230558.501,A,4543.8901,N,02112.7219,E,1.50,181.47,230213,,,A*66, |
trevieze | 1:4b5ffae743c0 | 176 | * |
trevieze | 1:4b5ffae743c0 | 177 | * WORDS: |
trevieze | 1:4b5ffae743c0 | 178 | * 1 = UTC of position fix |
trevieze | 1:4b5ffae743c0 | 179 | * 2 = Data status (V=navigation receiver warning) |
trevieze | 1:4b5ffae743c0 | 180 | * 3 = Latitude of fix |
trevieze | 1:4b5ffae743c0 | 181 | * 4 = N or S |
trevieze | 1:4b5ffae743c0 | 182 | * 5 = Longitude of fix |
trevieze | 1:4b5ffae743c0 | 183 | * 6 = E or W |
trevieze | 1:4b5ffae743c0 | 184 | * 7 = Speed over ground in knots |
trevieze | 1:4b5ffae743c0 | 185 | * 8 = Track made good in degrees True, Bearing This indicates the direction that the device is currently moving in, |
trevieze | 1:4b5ffae743c0 | 186 | * from 0 to 360, measured in �azimuth�. |
trevieze | 1:4b5ffae743c0 | 187 | * 9 = UT date |
trevieze | 1:4b5ffae743c0 | 188 | * 10 = Magnetic variation degrees (Easterly var. subtracts from true course) |
trevieze | 1:4b5ffae743c0 | 189 | * 11 = E or W |
trevieze | 1:4b5ffae743c0 | 190 | * 12 = Checksum |
trevieze | 1:4b5ffae743c0 | 191 | */ |
trevieze | 1:4b5ffae743c0 | 192 | if (mstrcmp(tmp_words[0], "$GPRMC") == 0) { |
trevieze | 1:4b5ffae743c0 | 193 | // Check data status: A-ok, V-invalid |
trevieze | 1:4b5ffae743c0 | 194 | if (tmp_words[2][0] == 'V') { |
trevieze | 1:4b5ffae743c0 | 195 | // clear data |
trevieze | 1:4b5ffae743c0 | 196 | res_fLatitude = 0; |
trevieze | 1:4b5ffae743c0 | 197 | res_fLongitude = 0; |
trevieze | 1:4b5ffae743c0 | 198 | m_bFlagDataReady = false; |
trevieze | 1:4b5ffae743c0 | 199 | return; |
trevieze | 1:4b5ffae743c0 | 200 | } |
trevieze | 1:4b5ffae743c0 | 201 | // parse time |
trevieze | 1:4b5ffae743c0 | 202 | res_nUTCHour = digit2dec(tmp_words[1][0]) * 10 + digit2dec(tmp_words[1][1]); |
trevieze | 1:4b5ffae743c0 | 203 | res_nUTCMin = digit2dec(tmp_words[1][2]) * 10 + digit2dec(tmp_words[1][3]); |
trevieze | 1:4b5ffae743c0 | 204 | res_nUTCSec = digit2dec(tmp_words[1][4]) * 10 + digit2dec(tmp_words[1][5]); |
trevieze | 1:4b5ffae743c0 | 205 | // parse latitude and longitude in NMEA format |
trevieze | 1:4b5ffae743c0 | 206 | res_fLatitude = string2float(tmp_words[3]); |
trevieze | 1:4b5ffae743c0 | 207 | res_fLongitude = string2float(tmp_words[5]); |
trevieze | 1:4b5ffae743c0 | 208 | // get decimal format |
trevieze | 1:4b5ffae743c0 | 209 | if (tmp_words[4][0] == 'S') res_fLatitude *= -1.0; |
trevieze | 5:c5f700c1e1af | 210 | res_clat = tmp_words[4][0]; |
trevieze | 1:4b5ffae743c0 | 211 | if (tmp_words[6][0] == 'W') res_fLongitude *= -1.0; |
trevieze | 5:c5f700c1e1af | 212 | res_clon = tmp_words[6][0]; |
trevieze | 1:4b5ffae743c0 | 213 | float degrees = trunc(res_fLatitude / 100.0f); |
trevieze | 1:4b5ffae743c0 | 214 | float minutes = res_fLatitude - (degrees * 100.0f); |
trevieze | 1:4b5ffae743c0 | 215 | res_fLatitude = degrees + minutes / 60.0f; |
trevieze | 1:4b5ffae743c0 | 216 | degrees = trunc(res_fLongitude / 100.0f); |
trevieze | 1:4b5ffae743c0 | 217 | minutes = res_fLongitude - (degrees * 100.0f); |
trevieze | 1:4b5ffae743c0 | 218 | res_fLongitude = degrees + minutes / 60.0f; |
trevieze | 1:4b5ffae743c0 | 219 | //parse speed |
trevieze | 1:4b5ffae743c0 | 220 | // The knot (pronounced not) is a unit of speed equal to one nautical mile (1.852 km) per hour |
trevieze | 1:4b5ffae743c0 | 221 | res_fSpeed = string2float(tmp_words[7]); |
trevieze | 6:f0c13bb7d266 | 222 | res_fSpeed *= double(1.852); // convert to km/h 1knot = 1.852Km, Was res_fSpeed /= 1.852; |
trevieze | 1:4b5ffae743c0 | 223 | // parse bearing |
trevieze | 1:4b5ffae743c0 | 224 | res_fBearing = string2float(tmp_words[8]); |
trevieze | 1:4b5ffae743c0 | 225 | // parse UTC date |
trevieze | 1:4b5ffae743c0 | 226 | res_nUTCDay = digit2dec(tmp_words[9][0]) * 10 + digit2dec(tmp_words[9][1]); |
trevieze | 1:4b5ffae743c0 | 227 | res_nUTCMonth = digit2dec(tmp_words[9][2]) * 10 + digit2dec(tmp_words[9][3]); |
trevieze | 1:4b5ffae743c0 | 228 | res_nUTCYear = digit2dec(tmp_words[9][4]) * 10 + digit2dec(tmp_words[9][5]); |
trevieze | 1:4b5ffae743c0 | 229 | |
trevieze | 1:4b5ffae743c0 | 230 | // data ready |
trevieze | 1:4b5ffae743c0 | 231 | m_bFlagDataReady = true; |
trevieze | 1:4b5ffae743c0 | 232 | } |
trevieze | 1:4b5ffae743c0 | 233 | } |
trevieze | 1:4b5ffae743c0 | 234 | /* |
trevieze | 1:4b5ffae743c0 | 235 | * returns base-16 value of chars '0'-'9' and 'A'-'F'; |
trevieze | 1:4b5ffae743c0 | 236 | * does not trap invalid chars! |
trevieze | 1:4b5ffae743c0 | 237 | */ |
trevieze | 1:4b5ffae743c0 | 238 | int NMEA::digit2dec(char digit) { |
trevieze | 1:4b5ffae743c0 | 239 | if (int(digit) >= 65) |
trevieze | 1:4b5ffae743c0 | 240 | return int(digit) - 55; |
trevieze | 1:4b5ffae743c0 | 241 | else |
trevieze | 1:4b5ffae743c0 | 242 | return int(digit) - 48; |
trevieze | 1:4b5ffae743c0 | 243 | } |
trevieze | 1:4b5ffae743c0 | 244 | |
trevieze | 1:4b5ffae743c0 | 245 | /* returns base-10 value of zero-terminated string |
trevieze | 1:4b5ffae743c0 | 246 | * that contains only chars '+','-','0'-'9','.'; |
trevieze | 1:4b5ffae743c0 | 247 | * does not trap invalid strings! |
trevieze | 1:4b5ffae743c0 | 248 | */ |
trevieze | 1:4b5ffae743c0 | 249 | float NMEA::string2float(char* s) { |
trevieze | 1:4b5ffae743c0 | 250 | long integer_part = 0; |
trevieze | 1:4b5ffae743c0 | 251 | float decimal_part = 0.0; |
trevieze | 1:4b5ffae743c0 | 252 | float decimal_pivot = 0.1; |
trevieze | 1:4b5ffae743c0 | 253 | bool isdecimal = false, isnegative = false; |
trevieze | 1:4b5ffae743c0 | 254 | |
trevieze | 1:4b5ffae743c0 | 255 | char c; |
trevieze | 1:4b5ffae743c0 | 256 | while ( ( c = *s++) ) { |
trevieze | 1:4b5ffae743c0 | 257 | // skip special/sign chars |
trevieze | 1:4b5ffae743c0 | 258 | if (c == '-') { isnegative = true; continue; } |
trevieze | 1:4b5ffae743c0 | 259 | if (c == '+') continue; |
trevieze | 1:4b5ffae743c0 | 260 | if (c == '.') { isdecimal = true; continue; } |
trevieze | 1:4b5ffae743c0 | 261 | |
trevieze | 1:4b5ffae743c0 | 262 | if (!isdecimal) { |
trevieze | 1:4b5ffae743c0 | 263 | integer_part = (10 * integer_part) + (c - 48); |
trevieze | 1:4b5ffae743c0 | 264 | } |
trevieze | 1:4b5ffae743c0 | 265 | else { |
trevieze | 1:4b5ffae743c0 | 266 | decimal_part += decimal_pivot * (float)(c - 48); |
trevieze | 1:4b5ffae743c0 | 267 | decimal_pivot /= 10.0; |
trevieze | 1:4b5ffae743c0 | 268 | } |
trevieze | 1:4b5ffae743c0 | 269 | } |
trevieze | 1:4b5ffae743c0 | 270 | // add integer part |
trevieze | 1:4b5ffae743c0 | 271 | decimal_part += (float)integer_part; |
trevieze | 1:4b5ffae743c0 | 272 | |
trevieze | 1:4b5ffae743c0 | 273 | // check negative |
trevieze | 1:4b5ffae743c0 | 274 | if (isnegative) decimal_part = - decimal_part; |
trevieze | 1:4b5ffae743c0 | 275 | |
trevieze | 1:4b5ffae743c0 | 276 | return decimal_part; |
trevieze | 1:4b5ffae743c0 | 277 | } |
trevieze | 1:4b5ffae743c0 | 278 | |
trevieze | 1:4b5ffae743c0 | 279 | int NMEA::mstrcmp(const char *s1, const char *s2) |
trevieze | 1:4b5ffae743c0 | 280 | { |
trevieze | 1:4b5ffae743c0 | 281 | while((*s1 && *s2) && (*s1 == *s2)) |
trevieze | 1:4b5ffae743c0 | 282 | s1++,s2++; |
trevieze | 1:4b5ffae743c0 | 283 | return *s1 - *s2; |
trevieze | 1:4b5ffae743c0 | 284 | } |
trevieze | 1:4b5ffae743c0 | 285 | |
trevieze | 1:4b5ffae743c0 | 286 | bool NMEA::isdataready() { |
trevieze | 1:4b5ffae743c0 | 287 | return m_bFlagDataReady; |
trevieze | 1:4b5ffae743c0 | 288 | } |
trevieze | 1:4b5ffae743c0 | 289 | |
trevieze | 1:4b5ffae743c0 | 290 | int NMEA::getHour() { |
trevieze | 1:4b5ffae743c0 | 291 | return res_nUTCHour; |
trevieze | 1:4b5ffae743c0 | 292 | } |
trevieze | 1:4b5ffae743c0 | 293 | int NMEA::getMinute() { |
trevieze | 1:4b5ffae743c0 | 294 | return res_nUTCMin; |
trevieze | 1:4b5ffae743c0 | 295 | } |
trevieze | 1:4b5ffae743c0 | 296 | int NMEA::getSecond() { |
trevieze | 1:4b5ffae743c0 | 297 | return res_nUTCSec; |
trevieze | 1:4b5ffae743c0 | 298 | } |
trevieze | 1:4b5ffae743c0 | 299 | int NMEA::getDay() { |
trevieze | 1:4b5ffae743c0 | 300 | return res_nUTCDay; |
trevieze | 1:4b5ffae743c0 | 301 | } |
trevieze | 1:4b5ffae743c0 | 302 | int NMEA::getMonth() { |
trevieze | 1:4b5ffae743c0 | 303 | return res_nUTCMonth; |
trevieze | 1:4b5ffae743c0 | 304 | } |
trevieze | 1:4b5ffae743c0 | 305 | int NMEA::getYear() { |
trevieze | 1:4b5ffae743c0 | 306 | return res_nUTCYear; |
trevieze | 1:4b5ffae743c0 | 307 | } |
trevieze | 1:4b5ffae743c0 | 308 | |
trevieze | 1:4b5ffae743c0 | 309 | float NMEA::getLatitude() { |
trevieze | 1:4b5ffae743c0 | 310 | return res_fLatitude; |
trevieze | 1:4b5ffae743c0 | 311 | } |
trevieze | 1:4b5ffae743c0 | 312 | |
trevieze | 1:4b5ffae743c0 | 313 | float NMEA::getLongitude() { |
trevieze | 1:4b5ffae743c0 | 314 | return res_fLongitude; |
trevieze | 1:4b5ffae743c0 | 315 | } |
trevieze | 1:4b5ffae743c0 | 316 | |
trevieze | 1:4b5ffae743c0 | 317 | int NMEA::getSatellites() { |
trevieze | 1:4b5ffae743c0 | 318 | return res_nSatellitesUsed; |
trevieze | 1:4b5ffae743c0 | 319 | } |
trevieze | 1:4b5ffae743c0 | 320 | |
trevieze | 1:4b5ffae743c0 | 321 | float NMEA::getAltitude() { |
trevieze | 1:4b5ffae743c0 | 322 | return res_fAltitude; |
trevieze | 1:4b5ffae743c0 | 323 | } |
trevieze | 1:4b5ffae743c0 | 324 | |
trevieze | 1:4b5ffae743c0 | 325 | float NMEA::getSpeed() { |
trevieze | 1:4b5ffae743c0 | 326 | return res_fSpeed; |
trevieze | 1:4b5ffae743c0 | 327 | } |
trevieze | 1:4b5ffae743c0 | 328 | |
trevieze | 1:4b5ffae743c0 | 329 | float NMEA::getBearing() { |
trevieze | 1:4b5ffae743c0 | 330 | return res_fBearing; |
trevieze | 1:4b5ffae743c0 | 331 | } |
trevieze | 1:4b5ffae743c0 | 332 | |
trevieze | 5:c5f700c1e1af | 333 | char NMEA::getlatc() { |
trevieze | 5:c5f700c1e1af | 334 | return res_clat; |
trevieze | 5:c5f700c1e1af | 335 | } |
trevieze | 5:c5f700c1e1af | 336 | |
trevieze | 5:c5f700c1e1af | 337 | char NMEA::getlonc() { |
trevieze | 5:c5f700c1e1af | 338 | return res_clon; |
trevieze | 5:c5f700c1e1af | 339 | } |
trevieze | 5:c5f700c1e1af | 340 | |
trevieze | 1:4b5ffae743c0 | 341 | float NMEA::trunc(float v) { |
trevieze | 1:4b5ffae743c0 | 342 | if(v < 0.0) { |
trevieze | 1:4b5ffae743c0 | 343 | v*= -1.0; |
trevieze | 1:4b5ffae743c0 | 344 | v = floor(v); |
trevieze | 1:4b5ffae743c0 | 345 | v*=-1.0; |
trevieze | 1:4b5ffae743c0 | 346 | } else { |
trevieze | 1:4b5ffae743c0 | 347 | v = floor(v); |
trevieze | 1:4b5ffae743c0 | 348 | } |
trevieze | 1:4b5ffae743c0 | 349 | return v; |
trevieze | 1:4b5ffae743c0 | 350 | } |