Skip to content

Commit

Permalink
First commit @20221006
Browse files Browse the repository at this point in the history
  • Loading branch information
liuchuanstudy committed Oct 6, 2022
1 parent cd0eb5c commit 96737a7
Show file tree
Hide file tree
Showing 7 changed files with 398 additions and 0 deletions.
21 changes: 21 additions & 0 deletions Example/TestUblox/TestUblox.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <GNSS.h>

GNSS gnss;

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println(" ");

gnss.init(Serial1, 9600);
}

void loop() {
// put your main code here, to run repeatedly:
gnss.serialRead();
printf("%s,%s,%.7f,%.7f,%.2f,%.2f\n",
gnss.UTCDate.c_str(),
gnss.UTCTime.c_str(),
gnss.lat, gnss.lon, gnss.velocity, gnss.course);
delay(200);
}
20 changes: 20 additions & 0 deletions Example/TestWithoutReceiver/TestWithoutReceiver.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <GNSS.h>

GNSS gnss;

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println(" ");

String str0 = "$GNRMC,083712.40,A,3030.83159,N,11424.56558,E,";
String str1 = "0.150,,291221,,,A*65\r\n$GNRMC,083712.80,A,3030.83158,N,11424.56558,E,0.033,,291221,,,A*6C\r\n";

gnss.parseNAME(str0);
gnss.parseNAME(str1);
Serial.printf("%s,%s,%.7f,%.7f,%.3f",gnss.UTCTime.c_str(),gnss.UTCDate.c_str(),gnss.lat,gnss.lon,gnss.velocity);
}

void loop() {
// put your main code here, to run repeatedly:
}
264 changes: 264 additions & 0 deletions GNSS.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
#include "GNSS.h"

//#define GNSSDEBUG

unsigned char hexToDec(unsigned char hex)
{
if (hex >= 'A')
return (hex - 'A') + 10;
else
return hex - '0';
}

GNSS::GNSS()
{
status = false;
}

GNSS::~GNSS()
{
_serial->end();
}

void GNSS::init(HardwareSerial& serial, int baud)
{
_serial = &serial;
_serial->begin(baud);
}

void GNSS::serialRead()
{
int len = _serial->available();
if(len>0)
{
String recvStr = _serial->readString();
parseNAME(recvStr);
}
}

void GNSS::parseNAME(String parseStr)
{
int parseLength = 1;
int len = static_cast<int>(parseStr.length());

while (len > parseLength)
{
String str = parseStr.substring(parseLength - 1);
#ifdef GNSSDEBUG
Serial.println(str);
#endif
if (parse(str, parseLength))
{
if (checkCRC())
{
int nPos = payload.indexOf(',');
if(nPos != -1)
{
String nmeaHeader = payload.substring(0,nPos);
#ifdef GNSSDEBUG
Serial.print("Get");
Serial.println(nmeaHeader);
#endif
if(nmeaHeader == "$GNRMC")
parseRMC();
else if(nmeaHeader == "$GNGGA")
parseGGA();
}
}
}
}
}

bool GNSS::parse(String str, int &parseLen)
{
#ifdef GNSSDEBUG
Serial.println("parsing...");
#endif
static bool get_header = false;
if (get_header)
{
int pos_footer = str.indexOf(footer);
if (pos_footer != -1)
{
#ifdef GNSSDEBUG
Serial.println("gotFooter");
#endif
payload += str.substring(0, pos_footer);
get_header = false;
parseLen += pos_footer + 2;
return true;
}
else
{
payload += str;
if (payload.length() >= 100)
{
payload = "";
get_header = false;
}
parseLen += str.length();
return false;
}
}
else
{
int pos_header = str.indexOf(header);
if (pos_header != -1)
{
#ifdef GNSSDEBUG
Serial.println("gotHeader");
#endif
payload = "";
get_header = true;
int pos_footer = str.indexOf(footer, pos_header);
if (pos_footer != -1)
{
#ifdef GNSSDEBUG
Serial.println("gotFooter");
#endif
payload = str.substring(pos_header, pos_footer);
get_header = false;
parseLen += pos_footer-pos_header + 2;
return true;
}
else
{
payload += str.substring(pos_header);
parseLen += str.length();
return false;
}
}
else
{
parseLen += str.length();
return false;
}
}
}

bool GNSS::checkCRC()
{
int pos = payload.indexOf('*');

if(pos != -1)
{
unsigned char checkSum = 0;
unsigned char CRC = (hexToDec(payload[pos + 1]) << 4) + hexToDec(payload[pos + 2]);
for (int i = 1; i < pos; i++)
{
checkSum ^= payload[i];
}
if (checkSum == CRC)
return true;
else
return false;
}
else
return false;
}

void GNSS::parseRMC()
{
/**UTC**/
int headPos = payload.indexOf(',');
int footPos = payload.indexOf(',',headPos+1);
if(footPos == -1) return;
UTCTime = payload.substring(headPos+1,footPos);

/**Status**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
String subStr = payload.substring(headPos+1,footPos);
if(subStr == "A") status == true;

/**Lat**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
subStr = payload.substring(headPos+1,footPos);
int pos = subStr.indexOf('.');
if(pos == -1) return;
lat = subStr.substring(0,pos - 2).toDouble() + subStr.substring(pos - 2).toDouble()/60;

/**Northing Indicator**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);

/**Lon**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
subStr = payload.substring(headPos+1,footPos);
pos = subStr.indexOf('.');
if(pos == -1) return;
lon = subStr.substring(0,pos - 2).toDouble() + subStr.substring(pos - 2).toDouble()/60;

/**Easting Indicator**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);

/**SOG**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
velocity = payload.substring(headPos+1,footPos).toFloat();

/**COG**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
course = payload.substring(headPos+1,footPos).toFloat();

/**Date**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
UTCDate = payload.substring(headPos+1,footPos);
}

void GNSS::parseGGA()
{
/**UTC**/
int headPos = payload.indexOf(',');
int footPos = payload.indexOf(',',headPos+1);
if(footPos == -1) return;
UTCTime = payload.substring(headPos+1,footPos);

/**Lat**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
String subStr = payload.substring(headPos+1,footPos);
int pos = subStr.indexOf('.');
if(pos == -1) return;
lat = subStr.substring(0,pos - 2).toDouble() + subStr.substring(pos - 2).toDouble()/60;

/**Northing Indicator**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);

/**Lon**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
subStr = payload.substring(headPos+1,footPos);
pos = subStr.indexOf('.');
if(pos == -1) return;
lon = subStr.substring(0,pos - 2).toDouble() + subStr.substring(pos - 2).toDouble()/60;

/**Easting Indicator**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);

/**Status**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);

/**SVs Used**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
SVs = static_cast<uint8_t>(payload.substring(headPos+1,footPos).toInt());

/**HDOP**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
HDOP = payload.substring(headPos+1,footPos).toFloat();

/**Alt**/
headPos = footPos;
footPos = payload.indexOf(',',headPos+1);
altitude = payload.substring(headPos+1,footPos).toFloat();
}
40 changes: 40 additions & 0 deletions GNSS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef __GNSS_H_
#define __GNSS_H_

#include "Arduino.h"

class GNSS
{
public:
GNSS();
~GNSS();
void init(HardwareSerial& serial, int baud);
void serialRead();

bool status; //true-valid;false-invalid
String UTCTime;
String UTCDate;
double lat, lon;
float velocity; //knot
float course; //deg 0-360
float altitude; //m
uint8_t SVs;
float HDOP;

void parseNAME(String);

private:
const String header = "$GN";
const String footer = "\r\n";
String payload;

HardwareSerial* _serial;

bool parse(String str, int &parseLen);

bool checkCRC();
void parseRMC();
void parseGGA();
};

#endif
20 changes: 20 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#######################################
# Syntax Coloring Map GNSS
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

GNSS KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################
init KEYWORD2
serialRead KEYWORD2
parseNAME KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
23 changes: 23 additions & 0 deletions library.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "EasyGNSS",
"keywords": "gnss,gps,NMEA,ublox",
"description": "An easy-to-use library to parse the NMEA protocol output by the GNSS receiver (Ublox) through serial port.",
"authors":
[
{
"name": "Chuan Liu",
"email": "liuchuanstudy@outlook.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/chuanstudyup/EasyGNSS.git"
},
"version": "1.0.0",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",
"headers": "GNSS.h"
}
Loading

0 comments on commit 96737a7

Please sign in to comment.