Why is my ZED-F9P responding so slowly?

See below the output at Serial monitor from my code. Although I have setNavigationFrequency to 2 solutions/second it often takes over 2 seconds to respond, and even then it only updates the GPS coordinates every 5 - 10 seconds. (NB: the ms value in square brackets at end of each line is time spent in that loop)

Also it sometimes respond really quick, even < 100ms.
What am I doing wrong? (TIA)

My hardware:
Micromod Main Double board, fitted with:
Processor board : Micromod Teensy
Function board 0: Micromod ZED-F9P GNSS
Function board 1: Micromod ESP-32 WiFi/Bluetooth

My code, on Teensy:

#include <Streaming.h> 
#include <TimeLib.h> 
#include <SparkFun_u-blox_GNSS_v3.h> 

#define ZED Serial1                       // for TX of RTCM3 corrections + RX of GNS status data 

SFE_UBLOX_GNSS_SERIAL gnss;

time_t timeU;                             // UTC 
uint32_t t0,t1,t2;                        // timestamps
int32_t latitude, longitude, altitude;    // GPS coords

void setup() {
  Serial.begin(115200);                   // not needed teensy
  while (!Serial && millis() < 1000);
  delay(1000);
  Serial << "\n\n======= GPS_basic.A =======\n";
  initGNS();
  processGPStime();                       // UTC time
  reportDateTime(timeU);
  Serial << '\n' << '\n';
  latitude  = gnss.getLatitude();                     // (10^7)°
  longitude = gnss.getLongitude();                    // (10^7)°
  Serial << "Lat/Lon: " << latitude << " / " << longitude << " ° (*10^7)";
  Serial << "\n\n------ setup() done -----\n"; 
  t0 = millis();
}

uint loops = 0;

void loop() {  
  t1 = millis();
  //if (t1 - t0 >= 1000) {
    Serial << _WIDTHZ(++loops,3) << ": ";
    processGPStime();
    reportDateTime(timeU);
    latitude  = gnss.getLatitude(); 
    longitude = gnss.getLongitude();
    Serial << "  Lat/Lon " << latitude << " / " << longitude; // << "° (*10^7) ";
    t0 = millis();
    Serial << "  [" << (t0-t1) << " ms]\n";    
  //}
}

void initGNS(){  
  Serial << " * initialise GNSS  : ";
  ZED.begin(921600);                                            // 8 x 115200 bps = 115.2 kB/s 
  while (!gnss.begin(ZED)) {                                    // Connect to ZED-F9P over Serial 
          Serial << ".";
          delay (1000);
          }
  gnss.setUART1Output(COM_TYPE_UBX);                            // same, for Serial/UART1 connections
  gnss.setNavigationFrequency(2);                               // set for 2 solutions/second  
  Serial << "OK [2 sol/sec]\n";   
  Serial << " * Wait for GPS Fix : ";      
  while (!gnss.getGnssFixOk()) {                                // Connect to the u-blox module 
          Serial << ".";
          delay (1000);
          }
  Serial << "OK\n";
  Serial << " * Wait for GPS PVT : ";
  while (!gnss.getPVT()) {
    Serial << "."; 
    delay(500);
    } 
  Serial << " OK\n\n";  
  }

void processGPStime(){
  tmElements_t tm;  
  tm.Year   = gnss.getYear(1) - 1970;                           // load UTC time elements
  tm.Month  = gnss.getMonth(1);
  tm.Day    = gnss.getDay(1);
  tm.Hour   = gnss.getHour(1);
  tm.Minute = gnss.getMinute(1);
  tm.Second = gnss.getSecond(1);    
  timeU = makeTime(tm);                                         // UTC = GPS time (as unixtime) 
  }

void reportDateTime(time_t t){
  if (t >=  946684800 && t < 2524608000){                 // if in valid years (1/1/2000 to 31/12/2049)
    Serial << "UTC "; 
    Serial  << _WIDTHZ(  hour(t),2) << ":" 
            << _WIDTHZ(minute(t),2) << ":" 
            << _WIDTHZ(second(t),2) << " "; 
    Serial  << dayShortStr(weekday(t)) << " "
            << _WIDTHZ(  day(t),2) << "/"
            << _WIDTHZ(month(t),2) << "/"
            <<          year(t);
    }
  else Serial << " *** time invalid (2) ***";
  }

I don’t think 2 Hz would overwhelm UART2 at 38400 baud, but would suggest you disable output on UART2

Otherwise you’re going to want to inspect the output on UART1 to understand what’s happening there.

I doubt that. The only instuctions that are slow are getLatittude() and getLongitude(). If I comment them out, I have to enable the if (t1-t0) >= 1000) { test, to slow the loop to a readable speed.

The question is why are these two requests to the ZED adding over 2 seconds delay on most occasions, but not always? I should be able to get a current Lat/Lon readings twice a second, since I’ve set up for 2 solutions per second.

The time output isn’t exactly consistent either, with the supposed elapsed time.
So either somethings blocking, or there are secondary issues.
You’ll have to debug the library, and see what pumps the data, or if you have to spin on the getPVT().
Observing what’s coming out the ZED’s UART1 would be instructive as to whether you’re fighting an issue with the receiver, or your application of the library.

Yes it’s weird the time gap jumps around. I’ve even seen it as short as 85ms, although even that’s a long time in a Teensy.

AFAIK my code is not unusual. I did start from Sparkfun examples way back, but I’d like to know if my code is basically wrong, or not.

Well its not working the way you want, I’d take that as a sign..

Perhaps try something closer to this, where getPVT() might pump/gate the availability of new data more coherently.

Note it’s use of gnss.setAutoPVT(true); //Tell the GNSS to “send” each solution

If you’re instead POLLING, the round trip of the query/response might be multiple epochs, rather than simply output with periodicity.

Hi @ninja2 ,

I agree with @clive1, I think the slow rate is all due to the way you have structured your code. Your use of 1ms timeouts is unusual and unlikely to work the way you expect it to. By default, the library polls (requests) the PVT message. Making it periodic (setting it to “Auto”) helps a lot and changes the way getPVT works. getPVT will then return true if fresh PVT data has arrived since the last call, otherwise it returns false.

For the ZED-F9P, I’d recommend using v3 of the library. It looks like you already are. Clive’s link is to a v2 example. For v3, the simplest “Auto PVT” example is below.

I hope this helps,
Paul