Not able to obtain altitude value from Neo-6M GPS Module using arduino

Hi, I could not obtain the altitude from the Neo-6M.

The other value, such as date, time, latitude, and longitude, is fine.

I have tested in the open area, and no high building might block the connection.

The code I'm using is taken from other tutorials & modified based on johnwasser's advice for testing purposes.

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

const int RXPin = 3, TXPin = 4;
const uint32_t GPSBaud = 9600; //Default baud of NEO-6M is 9600


TinyGPSPlus gps; // the TinyGPS++ object
SoftwareSerial gpsSerial(RXPin, TXPin); // the serial interface to the GPS device

void setup() {
  Serial.begin(9600);
  gpsSerial.begin(GPSBaud);

  Serial.println(F("Arduino - GPS module"));
}

void loop() {
  if (gpsSerial.available() > 0) {
    char gpsChar = gpsSerial.read();
    Serial.write(gpsChar);
    if (gps.encode(gpsChar)) {
      if (gps.location.isValid()) {
        Serial.print(F("- latitude: "));
        Serial.println(gps.location.lat());

        Serial.print(F("- longitude: "));
        Serial.println(gps.location.lng());

        Serial.print(F("- altitude: "));
        if (gps.altitude.isValid())
          Serial.println(gps.altitude.meters());
        else
          Serial.println(F("INVALID"));
      } else {
        Serial.println(F("- location: INVALID"));
      }

      Serial.print(F("- speed: "));
      if (gps.speed.isValid()) {
        Serial.print(gps.speed.kmph());
        Serial.println(F(" km/h"));
      } else {
        Serial.println(F("INVALID"));
      }

      Serial.print(F("- GPS date&time: "));
      if (gps.date.isValid() && gps.time.isValid()) {
        Serial.print(gps.date.year());
        Serial.print(F("-"));
        Serial.print(gps.date.month());
        Serial.print(F("-"));
        Serial.print(gps.date.day());
        Serial.print(F(" "));
        Serial.print(gps.time.hour());
        Serial.print(F(":"));
        Serial.print(gps.time.minute());
        Serial.print(F(":"));
        Serial.println(gps.time.second());
      } else {
        Serial.println(F("INVALID"));
      }

      Serial.println();
    }
  }

  if (millis() > 5000 && gps.charsProcessed() < 10)
    Serial.println(F("No GPS data received: check wiring"));
}

Below is the log:
23-09-113631-GPS.log (150.1 KB)
22-09-115748-GPS.log (112.1 KB)

I might have a late reply as staying in a different time zone (UTC+08:00).
Let me know if more information is required to solve this issue, thanks :slight_smile: .

Is Serial Monitor showing this?

- altitude: INVALID

Try changing this part:

void loop() {
  if (gpsSerial.available() > 0) {
    if (gps.encode(gpsSerial.read())) {
      if (gps.location.isValid()) {

to this, so you can show us what data is received from the GPS:

void loop() {
  if (gpsSerial.available() > 0) {
    char gpsChar = gpsSerial.read();
    Serial.write(gpsChar);
    if (gps.encode(gpsChar)) {
      if (gps.location.isValid()) {

The NMEA sentence you need for altitude is GGA. Use the patch mentioned above to examine the GPS raw output.

If GGA does not appear, you may have a counterfeit Neo-6M, or transmission of that sentence has been turned off. If the latter, than can be reset using the U-center software from Ublox.

Please post the code here, using code tags.
Using a good library and example code height works fine. Example is available....
No problem here.
Know that height is varying a lot. +/- 5-10 meters is to be expected.

Yes, based on your advice I have changed the code and the log is posted in my first post...
Thanks~

Hi, I have posted the log in the first post. Thanks~

I have updated in the post.

Altitude reading appears in your GCA sentence as 22.5m - is that about right?

The data from the GPS looks quite normal. I don't immediately see why it never reports:

  • latitude:
  • longitude:
  • altitude:
  • speed:
    or
  • GPS date&time:

It's like the GPS library doesn't recognize any of the messages but you said that latitude, longitude, and speed were working before.

Ops, my bad :sweat_smile:

I forget to change part of the code.

I have updated the code and the log in the post, thanks. :smile:

Hi, I don't find any GCA sentence in my previous log.

GGA, you mean?

Ooo, you are right. :open_mouth:

I have noticed that it has already shown the altitude in GGA sentences in my current/ previous log...

I have tried to decode one of the GGA sentences using GPRMC & GPGGA: Online Decoder for GPS NMEA messages (rl.se):

$GPGGA,040114.00,0214.93399,N,10216.58887,E,1,09,0.85,19.7,M,-2.0,M,,*78

And the result:
image

But the altitude still displays as INVALID, so is it similar to the problem stated by johnwasser?

Yup, misread it :grimacing:

You display message when gps.encode(gpsChar) returns 'true'. It looks like that only happens for:
$GPGLL
$GPRMC
$GPVTG
The library is not processing $GPGGA messages so it never sees an altitude. It looks like it should. Maybe the checksum is failing?

Your sentences as showing in the monitor are badly chopped up -- missing data everywhere.

In that case, you could refer:

That log appears to be perfect. What code did you use to produce it?

BTW, it is confusing if you significantly edit early posts. If you want to provide new information it is better to add it in new posts. That way we can see how you are progresssing.

Thanks.

Ooo, okay. I will try to do so. :smile:

The code I am using:

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

const int RXPin = 3, TXPin = 4;
const uint32_t GPSBaud = 9600; //Default baud of NEO-6M is 9600


TinyGPSPlus gps; // the TinyGPS++ object
SoftwareSerial gpsSerial(RXPin, TXPin); // the serial interface to the GPS device

void setup() {
  Serial.begin(9600);
  gpsSerial.begin(GPSBaud);

  Serial.println(F("Arduino - GPS module"));
}

void loop() {
  if (gpsSerial.available() > 0) {
    char gpsChar = gpsSerial.read();
    Serial.write(gpsChar);
    Serial.println();
  }

  if (millis() > 5000 && gps.charsProcessed() < 10)
    Serial.println(F("No GPS data received: check wiring"));
}

Good job.
This establishes that your GPS module is working, your connections are fine and you have great satellite reception.

I'm wondering why you are not getting a new line after each character since you have a print line statement after writing each character:

Serial.write(gpsChar);
Serial.println();

I think the sentences contain their own new line & carriage return. (edit)

Get rid of the test at the end. It's not doing anything useful for you:
if (millis() > 5000 && gps.charsProcessed() < 10)

I think your best hope is to modify the TinyGPS++ library to report checksum failures.

In libraries/TinyGPSPlus/src/TinyGPS++.cpp, change:

    else
    {
      ++failedChecksumCount;
    }

to

    else
    {
      ++failedChecksumCount;

      Serial.println();
      Serial.print("Checksum failed! Expected ");
      Serial.print(parity, HEX);
      Serial.print(" but received ");
      Serial.println(checksum, HEX);
    }

Okay, I will try this approach first. Thanks :smile: