Skip to content
This repository has been archived by the owner on May 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #18 from 107-systems/mark-gprmc-data-valid
Browse files Browse the repository at this point in the history
Provide validity information with GPRMC data
  • Loading branch information
aentinger authored Oct 17, 2020
2 parents 8b95826 + a714676 commit 5a5fc26
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 33 deletions.
29 changes: 24 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,33 @@ Arduino library for interfacing with any GPS module and interpreting its NMEA me
```C++
#include <ArduinoNmeaParser.h>
/* ... */
void onPositionUpdate(float const last_fix_utc_s, float const latitude, float const longitude, float const speed, float const course)
void onGprmcUpdate(nmea::RmcData const rmc)
{
char msg[64] = {0};
snprintf(msg, 64, "[%f] %f LON | %f LAT | %d m/s | %d °", last_fix_utc_s, latitude, longitude, speed, course);
Serial.println(msg);
Serial.print(rmc.time_utc.hour);
Serial.print(":");
Serial.print(rmc.time_utc.minute);
Serial.print(":");
Serial.print(rmc.time_utc.second);
Serial.print(".");
Serial.print(rmc.time_utc.microsecond);

if (rmc.is_valid)
{
Serial.print(" : LON ");
Serial.print(rmc.longitude);
Serial.print(" ° | LAT ");
Serial.print(rmc.latitude);
Serial.print(" ° | VEL ");
Serial.print(rmc.speed);
Serial.print(" m/s | HEADING ");
Serial.print(rmc.course);
Serial.print(" °");
}

Serial.println();
}
/* ... */
ArduinoNmeaParser parser(onPositionUpdate);
ArduinoNmeaParser parser(onGprmcUpdate);
/* ... */
void setup() {
Serial.begin(9600);
Expand Down
35 changes: 19 additions & 16 deletions examples/NMEA-Basic/NMEA-Basic.ino
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
* FUNCTION DECLARATION
**************************************************************************************/

void onPositionUpdate(nmea::Time const &, float const latitude, float const longitude, float const speed, float const course);
void onGprmcUpdate(nmea::RmcData const);

/**************************************************************************************
* GLOBAL VARIABLES
**************************************************************************************/

ArduinoNmeaParser parser(onPositionUpdate);
ArduinoNmeaParser parser(onGprmcUpdate);

/**************************************************************************************
* SETUP/LOOP
Expand All @@ -53,25 +53,28 @@ void loop()
* FUNCTION DEFINITION
**************************************************************************************/

void onPositionUpdate(nmea::Time const & time, float const latitude, float const longitude, float const speed, float const course)
void onGprmcUpdate(nmea::RmcData const rmc)
{
Serial.print(time.hour);
Serial.print(rmc.time_utc.hour);
Serial.print(":");
Serial.print(time.minute);
Serial.print(rmc.time_utc.minute);
Serial.print(":");
Serial.print(time.second);
Serial.print(rmc.time_utc.second);
Serial.print(".");
Serial.print(time.microsecond);
Serial.print(rmc.time_utc.microsecond);

Serial.print(" : LON ");
Serial.print(longitude);
Serial.print(" ° | LAT ");
Serial.print(latitude);
Serial.print(" ° | VEL ");
Serial.print(speed);
Serial.print(" m/s | HEADING ");
Serial.print(course);
Serial.print(" °");
if (rmc.is_valid)
{
Serial.print(" : LON ");
Serial.print(rmc.longitude);
Serial.print(" ° | LAT ");
Serial.print(rmc.latitude);
Serial.print(" ° | VEL ");
Serial.print(rmc.speed);
Serial.print(" m/s | HEADING ");
Serial.print(rmc.course);
Serial.print(" °");
}

Serial.println();
}
4 changes: 4 additions & 0 deletions extras/test/src/test_ArduinoNmeaParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ TEST_CASE("No NMEA message received", "[Parser-01]")
ArduinoNmeaParser parser(nullptr);

REQUIRE(parser.error() == ArduinoNmeaParser::Error::None);
REQUIRE(parser.rmc().is_valid == false);
REQUIRE(std::isnan(parser.rmc().latitude) == true);
REQUIRE(std::isnan(parser.rmc().longitude) == true);
REQUIRE(parser.rmc().time_utc.hour == -1);
Expand All @@ -63,6 +64,7 @@ TEST_CASE("RMC message after startup, no satellites", "[Parser-02]")
encode(parser, GPRMC);

REQUIRE(parser.error() == ArduinoNmeaParser::Error::None);
REQUIRE(parser.rmc().is_valid == false);
REQUIRE(std::isnan(parser.rmc().latitude) == true);
REQUIRE(std::isnan(parser.rmc().longitude) == true);
REQUIRE(parser.rmc().time_utc.hour == -1);
Expand All @@ -86,6 +88,7 @@ TEST_CASE("RMC message after startup, time fix available", "[Parser-03]")
encode(parser, GPRMC);

REQUIRE(parser.error() == ArduinoNmeaParser::Error::None);
REQUIRE(parser.rmc().is_valid == false);
REQUIRE(std::isnan(parser.rmc().latitude) == true);
REQUIRE(std::isnan(parser.rmc().longitude) == true);
REQUIRE(parser.rmc().time_utc.hour == 14);
Expand All @@ -108,6 +111,7 @@ TEST_CASE("Decoding starts mid-message", "[Parser-04]")

encode(parser, GPRMC);

REQUIRE(parser.rmc().is_valid == true);
REQUIRE(parser.rmc().latitude == Approx(52.514467));
REQUIRE(parser.rmc().longitude == Approx(13.349300));
REQUIRE(parser.rmc().speed == Approx(39.6122));
Expand Down
10 changes: 5 additions & 5 deletions src/ArduinoNmeaParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
* CTOR/DTOR
**************************************************************************************/

ArduinoNmeaParser::ArduinoNmeaParser(OnRMCUpdateFunc on_rmc_update)
ArduinoNmeaParser::ArduinoNmeaParser(OnGprmcUpdateFunc on_rmc_update)
: _error{Error::None}
, _parser_state{ParserState::Synching}
, _parser_buf{{0}, 0}
, _rmc{NAN, NAN, NAN, NAN, NAN, {-1, -1, -1, -1}, {-1, -1, -1}}
, _on_rmc_update{on_rmc_update}
, _rmc{false, NAN, NAN, NAN, NAN, NAN, {-1, -1, -1, -1}, {-1, -1, -1}}
, _on_gprmc_update{on_rmc_update}
{

}
Expand Down Expand Up @@ -122,7 +122,7 @@ void ArduinoNmeaParser::parseGPRMC()
if (!nmea::GPRMC::parse(_parser_buf.buf, _rmc))
_error = Error::RMC;
else {
if (_on_rmc_update)
_on_rmc_update(_rmc.time_utc, _rmc.latitude, _rmc.longitude, _rmc.speed, _rmc.course);
if (_on_gprmc_update)
_on_gprmc_update(_rmc);
}
}
6 changes: 3 additions & 3 deletions src/ArduinoNmeaParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* TYPEDEF
**************************************************************************************/

typedef std::function<void(nmea::Time const &, float const, float const, float const, float const)> OnRMCUpdateFunc;
typedef std::function<void(nmea::RmcData const)> OnGprmcUpdateFunc;

/**************************************************************************************
* CLASS DECLARATION
Expand All @@ -36,7 +36,7 @@ class ArduinoNmeaParser

public:

ArduinoNmeaParser(OnRMCUpdateFunc on_rmc_update);
ArduinoNmeaParser(OnGprmcUpdateFunc on_rmc_update);


void encode(char const c);
Expand Down Expand Up @@ -70,7 +70,7 @@ class ArduinoNmeaParser
ParserState _parser_state;
ParserBuffer _parser_buf;
nmea::RmcData _rmc;
OnRMCUpdateFunc _on_rmc_update;
OnGprmcUpdateFunc _on_gprmc_update;

bool isParseBufferFull();
void addToParserBuffer(char const c);
Expand Down
10 changes: 7 additions & 3 deletions src/nmea/GPRMC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ bool GPRMC::parse(char const * gprmc, RmcData & data)
{
case ParserState::MessadeId: next_state = handle_MessadeId (token); break;
case ParserState::UTCPositionFix: next_state = handle_UTCPositionFix (token, data.time_utc); break;
case ParserState::Status: next_state = handle_Status (token); break;
case ParserState::Status: next_state = handle_Status (token, data.is_valid); break;
case ParserState::LatitudeVal: next_state = handle_LatitudeVal (token, data.latitude); break;
case ParserState::LatitudeNS: next_state = handle_LatitudeNS (token, data.latitude); break;
case ParserState::LongitudeVal: next_state = handle_LongitudeVal (token, data.longitude); break;
Expand Down Expand Up @@ -109,13 +109,17 @@ GPRMC::ParserState GPRMC::handle_UTCPositionFix(char const * token, Time & time_
return ParserState::Status;
}

GPRMC::ParserState GPRMC::handle_Status(char const * token)
GPRMC::ParserState GPRMC::handle_Status(char const * token, bool & is_valid)
{
is_valid = false;

if (strlen(token) == 0)
return ParserState::Error;

if(!strncmp(token, "A", 1))
if(!strncmp(token, "A", 1)) {
is_valid = true;
return ParserState::LatitudeVal;
}

if(!strncmp(token, "V", 1))
return ParserState::Done;
Expand Down
2 changes: 1 addition & 1 deletion src/nmea/GPRMC.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class GPRMC

static ParserState handle_MessadeId (char const * token);
static ParserState handle_UTCPositionFix (char const * token, Time & time_utc);
static ParserState handle_Status (char const * token);
static ParserState handle_Status (char const * token, bool & is_valid);
static ParserState handle_LatitudeVal (char const * token, float & latitude);
static ParserState handle_LatitudeNS (char const * token, float & latitude);
static ParserState handle_LongitudeVal (char const * token, float & longitude);
Expand Down
1 change: 1 addition & 0 deletions src/nmea/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ typedef struct

typedef struct
{
bool is_valid;
float latitude;
float longitude;
float speed;
Expand Down

0 comments on commit 5a5fc26

Please sign in to comment.