Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem parsing HDOP, satellites number and altitude #140

Open
AleksJakovlev opened this issue Jul 22, 2024 · 12 comments
Open

Problem parsing HDOP, satellites number and altitude #140

AleksJakovlev opened this issue Jul 22, 2024 · 12 comments

Comments

@AleksJakovlev
Copy link

AleksJakovlev commented Jul 22, 2024

Hi,

I've got a problem with the library. For some reason, I get back too high HDOP (Horizontal Dilution of Precision), satellites number and altitude.

The input is: $GPGGA,110641.00,5126.37428,N,00003.02175,E,1,07,1.02,58.8,M,45.4,M,,*63
where:
07 – number of satellites being tracked
1.02 - Horizontal dilution of position
58.8,M - Altitude, in meters above the sea level
45.4,M - Height of geoid (mean sea level) above WGS84 ellipsoid

Outputs on Arduino serial are:
11:06:42 UTC 22/07/2024
Latitude = 51.439590N Longitude = 0.050383E
COG = 0.0
SOG = 1.86
MPH = 2.14
KMPH = 3.44
Altitude in meters = 0.00
Altitude in feet = 0.00
Number of satellites in use = 7
HDOP = 354

Any thoughts?

@TD-er
Copy link
Contributor

TD-er commented Jul 22, 2024

Which (example) code do you use?

@AleksJakovlev
Copy link
Author

AleksJakovlev commented Jul 22, 2024

This is a bare minimum code:

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);
LiquidCrystal_I2C lcd(0x27, 20, 4);

void setup() {
  Serial.begin(9600);
  ss.begin(GPSBaud);
  lcd.init();
  lcd.backlight();
  lcd.clear();
}

void loop() {
  while (ss.available() > 0) {
    gps.encode(ss.read());
    if (gps.location.isUpdated()) {

      Serial.print("HDOP: ");
      Serial.println(gps.hdop.value());
      Serial.print("Satellites: ");
      Serial.println(gps.satellites.value());
      Serial.print("Altitude: ");
      Serial.println(gps.altitude.meters());

      lcd.setCursor(0, 0);
      lcd.print("HDOP: ");
      lcd.print(gps.hdop.value());
      lcd.setCursor(0, 1);
      lcd.print("Satellites: ");
      lcd.print(gps.satellites.value());
      lcd.setCursor(0, 2);
      lcd.print("Altitude: ");
      lcd.print(gps.altitude.meters());
    }
  }
}

And a few images with setup and output from the serial port:
GP__5386
GP__5389
GP__5395

@TD-er
Copy link
Contributor

TD-er commented Jul 22, 2024

You need to divide the HDOP by 100.0f
I also use altitude.meters(), but this does return a double
So you might want to try altitude.value()/100.0f so you get the value as a float.

@mikalhart
Copy link
Owner

The HDOP class has a member hdop() that does the division for you, if that helps. Try

    lcd.print(gps.hdop.hdop());

@AleksJakovlev
Copy link
Author

AleksJakovlev commented Jul 23, 2024

@TD-er Thanks. I will try altitude.value()/100.0f
There are two altitude values as an output from the GPS module - 58.2m and 45.4m. Which one comes from gps.altitude.meters()
Below there is an example for data parsing, also screenshot attached from my terminal.
In my case it should be: satellites number - 6, HDOP - 1.90 and altitudes are 58.2m and 45.4m.

$GPGGA,110617.00,41XX.XXXXX,N,00831.54761,W,1,05,2.68,129.0,M,50.1,M,,*42

110617 – represents the time at which the fix location was taken, 11:06:17 UTC
41XX.XXXXX,N – latitude 41 deg XX.XXXXX’ N
00831.54761,W – Longitude 008 deg 31.54761′ W
1 – fix quality (0 = invalid; 1= GPS fix; 2 = DGPS fix; 3 = PPS fix; 4 = Real Time Kinematic; 5 = Float RTK; 6 = estimated (dead reckoning); 7 = Manual input mode; 8 = Simulation mode)
05 – number of satellites being tracked
2.68 – Horizontal dilution of position
129.0, M – Altitude, in meters above the sea level
50.1, M – Height of geoid (mean sea level) above WGS84 ellipsoid
empty field – time in seconds since last DGPS update
empty field – DGPS station ID number
*42 – the checksum data, always begins with *

@mikalhart Thanks, I will try today and let you know if it works.

Screenshot 2024-07-23 085927

@TD-er
Copy link
Contributor

TD-er commented Jul 23, 2024

50.1, M – Height of geoid (mean sea level) above WGS84 ellipsoid

Just the first hit on DuckDuckGo when searching for "GGA nmea message": https://receiverhelp.trimble.com/alloy-gnss/en-us/NMEA-0183messages_GGA.html

Fields 11 & 12:

11 | Geoid separation
12 | M: geoid separation measured in meters

Since I had no idea what this is, I searched for it and found this: https://gis.stackexchange.com/a/174116
And to be honest, I still don't think I fully understand what use it has.
Maybe it can be used to improve altitude calculations by applying some other model of the curvature of the earth???

@AleksJakovlev
Copy link
Author

You need to divide the HDOP by 100.0f I also use altitude.meters(), but this does return a double So you might want to try altitude.value()/100.0f so you get the value as a float.

Unfortunately, it doesn't help.

@AleksJakovlev
Copy link
Author

The HDOP class has a member hdop() that does the division for you, if that helps. Try

    lcd.print(gps.hdop.hdop());

Also, this doesn't work as well

@AleksJakovlev
Copy link
Author

AleksJakovlev commented Jul 24, 2024

An updated code is:

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);
LiquidCrystal_I2C lcd(0x27, 20, 4);

void setup() {
  Serial.begin(9600);
  ss.begin(GPSBaud);
  lcd.init();
  lcd.backlight();
  lcd.clear();
}

void loop() {
  while (ss.available() > 0) {
    gps.encode(ss.read());
    if (gps.location.isUpdated()) {
      Serial.print("HDOP: ");
      // Serial.println(gps.hdop.value());
      Serial.println(gps.hdop.hdop());      //HDOP has a member hdop() - updated 23/07/2024
      Serial.print("Satellites: ");
      Serial.println(gps.satellites.value());
      Serial.print("Altitude: ");
      // Serial.println(gps.altitude.meters());
      Serial.println(gps.altitude.value() / 100.0f);      //updated 23/07/2024

      lcd.setCursor(0, 0);
      lcd.print("HDOP: ");
      // lcd.print(gps.hdop.value());
      lcd.print(gps.hdop.hdop());         //HDOP has a member hdop() - updated 23/07/2024
      lcd.setCursor(0, 1);
      lcd.print("Satellites: ");
      lcd.print(gps.satellites.value());
      lcd.setCursor(0, 2);
      lcd.print("Altitude: ");
      // lcd.print(gps.altitude.meters());
      lcd.print(gps.altitude.value() / 100.0f);     //updated 23/07/2024
    }
  }
}

Input from GPS module:
$GPRMC,054347.00,A,5126.37255,N,00003.01659,E,0.230,,240724,,,A79
$GPVTG,,T,,M,0.230,N,0.426,K,A
22
$GPGGA,054347.00,5126.37255,N,00003.01659,E,1,06,1.96,68.3,M,45.4,M,,63
$GPGSA,A,3,31,23,05,18,26,16,,,,,,,3.02,1.96,2.29
08
$GPGSV,3,1,12,01,50,155,,05,05,023,15,07,11,329,,08,17,274,78
$GPGSV,3,2,12,10,13,154,18,16,75,262,20,18,52,062,31,23,32,124,20
7D
$GPGSV,3,3,12,26,54,169,31,27,50,277,23,29,04,085,,31,11,202,1273
$GPGLL,5126.37255,N,00003.01659,E,054347.00,A,A
66

Output from Arduino:
HDOP: 0.00
Satellites: 0
Altitude: 0.00

@TD-er
Copy link
Contributor

TD-er commented Jul 24, 2024

Can you wrap your code in 3 backticks (each on a separate line) so it is better readable?
And if you really want to do it fancy, add c++ right after the first 3 backticks :)

@svdrummer
Copy link

svdrummer commented Jul 24, 2024

I have been using this library on my test instruments for years.
I may have missed why you are having issues.
Try
lcd.print(" HDOP " + String(gps.hdop.value()));
This will print out the GPS side (I know this works)
Do the division later, once you know the initial value is working

number of sats
lcd.print("Sat # " + String(gps.satellites.value()));

Like NASA and startrek, altitude is in metres.

What is the GPS model
what settings do you have for the GPS. IE, sea, Air, pedestrian, mobile.... GPS unit have configuration setting that affects the NMEA output. IE, I use the Sea setting, pedestrian or air, depending what testing i am performing.

Great idea for the terminal. I will have to try that

@AleksJakovlev
Copy link
Author

AleksJakovlev commented Jul 25, 2024

I have been using this library on my test instruments for years. I may have missed why you are having issues. Try lcd.print(" HDOP " + String(gps.hdop.value())); This will print out the GPS side (I know this works) Do the division later, once you know the initial value is working

number of sats lcd.print("Sat # " + String(gps.satellites.value()));

Like NASA and startrek, altitude is in metres.

What is the GPS model what settings do you have for the GPS. IE, sea, Air, pedestrian, mobile.... GPS unit have configuration setting that affects the NMEA output. IE, I use the Sea setting, pedestrian or air, depending what testing i am performing.

Great idea for the terminal. I will have to try that

I tried using the setup yesterday, but it doesn't seem to be working as expected. It appears that the data from the Arduino doesn't match the raw data from the GPS module for HDOP, the number of satellites, and altitude.
It looks like there is a bug in the TinyGPS++ library.
The GPS module I'm using is the GY-NEO6MV2.
1721905123201
1721905123223

@AleksJakovlev AleksJakovlev changed the title problem parsing HDOP, satellites number and altitude Problem parsing HDOP, satellites number and altitude Jul 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants