SlashDevin / NeoGPS

NMEA and ublox GPS parser for Arduino, configurable to use as few as 10 bytes of RAM
GNU General Public License v3.0
714 stars 196 forks source link

Time returning as 00:00:00.000, fix.valid.time is never true. Adafruit GPS and TinyGPS++ working correctly with same hardware. #83

Closed hiltswaltts closed 6 years ago

hiltswaltts commented 6 years ago

This is with a Garmin 18x LVC connected to an Arduino MEGA through hardware serial, using a MAX3232 RS232 to TTL converter. The Garmin's firmware has been updated to the latest version (4.00). I've tired setting the GPS baud rate to both 9600 and 38400 with no effect.

The Garmin is sending the following sentences in this order, as reported by NMEAOrder.INO :

RMC GGA GSA GSV GSV GSV GLL

These are the only sentences are enabled in NMEAGPS_cfg.h, and LAST_SENTENCE_IN_INTERVAL has been set to NMEA_GLL, and verified correct by NMEAorder.ino. It is not possible to enable $GPZDA sentences on the Garmin 18x.

(I started with GLL disabled in both the Garmin's settings and in NMEAGPS_cfg.h, with GSV being the LAST_SENTENCE_IN_INTERVAL, but I enabled it to see if that would fix the problem, since GLL also includes the UTC time of fix, and I haven't bothered to disable it yet.)

NMEA.INO returns:

Status,UTC Date/Time,Lat,Lon,DMS,Alt,HDOP,VDOP,PDOP,Geoid Ht,Sats,Rx ok,Rx err,Rx chars,
4,2018-04-15 00:00:00.000,30XXXXXXX,-97YYYYYYY,XX XX' XX.XXX" N 097 YY' YY.YYY" W,22160,1000,1500,1800,-2770,7,7,0,439,

4,2018-04-15 00:00:00.000,30XXXXXXX,-97YYYYYYY,XX XX' XX.XXX" N 097 YY' YY.YYY" W,22160,1000,1500,1800,-2770,7,14,0,880,

The following program:

#include <NMEAGPS.h>
#include <GPSport.h>

NMEAGPS gps;
gps_fix fix;

void setup() {
  Serial.begin(115200);
  gpsPort.begin(9600);
}

void loop() {

  static unsigned long timer, current_millis, previous_millis;
  static boolean valid_date;
  static boolean valid_time;

  while (gps.available( Serial1 )) {
    fix = gps.read();

    current_millis = millis();
    timer = current_millis - previous_millis;

    if (fix.valid.date) {
      valid_date = true;
    }

    if (fix.valid.time) {
      valid_time = true;
    }

    if (timer > 2000) {

      previous_millis = current_millis;

      Serial.print(fix.dateTime.month); Serial.print("/"); Serial.print(fix.dateTime.date); Serial.print("/"); Serial.println(fix.dateTime.year);

      Serial.print(fix.dateTime.hours); Serial.print(":"); Serial.print(fix.dateTime.minutes); Serial.print(":"); Serial.println(fix.dateTime.seconds);

      if (valid_date) {
        Serial.println("fix.valid.date = true");
      }

      else {
        Serial.println("fix.valid.date = false");
      }

      if (valid_time) {
        Serial.println("fix.valid.time = true");
      }

      else {
        Serial.println("fix.valid.time = false");
      }

      Serial.println();

      valid_date = false;
      valid_time = false;
    }
  }
}

Returns:

4/16/18
0:0:0
fix.valid.date = true
fix.valid.time = false

4/16/18
0:0:0
fix.valid.date = true
fix.valid.time = false

Both Adadruit's GPS_HardwareSerial_Parsing.ino and TinyGPS++'s KitchenSink.ino (slightly modified to use hardware serial) are able to parse the time and date correctly, without making any changes to my hardware or the Garmin's internal settings.

Adadruit's GPS_HardwareSerial_Parsing.ino returns:

$GPRMC,231829,A,30XX.XXXX,N,097YY.YYYY,W,000.0,185.2,150418,004.1,E,D*00

$GPGGA,231829,30XX.XXXX,N,097YY.YYYY,W,2,08,1.0,218.2,M,-27.7,M,,*72

$GPGSA,A,3,,03,06,13,17,19,22,,28,30,,,1.6,1.0,1.2*37

$GPGSV,3,1,11,01,12,039,16,03,14,074,30,06,53,193,37,13,11,240,16*7E

$GPGSV,3,2,11,17,61,350,28,19,59,305,26,22,06,053,21,24,17,316,18*7D

$GPGSV,3,3,11,28,51,082,23,30,24,166,41,02,17,211,00*4B

$GPGLL,30XX.XXX,N,097YY.YYYY,W,231829,A,D*5E

Time: 23:18:29.0
Date: 15/4/2018
Fix: 1 quality: 2
Location: 30XX.XXXXN, 97YY.YYYYW
Speed (knots): 0.00
Angle: 185.20
Altitude: 218.20
Satellites: 8
SlashDevin commented 6 years ago

What an excellent report! The example data was crucial.

SlashDevin commented 6 years ago

BTW, I would like to suggest a few things:

Incorporating all those changes:

#include <NMEAGPS.h>
#include <GPSport.h>

NMEAGPS gps;
gps_fix fix;
uint8_t fixCount;

void setup() {
  Serial.begin(115200);
  gpsPort.begin(9600);
}

void loop() {

  while (gps.available( Serial1 )) {
    fix = gps.read();
    fixCount++;

    if (fixCount >= 2) {
      fixCount = 0;

      if (fix.valid.date) {
        Serial.print(fix.dateTime.month); Serial.print('/'); Serial.print(fix.dateTime.date); Serial.print('/'); Serial.println(fix.dateTime.year);
      } else {
        Serial.println( F("--/--/--") );
      }

      if (fix.valid.time) {
        Serial.print(fix.dateTime.hours); Serial.print(':'); Serial.print(fix.dateTime.minutes); Serial.print(':'); Serial.println(fix.dateTime.seconds);
      } else {
        Serial.println( F("--:--:--") );
      }

      Serial.println();
    }
  }
}

Thanks for the feedback!

SlashDevin commented 6 years ago

Sorry, I forgot to mention: you need to get the new NMEAGPS.cpp file for the Libraries/NeoGPS/src directory. This is not a new release yet.