cyberman54 / ESP32-Paxcounter

Wifi & BLE driven passenger flow metering with cheap ESP32 boards
https://cyberman54.github.io/ESP32-Paxcounter/
Other
1.73k stars 404 forks source link

[GPS] Sent GPS data to LoRaWAN is corrupt when shown on display #1009

Closed TD-er closed 3 months ago

TD-er commented 3 months ago

The function gps_storelocation(gpsStatus_t *gps_store) does check for .isUpdated(), but the updated flag is already reset while showing on the display. (push the button a few times to display GPS data)

This causes the gps_store data not to get updated and thus the random data of this struct (because it isn't initialized in the constructor) is sent to LoRa.

Proposal: Change the function to return a bool:

bool gps_storelocation(gpsStatus_t *gps_store) {
  if (gps.location.isUpdated() && gps.location.isValid() &&
      (gps.location.age() < 1500)) {
    gps_store->latitude = (int32_t)(gps.location.lat() * 1e6);
    gps_store->longitude = (int32_t)(gps.location.lng() * 1e6);
    gps_store->satellites = (uint8_t)gps.satellites.value();
    gps_store->hdop = (uint16_t)gps.hdop.value();
    gps_store->altitude = (int16_t)gps.altitude.meters();
    return true;
  }
  return false;
}

And make sure to initialize the struct:

typedef struct {
  int32_t latitude{};
  int32_t longitude{};
  uint8_t satellites{};
  uint16_t hdop{};
  int16_t altitude{};
} gpsStatus_t;

Then in the 2 places where this function is called, check for its return value:

#if (HAS_GPS)
      if (GPSPORT == COUNTERPORT) {
        // send GPS position only if we have a fix
        if (gps_hasfix()) {
          if (gps_storelocation(&gps_status))
            payload.addGPS(gps_status);
        } else
          ESP_LOGD(TAG, "No valid GPS position");
      }
#endif
#if (HAS_GPS)
    case GPS_DATA:
      if (GPSPORT != COUNTERPORT) {
        // send GPS position only if we have a fix
        if (gps_hasfix()) {
          if (gps_storelocation(&gps_status)) {
            payload.reset();
            payload.addGPS(gps_status);
            SendPayload(GPSPORT);
          }
        } else
          ESP_LOGD(TAG, "No valid GPS position");
      }
      break;
#endif

This way, at least no bogus data is being sent to LoRa.

Tomorrow I will look into how we can read the GPS data without resetting the updated flag (or keep track of updated state elsewhere outside TinyGPS+)