sparkfun / SparkFun_u-blox_GNSS_Arduino_Library

An Arduino library which allows you to communicate seamlessly with the full range of u-blox GNSS modules
Other
221 stars 100 forks source link

Latency upon working #162

Closed jan5650 closed 1 year ago

jan5650 commented 1 year ago

Hello!

I have been very busy with this library lately. I have a GPS based project running at the moment, but I would like to rewrite the whole thing to this library, because I really like it and it makes it easy to configure the module.

I am using Arduino Mega 2560 Pro with Neo M8N GPS module.

Thanks to your help so far, the project is now functional with this library. The only problem I have is that it is a bit slow.

On a display I show the current Latitude-Longitude values and calculate the distance between two GPS coordinates. Unfortunately, the distance is updated very slowly. Sometimes it takes 3-4 seconds, sometimes 15-16 seconds, and I've had cases where it took 30-40 seconds to update, while I was constantly moving with the GPS module and there is 14 used GPS satelites and good view to sky.

With the previous library it updated very, very quickly.

Obviously, it is a case of me not setting something up correctly. I would like your help on this. The code is as follows: (the relevant part)

`

#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
SFE_UBLOX_GNSS myGNSS;
#define mySerial Serial1

void setup() {
  do {
    mySerial.begin(38400);
    if (myGNSS.begin(mySerial) == true) break;
    delay(100);
    mySerial.begin(9600);
    if (myGNSS.begin(mySerial) == true) {
        myGNSS.setSerialRate(38400);
        delay(100);
    } else {
        delay(2000); 
    }
  } while(1);

  myGNSS.setMeasurementRate(200); 
  myGNSS.setNavigationRate(1); 
  myGNSS.setAutoPVTrate(1); 

  myGNSS.disableNMEAMessage(UBX_NMEA_GLL, COM_PORT_UART1);
  myGNSS.disableNMEAMessage(UBX_NMEA_GSA, COM_PORT_UART1);
  myGNSS.disableNMEAMessage(UBX_NMEA_GSV, COM_PORT_UART1);
  myGNSS.disableNMEAMessage(UBX_NMEA_GLL, COM_PORT_I2C);
  myGNSS.disableNMEAMessage(UBX_NMEA_GSA, COM_PORT_I2C);
  myGNSS.disableNMEAMessage(UBX_NMEA_GSV, COM_PORT_I2C);

  myGNSS.setUART1Output(COM_TYPE_UBX); 
  myGNSS.setI2COutput(COM_TYPE_UBX); 
  myGNSS.saveConfiguration();   
}

void loop() {

 readingpwm();

 if ((millis()-lastTime)>200){
    lastTime=millis();

    satelites=myGNSS.getSIV();  

    if (myGNSS.getFixType() > 2){
        actlan = myGNSS.getLatitude();
        actlon = myGNSS.getLongitude();
        distanceBetween(actlan, actlon, oldlan, lodlon)   // oldlan and oldlon store elsewhere, not relevant
     }
  }      

 displaywrite(); 
}

void readingpwm() {
    // READING SOME PWM VALUES ON 3 PWM CAPABLE INPUT PIN
}

void displaywrite() {
    // WRITING SOME VALUES INTO DISPLAY (SATELITES NUMBER, Distance, ETC...)  
}

double distanceBetween(long lat1_l, long long1_l, long lat2_l, long long2_l)
{
    // THIS IS YOUR METHODE, NOT CHANGED
}`

So in nutshell: I am using hardware Serial1. I set the baud rate to 38400, then the measure rate to 5Hz (i want to query new gps position every 200ms, so track fast movement), and turn off some unnecessary NMEA sentences. I set UART1 output to UBX only. Then i read some pwm values, and then if there 3D gps fix then compute lat,lon,distance. After that i write out them on a display.

In this case, there is quite a long delay in the data entry. The distance data is updated very infrequently, whereas I would expect it to be updated 5 times per second.

However, if I rewrite if ((millis()-lastTime)>200){ to if ((millis()-lastTime)>100){, it updates much faster.

I think this may be the crux of the matter. I must be setting something wrong.

What do you think is the problem?

+1 Question: how can I configure the UBX command to allow the use of GALIELO satellites? So the best would be to use GPS+GLONASS+GALIELO satellites.

Thank you!

PaulZC commented 1 year ago

Hi @jan5650 ,

Some quick comments (I am busy with another project):

The six calls to disableNMEAMessage are actually redundant. setUART1Output(COM_TYPE_UBX) stops all NMEA messages from being output on UART1.

I think the main issue is this:

You are calling setAutoPVTrate to enable the PVT messages (at 5Hz). But you are only 'checking' UART1 / Serial1 when you call myGNSS.getSIV inside your lastTime > 200 loop.

You will get better results if you replace:

if ((millis()-lastTime)>200){

with:

if (myGNSS.getPVT()){

getPVT returns true when a new PVT message is received and processed. With the messages arriving at 5Hz, it will perform the 200ms timing for you. It will perform better because you are then checking Serial1 continuously for the arrival of new messages.

The other way is to leave your code as it is now, and add myGNSS.checkUblox(); to the main loop - outside the 200ms loop.

Re. setting the constellations, you need to call enableGNSS. Please try:

  myGNSS.enableGNSS(true, SFE_UBLOX_GNSS_ID_GPS); // Make sure GPS is enabled (we must leave at least one major GNSS enabled!)
  myGNSS.enableGNSS(false, SFE_UBLOX_GNSS_ID_BEIDOU); // Disable BeiDou
  myGNSS.enableGNSS(true, SFE_UBLOX_GNSS_ID_GALILEO); // Enable Galileo
  myGNSS.enableGNSS(true, SFE_UBLOX_GNSS_ID_GLONASS); // Enable GLONASS

Best wishes, Paul

jan5650 commented 1 year ago

Thank you for all your help.

Unfortunately the "myGNSS.getPVT()" method didn't work, for some reason it didn't return a value. I couldn't even get the satellite number back.

However, it looks like myGNSS.checkUblox(); works, I can run this every round, and the

actlan = myGNSS.getLatitude(); actlon = myGNSS.getLongitude();

lines out of the 200ms timing, so they run in every loop. Currently it runs pretty fast! You could say perfect. Question if this will cause a buffer overrun over time? The device runs for about 10 minutes in a row, then restarts. If it doesn't cause a buffer overrun or slowdown due to data accumulation in that time, it's a perfect solution.

So the code looks like now:

#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
SFE_UBLOX_GNSS myGNSS;
#define mySerial Serial1

void setup() {
  do {
    mySerial.begin(38400);
    if (myGNSS.begin(mySerial) == true) break;
    delay(100);
    mySerial.begin(9600);
    if (myGNSS.begin(mySerial) == true) {
        myGNSS.setSerialRate(38400);
        delay(100);
    } else {
        delay(2000); 
    }
  } while(1);

  myGNSS.setMeasurementRate(200); 
  myGNSS.setNavigationRate(1); 
  myGNSS.setAutoPVTrate(1);   

  myGNSS.setUART1Output(COM_TYPE_UBX); 
  myGNSS.setI2COutput(COM_TYPE_UBX); 
  myGNSS.saveConfiguration();   
}

void loop() {

 readingpwm();

 myGNSS.checkUblox();

 satelites=myGNSS.getSIV();  

    if (myGNSS.getFixType() > 2){
        actlan = myGNSS.getLatitude();
        actlon = myGNSS.getLongitude();
        distanceBetween(actlan, actlon, oldlan, lodlon)   // oldlan and oldlon store elsewhere, not relevant
     }   

 displaywrite(); 
}

void readingpwm() {
    // READING SOME PWM VALUES ON 3 PWM CAPABLE INPUT PIN
}

void displaywrite() {
    // WRITING SOME VALUES INTO DISPLAY (SATELITES NUMBER, Distance, ETC...)  
}

double distanceBetween(long lat1_l, long long1_l, long lat2_l, long long2_l)
{
    // THIS IS YOUR METHODE, NOT CHANGED
}

However, I ran into a problem with the Galileo satellites. Although Galileo is enabled in the module using the method you described, the device can only connect to and use the satellites if the NMEA protocol is version 4.10 (not 4.11, its not supported, only 4.10)

Is there an instruction in the library to enable NMEA 4.10?

PaulZC commented 1 year ago

Re. getPVT() : Please see this example:

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/blob/main/examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino

Re. NMEA for Galileo : why do you want to see the NMEA sentences for Galileo? (GAGGA etc.) If the Galileo constellation is enabled, the module will use it for positioning. It will provide fixes using the best satellites from all enabled constellations.

You can change the "Talker ID" if needed. Please see this example:

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/blob/main/examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino

Specifically, these lines:

https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/blob/89ecefc29a61dedb6ed755602924e082da22cc76/examples/Automatic_NMEA/Example1_getLatestNMEAGPGGA/Example1_getLatestNMEAGPGGA.ino#L68-L70

jan5650 commented 1 year ago

So I must have misunderstood something.

I use U-Center, and when I used NMEA protocol 4.0, I couldn't see the Galileo satellites. However, when I switched on the 4.10 NMEA they appeared.

NMEA 4.0 (NO GALIELO Satelites) galielo 1

NMEA 4.10 (There is 3-4 Galileo Satelites) galielo 2

So it's enough to enable Galileo and the module will send the Galileo data via UBX protocol, no problem if the satellites are not visible in U-Center because it interprets NMEA data?

Unfortunately this TalkerID is not clear to me. What exactly does it mean. If I set it to Galileo (GA) it will receive them primarily, but still use the other enabled ones (GPS, GLONASS)

PaulZC commented 1 year ago

Please see section 31.1.2 Talker ID and section 32.10.21.3 Extended NMEA protocol configuration V1:

https://www.u-blox.com/sites/default/files/products/documents/u-blox8-M8_ReceiverDescrProtSpec_UBX-13003221.pdf

image

PaulZC commented 1 year ago

"So it's enough to enable Galileo and the module will send the Galileo data via UBX protocol". Yes, exactly that.

Best wishes, Paul