Created
January 27, 2022 22:07
-
-
Save xaedes/70132358b2bc967d3a5e143d432dcb7a to your computer and use it in GitHub Desktop.
Encode NMEA GGA and ZDA messages using C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <sstream> | |
#include <iomanip> | |
using namespace std; | |
char computeChecksum(const std::string& str) | |
{ | |
char checksum = 0; | |
for (int i=0; i<str.size(); ++i) | |
{ | |
checksum ^= str[i]; | |
} | |
return checksum; | |
} | |
std::string zda( | |
int hour=3, | |
int minute=40, | |
float second=4.6, | |
int day=1, | |
int month=8, | |
int year=2000, | |
int local_hours=+1, // -13 .. 13 | |
int local_minutes=0 // 0..59 | |
) | |
{ | |
std::stringstream stream; | |
stream | |
<< "$--ZDA," | |
<< std::fixed | |
<< std::setbase(10) | |
<< std::setfill('0') | |
<< std::setw(2) | |
<< hour | |
<< minute | |
<< std::setw(5) | |
<< std::setprecision(2) | |
<< second | |
<< "," | |
<< std::setw(2) | |
<< day | |
<< "," | |
<< std::setw(2) | |
<< month | |
<< "," | |
<< std::setw(4) | |
<< year | |
<< "," | |
<< std::setw(2) | |
<< local_hours | |
<< "," | |
<< std::setw(2) | |
<< local_minutes | |
<< "*" | |
; | |
std::string str = stream.str(); | |
stream | |
<< std::setw(2) | |
<< std::setbase(16) | |
<< static_cast<int>(computeChecksum(str)) | |
<< "\r\n" | |
; | |
return stream.str(); | |
} | |
std::string gga( | |
int hour=3, | |
int minute=40, | |
float second=4.6, | |
float latitude=52.1, | |
float longitude=11.6, | |
int gpsQualityIndicator=1, // 0: fix_not_available, 1: gps fix, 2: dgps fix | |
int numSats=10, | |
float hdop=5, | |
float altitude=0, | |
char altitudeUnit = 'M', | |
float geoidalSeparation=0, | |
char geoidalSeparationUnit = 'M', | |
float dgpsAge=0, | |
int dgpsReferenceStationId=0 | |
) | |
{ | |
char NorS = (latitude >= 0) ? 'N' : 'S'; | |
char EorW = (longitude >= 0) ? 'E' : 'W'; | |
std::stringstream stream; | |
stream | |
<< "$--GGA," | |
<< std::fixed | |
<< std::setbase(10) | |
<< std::setfill('0') | |
<< std::setw(2) | |
<< hour | |
<< minute | |
<< std::setw(5) | |
<< std::setprecision(2) | |
<< second | |
<< "," | |
<< std::setw(7) | |
<< std::setprecision(2) | |
<< abs(latitude) | |
<< "," | |
<< NorS | |
<< "," | |
<< std::setw(7) | |
<< std::setprecision(2) | |
<< abs(longitude) | |
<< "," | |
<< EorW | |
<< "," | |
<< std::setw(1) | |
<< gpsQualityIndicator | |
<< "," | |
<< std::setw(2) | |
<< numSats | |
<< "," | |
<< std::setw(3) | |
<< std::setprecision(1) | |
<< hdop | |
<< "," | |
<< std::setw(3) | |
<< std::setprecision(1) | |
<< altitude | |
<< "," | |
<< altitudeUnit | |
<< "," | |
<< std::setw(3) | |
<< std::setprecision(1) | |
<< geoidalSeparation | |
<< "," | |
<< geoidalSeparationUnit | |
<< "," | |
<< std::setw(3) | |
<< std::setprecision(1) | |
<< dgpsAge | |
<< "," | |
<< std::setw(4) | |
<< dgpsReferenceStationId | |
<< "*" | |
; | |
std::string str = stream.str(); | |
stream | |
<< std::setw(2) | |
<< std::setbase(16) | |
<< static_cast<int>(computeChecksum(str)) | |
<< "\r\n" | |
; | |
return stream.str(); | |
} | |
int main() { | |
std::cout << gga(); | |
std::cout << zda(); | |
// $--GGA,034004.60,0052.10,N,0011.60,E,1,10,5.0,0.0,M,0.0,M,0.0,0000*5a | |
// $--ZDA,034004.60,01,08,2000,01,00*70 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment