mikalhart / TinyGPSPlus

A new, customizable Arduino NMEA parsing library
http://arduiniana.org
1.11k stars 494 forks source link

ESP32: GPGSA custom values stay empty #113

Closed sgofferj closed 1 year ago

sgofferj commented 1 year ago

I'm trying to extract the fix mode from the GPGSA sentence but it seems to always stay empty. The general parsing, however, seems to work. Here is my relevant code:


#define gpsPort_RX 35
#define gpsPort_TX 32

SoftwareSerial gpsPort;
TinyGPSPlus gps;

TinyGPSCustom fixMode(gps, "GPGSA", 2);
TinyGPSCustom pdop(gps, "GPGSA", 15);

void feedGPS (void * parameter) {
  for (;;) {
    while (gpsPort.available() > 0) {
      gps.encode(gpsPort.read());
      vTaskDelay(1);
    }
    vTaskDelay(1);
  }
}

void printGPS (void * parameter) {
  for (;;) {
    uint8_t mode = atoi(fixMode.value());
    if (gps.location.isUpdated()) {
      Serial.print(mode);
      Serial.print(", ");
      Serial.print(gps.location.lat(), 6);
      Serial.print(", ");
      Serial.print(gps.location.lng(), 6);
      Serial.print(", ");
      Serial.print(gps.speed.kmph());
      Serial.print(", ");
      Serial.print(gps.satellites.value());
      Serial.print(", ");
      Serial.print(pdop.value());
      Serial.print(", ");
      Serial.print(gps.location.isValid());
      Serial.print(", ");
      Serial.print(gps.location.age());
      Serial.println();
      vTaskDelay(500);
    } else {
      Serial.print(gps.time.value());
      Serial.print(", ");
      Serial.print(pdop.value());
      Serial.print(", ");
      Serial.print(mode);
      Serial.println();
      vTaskDelay(500);
    }
  }
}

void setup()
{
  Serial.begin(115200);
  gpsPort.begin(38400, SWSERIAL_8N1,gpsPort_RX,gpsPort_TX, false);
  if (!gpsPort) { // If the object did not initialize, then its configuration is invalid
    Serial.println("Invalid SoftwareSerial pin configuration, check config"); 
    while (1) { // Don't continue with invalid configuration
      delay (1000);
    }
  } 

  xTaskCreate(
    feedGPS,    // Function that should be called
    "Feed GPS",   // Name of the task (for debugging)
    1000,            // Stack size (bytes)
    NULL,            // Parameter to pass
    1,               // Task priority
    NULL             // Task handle
  );

  xTaskCreate(
    printGPS,    // Function that should be called
    "print GPS",   // Name of the task (for debugging)
    1000,            // Stack size (bytes)
    NULL,            // Parameter to pass
    1,               // Task priority
    NULL             // Task handle
  );
}

The GPGSA sentence from the GPS rx does come and it does seem correct to me. The rx is a genuine uBlox Neo-6M.

$GPGSA,A,1,24,06,11,,,,,,,,,,4.09,3.97,1.00*01

I tried to get different elements and c&p the example but I can't get it to work. All custom fields remain empty:

0, 61.xxxxxx, 24.xxxxxx, 1.43, 0, , 1, 389

My setup:

svdrummer commented 1 year ago

Have you tried GNGSA

sgofferj commented 1 year ago

Have you tried GNGSA

The Rx doesn't provide that.

sgofferj commented 1 year ago

Found the issue. I have a vTaskDelay(1); inside the while loop in feedGPS(). Apparently, that caused some bytes to drop and thus checksum errors. Removed that and it works now...

cyberman54 commented 1 year ago

@sgofferj i would not expect the vTaskDelay(1) causing that issue. The ESP32 is by far fast enough to feed the tinygps parser. I'm using much longer delays in the feed loop, and this works stable with 115200 bps on the serial interface. To ensure this you can validate the NMEA sentence cheksums.

For me this looks like a task priority / RTOS task starvation issue. Try to INCREASE the second vTaskDelay, and LOWER the task priorities by INCREASING the prio number. Watch the task states.

It sure is not an issue of TinyGps. It's inside your code / flow.

sgofferj commented 1 year ago

I'm using much longer delays in the feed loop

Actually, you don't :smiley: . In your inner while loop - the one which feeds the bytes from the serial to TGPS+ - there's no delay like I had. I changed my feedGPS function now to that and it works without flaws.

void feedGPS (void * parameter) {
  for (;;) {
    while (gpsPort.available() > 0)
      gps.encode(gpsPort.read());
    vTaskDelay(10);
  }
}

To ensure this you can validate the NMEA sentence cheksums.

Yeah, that was actually how I got to look at feeGPS. I Serial.println()'d the number of bad checksum packets.