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"); } } }
Revision 1:4b5ffae743c0, committed 2017-02-10
- Comitter:
- trevieze
- Date:
- Fri Feb 10 17:57:45 2017 +0000
- Parent:
- 0:15611c7938a3
- Child:
- 2:dbc6c0789611
- Commit message:
- New interrupt service handler for NMEA library
Changed in this revision
--- a/GPS.cpp Tue Jun 08 14:10:27 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* mbed EM-406 GPS Module Library - * Copyright (c) 2008-2010, sford - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "GPS.h" - -GPS::GPS(PinName tx, PinName rx) : _gps(tx, rx) { - _gps.baud(4800); - longitude = 0.0; - latitude = 0.0; -} - -int GPS::sample() { - float time; - char ns, ew; - int lock; - - while(1) { - getline(); - - // Check if it is a GPGGA msg (matches both locked and non-locked msg) - if(sscanf(msg, "GPGGA,%f,%f,%c,%f,%c,%d", &time, &latitude, &ns, &longitude, &ew, &lock) >= 1) { - if(!lock) { - longitude = 0.0; - latitude = 0.0; - return 0; - } else { - if(ns == 'S') { latitude *= -1.0; } - if(ew == 'W') { longitude *= -1.0; } - float degrees = trunc(latitude / 100.0f); - float minutes = latitude - (degrees * 100.0f); - latitude = degrees + minutes / 60.0f; - degrees = trunc(longitude / 100.0f * 0.01f); - minutes = longitude - (degrees * 100.0f); - longitude = degrees + minutes / 60.0f; - return 1; - } - } - } -} - -float GPS::trunc(float v) { - if(v < 0.0) { - v*= -1.0; - v = floor(v); - v*=-1.0; - } else { - v = floor(v); - } - return v; -} - -void GPS::getline() { - while(_gps.getc() != '$'); // wait for the start of a line - for(int i=0; i<256; i++) { - msg[i] = _gps.getc(); - if(msg[i] == '\r') { - msg[i] = 0; - return; - } - } - error("Overflowed message limit"); -}
--- a/GPS.h Tue Jun 08 14:10:27 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* mbed EM-406 GPS Module Library - * Copyright (c) 2008-2010, sford - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "mbed.h" - -#ifndef MBED_GPS_H -#define MBED_GPS_H - -/** A GPS interface for reading from a Globalsat EM-406 GPS Module */ -class GPS { -public: - - /** Create the GPS interface, connected to the specified serial port - */ - GPS(PinName tx, PinName rx); - - /** Sample the incoming GPS data, returning whether there is a lock - * - * @return 1 if there was a lock when the sample was taken (and therefore .longitude and .latitude are valid), else 0 - */ - int sample(); - - /** The longitude (call sample() to set) */ - float longitude; - - /** The latitude (call sample() to set) */ - float latitude; - -private: - float trunc(float v); - void getline(); - - Serial _gps; - char msg[256]; - -}; - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GPSISR.cpp Fri Feb 10 17:57:45 2017 +0000 @@ -0,0 +1,50 @@ +/* mbed EM-406 GPS Module Library + * Copyright (c) 2008-2010, sford + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "GPSISR.h" + +GPS::GPS(PinName tx, PinName rx, int Baud) : _gps(tx, rx) { + _gps.baud(Baud); + _gps.attach(this,&GPS::Rx_interrupt, Serial::RxIrq); + printf("Interrupt Attached"); +} + +void GPS::getline() { + while(_gps.getc() != '$'); // wait for the start of a line + for(int i=0; i<256; i++) { + msg[i] = _gps.getc(); + if(msg[i] == '\r') { + msg[i] = 0; + return; + } + } + error("Overflowed message limit"); + return; +} + +// Interupt Routine to read in data from serial port +void GPS::Rx_interrupt(void) { + interrupt = 1; + rx_in = _gps.getc(); + interrupt = 0; + return; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GPSISR.h Fri Feb 10 17:57:45 2017 +0000 @@ -0,0 +1,47 @@ +/* mbed EM-406 GPS Module Library + * Copyright (c) 2008-2010, sford + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "mbed.h" + +#ifndef MBED_GPS_H +#define MBED_GPS_H + +/** A GPS interface for reading from a Globalsat EM-406 GPS Module */ +class GPS { +public: + + /** Create the GPS interface, connected to the specified serial port + */ + GPS(PinName tx, PinName rx, int Baud); + //Peripheral + Serial _gps; + // Setup a serial interrupt function to transmit data + void getline(); + void Rx_interrupt(void); + char msg[256]; + volatile char rx_in; + bool interrupt; +private: + + }; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nmea.cpp Fri Feb 10 17:57:45 2017 +0000 @@ -0,0 +1,340 @@ +/* + File: nmea.cpp + Version: 0.1.0 + Date: Feb. 23, 2013 + License: GPL v2 + + NMEA GPS content parser + + **************************************************************************** + Copyright (C) 2013 Radu Motisan <radu.motisan@gmail.com> + + http://www.pocketmagic.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + **************************************************************************** + */ + +#include "nmea.h" +#include <stdio.h> +#include <stdlib.h> + +#include "mbed.h" +#include <stdint.h> +#include <math.h> +#include <ctype.h> + +//#include "../uart/uart.h" +//extern UART uart1; + + +/* + * The serial data is assembled on the fly, without using any redundant buffers. + * When a sentence is complete (one that starts with $, ending in EOL), all processing is done on + * this temporary buffer that we've built: checksum computation, extracting sentence "words" (the CSV values), + * and so on. + * When a new sentence is fully assembled using the fusedata function, the code calls parsedata. + * This function in turn, splits the sentences and interprets the data. Here is part of the parser function, + * handling both the $GPRMC NMEA sentence: + */ +int NMEA::fusedata(char c) { + + if (c == '$') { + m_bFlagRead = true; + // init parser vars + m_bFlagComputedCks = false; + m_nChecksum = 0; + // after getting * we start cuttings the received m_nChecksum + m_bFlagReceivedCks = false; + index_received_checksum = 0; + // word cutting variables + m_nWordIdx = 0; m_nPrevIdx = 0; m_nNowIdx = 0; + } + + if (m_bFlagRead) { + // check ending + if (c == '\r' || c== '\n') { + // catch last ending item too + tmp_words[m_nWordIdx][m_nNowIdx - m_nPrevIdx] = 0; + m_nWordIdx++; + // cut received m_nChecksum + tmp_szChecksum[index_received_checksum] = 0; + // sentence complete, read done + m_bFlagRead = false; + // parse + parsedata(); + } else { + // computed m_nChecksum logic: count all chars between $ and * exclusively + if (m_bFlagComputedCks && c == '*') m_bFlagComputedCks = false; + if (m_bFlagComputedCks) m_nChecksum ^= c; + if (c == '$') m_bFlagComputedCks = true; + // received m_nChecksum + if (m_bFlagReceivedCks) { + tmp_szChecksum[index_received_checksum] = c; + index_received_checksum++; + } + if (c == '*') m_bFlagReceivedCks = true; + // build a word + tmp_words[m_nWordIdx][m_nNowIdx - m_nPrevIdx] = c; + if (c == ',') { + tmp_words[m_nWordIdx][m_nNowIdx - m_nPrevIdx] = 0; + m_nWordIdx++; + m_nPrevIdx = m_nNowIdx; + } + else m_nNowIdx++; + } + } + return m_nWordIdx; +} + + +/* + * parse internal tmp_ structures, fused by pushdata, and set the data flag when done + */ +void NMEA::parsedata() { + int received_cks = 16*digit2dec(tmp_szChecksum[0]) + digit2dec(tmp_szChecksum[1]); + //uart1.Send("seq: [cc:%X][words:%d][rc:%s:%d]\r\n", m_nChecksum,m_nWordIdx, tmp_szChecksum, received_cks); + // check checksum, and return if invalid! + if (m_nChecksum != received_cks) { + //m_bFlagDataReady = false; + return; + } + /* $GPGGA + * $GPGGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh + * ex: $GPGGA,230600.501,4543.8895,N,02112.7238,E,1,03,3.3,96.7,M,39.0,M,,0000*6A, + * + * WORDS: + * 1 = UTC of Position + * 2 = Latitude + * 3 = N or S + * 4 = Longitude + * 5 = E or W + * 6 = GPS quality indicator (0=invalid; 1=GPS fix; 2=Diff. GPS fix) + * 7 = Number of satellites in use [not those in view] + * 8 = Horizontal dilution of position + * 9 = Antenna altitude above/below mean sea level (geoid) + * 10 = Meters (Antenna height unit) + * 11 = Geoidal separation (Diff. between WGS-84 earth ellipsoid and mean sea level. + * -geoid is below WGS-84 ellipsoid) + * 12 = Meters (Units of geoidal separation) + * 13 = Age in seconds since last update from diff. reference station + * 14 = Diff. reference station ID# + * 15 = Checksum + */ + if (mstrcmp(tmp_words[0], "$GPGGA") == 0) { + // Check GPS Fix: 0=no fix, 1=GPS fix, 2=Dif. GPS fix + if (tmp_words[6][0] == '0') { + // clear data + res_fLatitude = 0; + res_fLongitude = 0; + m_bFlagDataReady = false; + return; + } + // parse time + res_nUTCHour = digit2dec(tmp_words[1][0]) * 10 + digit2dec(tmp_words[1][1]); + res_nUTCMin = digit2dec(tmp_words[1][2]) * 10 + digit2dec(tmp_words[1][3]); + res_nUTCSec = digit2dec(tmp_words[1][4]) * 10 + digit2dec(tmp_words[1][5]); + // parse latitude and longitude in NMEA format + res_fLatitude = string2float(tmp_words[2]); + res_fLongitude = string2float(tmp_words[4]); + // get decimal format + if (tmp_words[3][0] == 'S') res_fLatitude *= -1.0; + if (tmp_words[5][0] == 'W') res_fLongitude *= -1.0; + float degrees = trunc(res_fLatitude / 100.0f); + float minutes = res_fLatitude - (degrees * 100.0f); + res_fLatitude = degrees + minutes / 60.0f; + degrees = trunc(res_fLongitude / 100.0f); + minutes = res_fLongitude - (degrees * 100.0f); + res_fLongitude = degrees + minutes / 60.0f; + + // parse number of satellites + res_nSatellitesUsed = (int)string2float(tmp_words[7]); + + // parse altitude + res_fAltitude = string2float(tmp_words[9]); + + // data ready + m_bFlagDataReady = true; + } + + /* $GPRMC + * note: a siRF chipset will not support magnetic headers. + * $GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a*hh + * ex: $GPRMC,230558.501,A,4543.8901,N,02112.7219,E,1.50,181.47,230213,,,A*66, + * + * WORDS: + * 1 = UTC of position fix + * 2 = Data status (V=navigation receiver warning) + * 3 = Latitude of fix + * 4 = N or S + * 5 = Longitude of fix + * 6 = E or W + * 7 = Speed over ground in knots + * 8 = Track made good in degrees True, Bearing This indicates the direction that the device is currently moving in, + * from 0 to 360, measured in �azimuth�. + * 9 = UT date + * 10 = Magnetic variation degrees (Easterly var. subtracts from true course) + * 11 = E or W + * 12 = Checksum + */ + if (mstrcmp(tmp_words[0], "$GPRMC") == 0) { + // Check data status: A-ok, V-invalid + if (tmp_words[2][0] == 'V') { + // clear data + res_fLatitude = 0; + res_fLongitude = 0; + m_bFlagDataReady = false; + return; + } + // parse time + res_nUTCHour = digit2dec(tmp_words[1][0]) * 10 + digit2dec(tmp_words[1][1]); + res_nUTCMin = digit2dec(tmp_words[1][2]) * 10 + digit2dec(tmp_words[1][3]); + res_nUTCSec = digit2dec(tmp_words[1][4]) * 10 + digit2dec(tmp_words[1][5]); + // parse latitude and longitude in NMEA format + res_fLatitude = string2float(tmp_words[3]); + res_fLongitude = string2float(tmp_words[5]); + // get decimal format + if (tmp_words[4][0] == 'S') res_fLatitude *= -1.0; + if (tmp_words[6][0] == 'W') res_fLongitude *= -1.0; + float degrees = trunc(res_fLatitude / 100.0f); + float minutes = res_fLatitude - (degrees * 100.0f); + res_fLatitude = degrees + minutes / 60.0f; + degrees = trunc(res_fLongitude / 100.0f); + minutes = res_fLongitude - (degrees * 100.0f); + res_fLongitude = degrees + minutes / 60.0f; + //parse speed + // The knot (pronounced not) is a unit of speed equal to one nautical mile (1.852 km) per hour + res_fSpeed = string2float(tmp_words[7]); + res_fSpeed /= 1.852; // convert to km/h + // parse bearing + res_fBearing = string2float(tmp_words[8]); + // parse UTC date + res_nUTCDay = digit2dec(tmp_words[9][0]) * 10 + digit2dec(tmp_words[9][1]); + res_nUTCMonth = digit2dec(tmp_words[9][2]) * 10 + digit2dec(tmp_words[9][3]); + res_nUTCYear = digit2dec(tmp_words[9][4]) * 10 + digit2dec(tmp_words[9][5]); + + // data ready + m_bFlagDataReady = true; + } +} +/* + * returns base-16 value of chars '0'-'9' and 'A'-'F'; + * does not trap invalid chars! + */ +int NMEA::digit2dec(char digit) { + if (int(digit) >= 65) + return int(digit) - 55; + else + return int(digit) - 48; +} + +/* returns base-10 value of zero-terminated string + * that contains only chars '+','-','0'-'9','.'; + * does not trap invalid strings! + */ +float NMEA::string2float(char* s) { + long integer_part = 0; + float decimal_part = 0.0; + float decimal_pivot = 0.1; + bool isdecimal = false, isnegative = false; + + char c; + while ( ( c = *s++) ) { + // skip special/sign chars + if (c == '-') { isnegative = true; continue; } + if (c == '+') continue; + if (c == '.') { isdecimal = true; continue; } + + if (!isdecimal) { + integer_part = (10 * integer_part) + (c - 48); + } + else { + decimal_part += decimal_pivot * (float)(c - 48); + decimal_pivot /= 10.0; + } + } + // add integer part + decimal_part += (float)integer_part; + + // check negative + if (isnegative) decimal_part = - decimal_part; + + return decimal_part; +} + +int NMEA::mstrcmp(const char *s1, const char *s2) +{ + while((*s1 && *s2) && (*s1 == *s2)) + s1++,s2++; + return *s1 - *s2; +} + +bool NMEA::isdataready() { + return m_bFlagDataReady; +} + +int NMEA::getHour() { + return res_nUTCHour; +} +int NMEA::getMinute() { + return res_nUTCMin; +} +int NMEA::getSecond() { + return res_nUTCSec; +} +int NMEA::getDay() { + return res_nUTCDay; +} +int NMEA::getMonth() { + return res_nUTCMonth; +} +int NMEA::getYear() { + return res_nUTCYear; +} + +float NMEA::getLatitude() { + return res_fLatitude; +} + +float NMEA::getLongitude() { + return res_fLongitude; +} + +int NMEA::getSatellites() { + return res_nSatellitesUsed; +} + +float NMEA::getAltitude() { + return res_fAltitude; +} + +float NMEA::getSpeed() { + return res_fSpeed; +} + +float NMEA::getBearing() { + return res_fBearing; +} + +float NMEA::trunc(float v) { + if(v < 0.0) { + v*= -1.0; + v = floor(v); + v*=-1.0; + } else { + v = floor(v); + } + return v; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nmea.h Fri Feb 10 17:57:45 2017 +0000 @@ -0,0 +1,104 @@ +/* + File: nmea.h + Version: 0.1.0 + Date: Feb. 23, 2013 + License: GPL v2 + + NMEA GPS content parser + + **************************************************************************** + Copyright (C) 2013 Radu Motisan <radu.motisan@gmail.com> + + http://www.pocketmagic.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + **************************************************************************** + */ +//#include "../timeout.h" + + + +class NMEA { + + private: + bool m_bFlagRead, // flag used by the parser, when a valid sentence has begun + m_bFlagDataReady; // valid GPS fix and data available, user can call reader functions + char tmp_words[20][15], // hold parsed words for one given NMEA sentence + tmp_szChecksum[15]; // hold the received checksum for one given NMEA sentence + + // will be set to true for characters between $ and * only + bool m_bFlagComputedCks ; // used to compute checksum and indicate valid checksum interval (between $ and * in a given sentence) + int m_nChecksum ; // numeric checksum, computed for a given sentence + bool m_bFlagReceivedCks ; // after getting * we start cuttings the received checksum + int index_received_checksum ; // used to parse received checksum + + // word cutting variables + int m_nWordIdx , // the current word in a sentence + m_nPrevIdx, // last character index where we did a cut + m_nNowIdx ; // current character index + + // globals to store parser results + float res_fLongitude; // GPRMC and GPGGA + float res_fLatitude; // GPRMC and GPGGA + unsigned char res_nUTCHour, res_nUTCMin, res_nUTCSec, // GPRMC and GPGGA + res_nUTCDay, res_nUTCMonth, res_nUTCYear; // GPRMC + int res_nSatellitesUsed; // GPGGA + float res_fAltitude; // GPGGA + float res_fSpeed; // GPRMC + float res_fBearing; // GPRMC + + // the parser, currently handling GPRMC and GPGGA, but easy to add any new sentences + void parsedata(); + // aux functions + int digit2dec(char hexdigit); + float string2float(char* s); + int mstrcmp(const char *s1, const char *s2); + float trunc(float v); + + public: + // constructor, initing a few variables + NMEA() { + m_bFlagRead = false; //are we in a sentence? + m_bFlagDataReady = false; //is data available? + } + + /* + * The serial data is assembled on the fly, without using any redundant buffers. + * When a sentence is complete (one that starts with $, ending in EOL), all processing is done on + * this temporary buffer that we've built: checksum computation, extracting sentence "words" (the CSV values), + * and so on. + * When a new sentence is fully assembled using the fusedata function, the code calls parsedata. + * This function in turn, splits the sentences and interprets the data. Here is part of the parser function, + * handling both the $GPRMC NMEA sentence: + */ + int fusedata(char c); + + + // READER functions: retrieving results, call isdataready() first + bool isdataready(); + int getHour(); + int getMinute(); + int getSecond(); + int getDay(); + int getMonth(); + int getYear(); + float getLatitude(); + float getLongitude(); + int getSatellites(); + float getAltitude(); + float getSpeed(); + float getBearing(); + }; +