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 #26 from 107-systems/decode-nmea-gpa
Browse files Browse the repository at this point in the history
Decode NMEA GxGGA messages
  • Loading branch information
aentinger authored Nov 23, 2020
2 parents f428605 + 2abd672 commit 359f331
Show file tree
Hide file tree
Showing 21 changed files with 1,001 additions and 72 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void onRmcUpdate(nmea::RmcData const rmc)
Serial.println();
}
/* ... */
ArduinoNmeaParser parser(onRmcUpdate);
ArduinoNmeaParser parser(onRmcUpdate, nullptr);
/* ... */
void setup() {
Serial.begin(9600);
Expand Down
43 changes: 42 additions & 1 deletion examples/NMEA-Basic/NMEA-Basic.ino
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@
**************************************************************************************/

void onRmcUpdate(nmea::RmcData const);
void onGgaUpdate(nmea::GgaData const);

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

ArduinoNmeaParser parser(onRmcUpdate);
ArduinoNmeaParser parser(onRmcUpdate, onGgaUpdate);

/**************************************************************************************
* SETUP/LOOP
Expand All @@ -55,6 +56,8 @@ void loop()

void onRmcUpdate(nmea::RmcData const rmc)
{
Serial.print("RMC ");

if (rmc.source == nmea::RmcSource::GPS) Serial.print("GPS");
else if (rmc.source == nmea::RmcSource::GLONASS) Serial.print("GLONASS");
else if (rmc.source == nmea::RmcSource::Galileo) Serial.print("Galileo");
Expand Down Expand Up @@ -84,3 +87,41 @@ void onRmcUpdate(nmea::RmcData const rmc)

Serial.println();
}

void onGgaUpdate(nmea::GgaData const gga)
{
Serial.print("GGA ");

if (gga.source == nmea::GgaSource::GPS) Serial.print("GPS");
else if (gga.source == nmea::GgaSource::GLONASS) Serial.print("GLONASS");
else if (gga.source == nmea::GgaSource::Galileo) Serial.print("Galileo");
else if (gga.source == nmea::GgaSource::GNSS) Serial.print("GNSS");

Serial.print(" ");
Serial.print(gga.time_utc.hour);
Serial.print(":");
Serial.print(gga.time_utc.minute);
Serial.print(":");
Serial.print(gga.time_utc.second);
Serial.print(".");
Serial.print(gga.time_utc.microsecond);

if (gga.fix_quality != nmea::FixQuality::Invalid)
{
Serial.print(" : LON ");
Serial.print(gga.longitude);
Serial.print(" ° | LAT ");
Serial.print(gga.latitude);
Serial.print(" ° | Num Sat. ");
Serial.print(gga.num_satellites);
Serial.print(" | HDOP = ");
Serial.print(gga.hdop);
Serial.print(" m | Altitude ");
Serial.print(gga.altitude);
Serial.print(" m | Geoidal Separation ");
Serial.print(gga.geoidal_separation);
Serial.print(" m");
}

Serial.println();
}
7 changes: 7 additions & 0 deletions extras/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,23 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(TEST_TARGET testNmeaParser)

set(TEST_SRCS
src/ArduinoNmeaParser/test_OnGgaUpdateFunc.cpp
src/ArduinoNmeaParser/test_OnRmcUpdateFunc.cpp
src/test_ArduinoNmeaParser.cpp
src/test_checksum.cpp
src/test_GxGGA.cpp
src/test_GxRMC.cpp
src/test_Types.cpp
src/test_main.cpp
src/test_gga.cpp
src/test_rmc.cpp

../../src/nmea/util/checksum.cpp
../../src/nmea/util/common.cpp
../../src/nmea/util/gga.cpp
../../src/nmea/util/rmc.cpp
../../src/nmea/util/timegm.c
../../src/nmea/GxGGA.cpp
../../src/nmea/GxRMC.cpp
../../src/nmea/Types.cpp
../../src/ArduinoNmeaParser.cpp
Expand Down
76 changes: 76 additions & 0 deletions extras/test/src/ArduinoNmeaParser/test_OnGgaUpdateFunc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* This software is distributed under the terms of the MIT License.
* Copyright (c) 2020 LXRobotics.
* Author: Alexander Entinger <[email protected]>
* Contributors: https://github.com/107-systems/107-Arduino-NMEA-Parser/graphs/contributors.
*/

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include <string.h>

#include <string>
#include <algorithm>

#include <catch.hpp>

#include <ArduinoNmeaParser.h>

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

static bool on_gga_update_called = false;

/**************************************************************************************
* FUNCTION DEFINITION
**************************************************************************************/

static void encode(ArduinoNmeaParser & parser, std::string const & nmea)
{
std::for_each(std::begin(nmea),
std::end(nmea),
[&parser](char const c)
{
parser.encode(c);
});
}

void onGgaUpdate(nmea::GgaData const data)
{
on_gga_update_called = true;

REQUIRE(data.source == nmea::GgaSource::GPS);

REQUIRE(data.time_utc.hour == 11);
REQUIRE(data.time_utc.minute == 19);
REQUIRE(data.time_utc.second == 8);
REQUIRE(data.time_utc.microsecond == 952);

REQUIRE(data.latitude == Approx(48.633433));
REQUIRE(data.longitude == Approx(13.026492));

REQUIRE(data.fix_quality == nmea::FixQuality::GPS_Fix);

REQUIRE(data.num_satellites == 5);
REQUIRE(data.hdop == Approx(2.4));
REQUIRE(data.altitude == Approx(454.7));
REQUIRE(data.geoidal_separation == Approx(46.6));

REQUIRE(data.dgps_age == Approx(0.0));
REQUIRE(strncmp(data.dgps_id, "0000", 4) == 0);
}

/**************************************************************************************
* TEST CODE
**************************************************************************************/

TEST_CASE("Testing execution of OnGgaUpdateFunc when a full GxGGA message has been received", "[OnGgaUpdateFunc-01]")
{
ArduinoNmeaParser parser(nullptr, onGgaUpdate);
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
encode(parser, GPGGA);
REQUIRE(on_gga_update_called == true);
}
77 changes: 77 additions & 0 deletions extras/test/src/ArduinoNmeaParser/test_OnRmcUpdateFunc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* This software is distributed under the terms of the MIT License.
* Copyright (c) 2020 LXRobotics.
* Author: Alexander Entinger <[email protected]>
* Contributors: https://github.com/107-systems/107-Arduino-NMEA-Parser/graphs/contributors.
*/

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include <string.h>

#include <string>
#include <algorithm>

#include <catch.hpp>

#include <ArduinoNmeaParser.h>

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

static bool on_rmc_update_called = false;

/**************************************************************************************
* FUNCTION DEFINITION
**************************************************************************************/

static void encode(ArduinoNmeaParser & parser, std::string const & nmea)
{
std::for_each(std::begin(nmea),
std::end(nmea),
[&parser](char const c)
{
parser.encode(c);
});
}

void onRmcUpdate(nmea::RmcData const data)
{
on_rmc_update_called = true;

REQUIRE(data.source == nmea::RmcSource::GPS);

REQUIRE(data.time_utc.hour == 5);
REQUIRE(data.time_utc.minute == 28);
REQUIRE(data.time_utc.second == 56);
REQUIRE(data.time_utc.microsecond == 105);

REQUIRE(data.is_valid == true);

REQUIRE(data.latitude == Approx(52.514567));
REQUIRE(data.longitude == Approx(13.350933));

REQUIRE(data.speed == Approx(44.088f));
REQUIRE(data.course == Approx(206.4f));

REQUIRE(data.date.day == 8);
REQUIRE(data.date.month == 7);
REQUIRE(data.date.year == 2020);

REQUIRE(data.magnetic_variation == Approx(0.0));
}

/**************************************************************************************
* TEST CODE
**************************************************************************************/

TEST_CASE("Testing execution of OnRmcUpdateFunc when a full GxRMC message has been received", "[OnRmcUpdateFunc-01]")
{
ArduinoNmeaParser parser(onRmcUpdate, nullptr);
std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n");
encode(parser, GPRMC);
REQUIRE(on_rmc_update_called == true);
}
14 changes: 7 additions & 7 deletions extras/test/src/test_ArduinoNmeaParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* FUNCTION DEFINITION
**************************************************************************************/

void encode(ArduinoNmeaParser & parser, std::string const & nmea)
static void encode(ArduinoNmeaParser & parser, std::string const & nmea)
{
std::for_each(std::begin(nmea),
std::end(nmea),
Expand All @@ -37,7 +37,7 @@ void encode(ArduinoNmeaParser & parser, std::string const & nmea)

TEST_CASE("No NMEA message received", "[Parser-01]")
{
ArduinoNmeaParser parser(nullptr);
ArduinoNmeaParser parser(nullptr, nullptr);

REQUIRE(parser.error() == ArduinoNmeaParser::Error::None);
REQUIRE(parser.rmc().is_valid == false);
Expand All @@ -58,7 +58,7 @@ TEST_CASE("No NMEA message received", "[Parser-01]")

TEST_CASE("RMC message after startup, no satellites", "[Parser-02]")
{
ArduinoNmeaParser parser(nullptr);
ArduinoNmeaParser parser(nullptr, nullptr);

std::string const GPRMC = ("$GPRMC,,V,,,,,,,,,,N*53\r\n");

Expand All @@ -83,7 +83,7 @@ TEST_CASE("RMC message after startup, no satellites", "[Parser-02]")

TEST_CASE("RMC message after startup, time fix available", "[Parser-03]")
{
ArduinoNmeaParser parser(nullptr);
ArduinoNmeaParser parser(nullptr, nullptr);

std::string const GPRMC = ("$GPRMC,141928.00,V,,,,,,,,,,N*7A\r\n");

Expand All @@ -108,7 +108,7 @@ TEST_CASE("RMC message after startup, time fix available", "[Parser-03]")

TEST_CASE("Decoding starts mid-message", "[Parser-04]")
{
ArduinoNmeaParser parser(nullptr);
ArduinoNmeaParser parser(nullptr, nullptr);

std::string const GPRMC = "077.0,023.5,080720,000.0,W*79\r\n$GPRMC,052852.105,A,5230.868,N,01320.958,E,077.0,023.5,080720,000.0,W*79\r\n";

Expand All @@ -128,7 +128,7 @@ TEST_CASE("Decoding starts mid-message", "[Parser-04]")

TEST_CASE("NMEA message with data corruption (checksum mismatch) received", "[Parser-05]")
{
ArduinoNmeaParser parser(nullptr);
ArduinoNmeaParser parser(nullptr, nullptr);

std::string const GPRMC = "$GPXXX,052852.105,A,5230.868,N,01320.958,E,077.0,023.5,080720,000.0,W*79\r\n";

Expand All @@ -139,7 +139,7 @@ TEST_CASE("NMEA message with data corruption (checksum mismatch) received", "[Pa

TEST_CASE("Multiple NMEA messages received", "[Parser-06]")
{
ArduinoNmeaParser parser(nullptr);
ArduinoNmeaParser parser(nullptr, nullptr);

std::vector<std::string> const GPRMC =
{
Expand Down
Loading

0 comments on commit 359f331

Please sign in to comment.