Last active
July 24, 2024 19:16
-
-
Save clavisound/45e29942a08ca6ce0c1086e3ebdbbce1 to your computer and use it in GitHub Desktop.
Reading HDOP from NMEA GGA sentence via callback
This file contains 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
/*! | |
* 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