Skip to content

Instantly share code, notes, and snippets.

@clavisound
Last active July 24, 2024 19:16
Show Gist options
  • Save clavisound/45e29942a08ca6ce0c1086e3ebdbbce1 to your computer and use it in GitHub Desktop.
Save clavisound/45e29942a08ca6ce0c1086e3ebdbbce1 to your computer and use it in GitHub Desktop.
Reading HDOP from NMEA GGA sentence via callback
/*!
* based on getAllGNSS.ino
* Added some code to read HDOP value.
* Clavisound jul 24
* @brief read all gnss data
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author ZhixinLiu([email protected])
* @version V1.0
* @date 2023-03-07
*
* DEFAULT data:
$GNGGA,101747.000,,,,,0,00,25.5,,,,,,*7E
$GNGLL,,,,,101747.000,V,N*60
$GNGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5,1*01
$GNGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5,4*04
$GNGSA,A,1,,,,,,,,,,,,,25.5,25.5,25.5,2*02
$GPGSV,1,1,01,08,,,24,0*6A
$BDGSV,1,1,00,0*74
$GLGSV,1,1,00,0*79
$GNRMC,101747.000,V,,,,,,,170724,,,N,V*2A
$GNVTG,,,,,,,,,N*2E
$GNZDA,101747.000,17,07,2024,00,00*49
$GPTXT,01,01,01,ANTENNA OK*35
*
*
* @url https://github.com/dfrobot/DFRobot_GNSS
*/
#include "DFRobot_GNSS.h"
//#include <NeoGPS_cfg.h>
//#include <NMEAGPS.h>
#define DEBUGINO 1
//NMEAGPS gps;
//gps_fix fix;
char nmeaBuffer[77]; // according to Google AI NMEA version 2.3 77 it's a safe choice
uint8_t nmeaIndex, nmeaStart, counterComma, indexHdop;
//char nmeaSentence[] = "GNGSA"; // comma in 17?
char nmeaSentence[6] = "GNGGA"; // comma in 8
uint16_t hdopNeoGPS; // multiply with 1000
char hdopTemp[] = "24.4";
#define NMEA_START 1
#define NMEA_NULL 0
// len is 32 most of the time because of arduino wire / i2c.
void hdop(char *data ,uint8_t len)
{
for(uint8_t i = 0; i < len; i++){
if ( data[i] == '$' && nmeaStart == NMEA_NULL ) {
nmeaIndex = 0;
nmeaBuffer[nmeaIndex] = '$';
nmeaStart = NMEA_START;
}
// store characters one-by-one
if ( nmeaStart == NMEA_START && data[i] != '$' && data[i] != '\r' ) {
nmeaBuffer[nmeaIndex] = data[i];
}
// reset counter. We found end
// TODO verify checksum
if ( data [i] == '\r' ) { // dec: 10 line feed.
nmeaBuffer[nmeaIndex] = data[i];
printMessage();
}
nmeaIndex++;
}
}
void printMessage(){
// In GSA is HDOP, VDOP, checksum.
// in GGA HDOP is after 8th comma
for ( uint8_t i = 1; i < 5; i++ ) {
// Continue if we have match with nmeaSentence
// we don't match; return.
if ( nmeaBuffer[i] != nmeaSentence[i-1] ) { // i-1 because I don't store '$' in nmeaSentence
// restart counters and abort.
nmeaStart = NMEA_NULL;
nmeaIndex = 0;
return;
}
}
#if DEBUGINO == 1
Serial.print("\n");
#endif
// we have match. print
counterComma = 0;
indexHdop = 0;
#if DEBUGINO == 1
Serial.print("\nnmeaIndex:\t\t");Serial.println(nmeaIndex);
#endif
for ( uint8_t i = 0; i < nmeaIndex; i++ ) {
// print message
#if DEBUGINO == 1
Serial.print(nmeaBuffer[i]);
#endif
// grab HDOP
if ( (char)nmeaBuffer[i] == ',' ) {
counterComma++;
}
if ( counterComma == 8 ) {
// when hdop is 25.5 we have five matches, including first ','
if ( atoi(nmeaBuffer[i]) >= 0 || atoi(nmeaBuffer[i]) <= 9 || nmeaBuffer[i] == '.' ) {
hdopTemp[indexHdop] = nmeaBuffer[i+1]; // Don't add the comma, store next character.
indexHdop++;
}
}
/*
// proccess via NeoGPS // FAILED
if ( gps.decode(nmeaBuffer[i]) == NMEAGPS::DECODE_COMPLETED ) {
if ( fix.valid.hdop ) {
#if DEBUGINO == 1
Serial.print("\n*NeoGPS hdop: ");
Serial.print(fix.hdop);
#endif
}
if ( fix.valid.time ) {
#if DEBUGINO == 1
Serial.print("\n*NeoGPS minutes: ");
Serial.print(fix.dateTime.minutes);
#endif
}
if ( fix.valid.date ) {
#if DEBUGINO == 1
Serial.print("\n*NeoGPS date: ");
Serial.print(fix.dateTime.year);
#endif
}
}*/
}
// Delete garbage from i+1 above.
hdopTemp[indexHdop-1] = '\0';
hdopNeoGPS = atof(hdopTemp) * 1000;
#if DEBUGINO == 1
Serial.print("\nHDOP NeoStyle: ");Serial.print(hdopNeoGPS);
Serial.print("\nhdopTemp: ");Serial.print(hdopTemp);
#endif
// restart counters.
nmeaStart = NMEA_NULL;
nmeaIndex = 0;
}
void callback(char *data ,uint8_t len)
{
#if DEBUGINO == 1
Serial.print("\nRaw callback len: ");Serial.println(len);
#endif
for(uint8_t i = 0; i < len; i++){
/*
if ( data [i] == '\r' ) {
#if DEBUGINO == 1
Serial.print("line feed");
#endif
}*/
#if DEBUGINO == 1
Serial.print(data[i]);
#endif
}
/*
#if DEBUGINO == 1
Serial.print("\nInt callback: \n");
#endif
for(uint8_t i = 0; i < len; i++){
#if DEBUGINO == 1
Serial.print(" ");Serial.print((uint8_t)data[i]);
#endif
}
*/
}
#define I2C_COMMUNICATION //use I2C for communication, but use the serial port for communication if the line of codes were masked
#ifdef I2C_COMMUNICATION
DFRobot_GNSS_I2C gnss(&Wire ,GNSS_DEVICE_ADDR);
#else
/* ---------------------------------------------------------------------------------------------------------------------
* board | MCU | Leonardo/Mega2560/M0 | UNO | ESP8266 | ESP32 | microbit | m0 |
* VCC | 3.3V/5V | VCC | VCC | VCC | VCC | X | vcc |
* GND | GND | GND | GND | GND | GND | X | gnd |
* RX | TX | Serial1 TX1 | 5 | 5/D6 | D2 | X | tx1 |
* TX | RX | Serial1 RX1 | 4 | 4/D7 | D3 | X | rx1 |
* ----------------------------------------------------------------------------------------------------------------------*/
/* Baud rate cannot be changed */
#if defined(ARDUINO_AVR_UNO) || defined(ESP8266)
SoftwareSerial mySerial(4, 5);
DFRobot_GNSS_UART gnss(&mySerial ,9600);
#elif defined(ESP32)
DFRobot_GNSS_UART gnss(&Serial1 ,9600 ,/*rx*/D2 ,/*tx*/D3);
#else
DFRobot_GNSS_UART gnss(&Serial1 ,9600);
#endif
#endif
void setup()
{
Serial.begin(9600);
while(!gnss.begin()){
Serial.println("NO Deivces !");
delay(1000);
}
gnss.enablePower(); // Enable gnss power
/** Set GNSS to be used
* eGPS use gps
* eBeiDou use beidou
* eGPS_BeiDou use gps + beidou
* eGLONASS use glonass
* eGPS_GLONASS use gps + glonass
* eBeiDou_GLONASS use beidou +glonass
* eGPS_BeiDou_GLONASS use gps + beidou + glonass
*/
gnss.setGnss(eGPS_BeiDou_GLONASS);
}
void loop()
{
//gnss.setCallback(callback);
//gnss.getAllGnss();
//strcpy(nmeaSentence, "GNGGA");
gnss.setCallback(hdop);
gnss.getAllGnss();
/*strcpy(nmeaSentence, "GNRMC");
gnss.setCallback(hdop);
gnss.getAllGnss();
*/
#if DEBUGINO == 1
Serial.print("\nsats: ");Serial.print(gnss.getNumSatUsed());
#endif
delay(3000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment