sparkfun / SparkFun_Ublox_Arduino_Library

Library to control UBX binary protocol and NMEA over I2C on Ublox GPS modules
Other
144 stars 84 forks source link

Bug : isConnected function only works for i2c and fails for Serial #129

Closed sukesh-ak closed 4 years ago

sukesh-ak commented 4 years ago

Subject of the issue

Looks like isConnected function only works for i2c but its used in both (i2c & Serial) Begin functions. So the detection fails in the case of UART connected modules.

//Returns true if I2C device ack's
boolean SFE_UBLOX_GPS::isConnected(uint16_t maxWait)
{
  if (commType == COMM_TYPE_I2C)
  {
    _i2cPort->beginTransmission((uint8_t)_gpsI2Caddress);
    if (_i2cPort->endTransmission() != 0)
      return false; //Sensor did not ack
  }

  // Query navigation rate to see whether we get a meaningful response
  packetCfg.cls = UBX_CLASS_CFG;
  packetCfg.id = UBX_CFG_RATE;
  packetCfg.len = 0;
  packetCfg.startingSpot = 0;

  return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_RECEIVED); // We are polling the RATE so we expect data and an ACK
}

This code does not work as expected

  if (myGPS.begin(GPSSerial) == false)
  {
    Serial.println(F("Ublox GPS not detected. Check wiring."));
    while (1)
      ;
  }

Your workbench

UBlox 8 connected to ESP32

Steps to reproduce

Use GPS module with UART and use begin check for module detection

Expected behavior

isConnected should implement routine for Serial too

Actual behavior

Fails the module detection logic

sukesh-ak commented 4 years ago

I checked again and isConnected works now without any hardware changes.

Is it possible that the isConnected fails when module is used just after cold start?

PaulZC commented 4 years ago

Hi Sukesh (@sukesh-ak ), You need to wait for a full second before attempting to communicate with the module after a cold start. If you try to attempt to communicate sooner than this, it can fail. Can you please try putting a delay(1000); in your code, before the myGPS.begin. Does that help? Best wishes, Paul

sukesh-ak commented 4 years ago

Hi Sukesh (@sukesh-ak ), You need to wait for a full second before attempting to communicate with the module after a cold start. If you try to attempt to communicate sooner than this, it can fail. Can you please try putting a delay(1000); in your code, before the myGPS.begin. Does that help? Best wishes, Paul

Thanks Paul for the quick response. Will try with delay and check.

sukesh-ak commented 4 years ago

@PaulZC Doesn't look like that fixes it. Waiting now for a fix to test again.

sukesh-ak commented 4 years ago
  if (myGPS.begin(GPSSerial) == false)
  {
    Serial.println(F("Ublox GPS not detected. Check wiring."));
    while (1)
      ;
  }

I skip the above snippet and initialize directly like below, it works fine. Delay didn't make any difference this time.

myGPS.begin(GPSSerial);
PaulZC commented 4 years ago

Hi Sukesh (@sukesh-ak ), Are you still having problems? I'm not familiar with the ESP32. Are you using hardware serial or software serial? Which pins are you using? Best wishes, Paul

sukesh-ak commented 4 years ago

Hi Sukesh (@sukesh-ak ), Are you still having problems? I'm not familiar with the ESP32. Are you using hardware serial or software serial? Which pins are you using? Best wishes, Paul

Yes I still have the issue. I am waiting for the arrival of some new modules for development. For now I skipped that check to make it work.

ESP32 has 3 UART so yes I am using hardware serial. UART on ESP32 is software configurable, so you can assign any available PINS.

In my case this is the config

#define GPSSerial Serial2
#define GPS_BAUD 115200
#define RXD2 33  
#define TXD2 32  

Using it like this

  GPSSerial.begin(GPS_BAUD,SERIAL_8N1,RXD2, TXD2);
PaulZC commented 4 years ago

Hi Sukesh, Thanks for letting me know. .begin does work with Serial, but there can be (rare) occasions when it fails. As you found, .begin calls .isConnected which polls the module's navigation RATE. If there are a lot of NMEA messages coming in on the serial port, the UBX RATE message might get missed. Let me know what happens when your new modules arrive. I can give you some pointers on how to disable the NMEA messages using u-center. Best wishes, Paul

sukesh-ak commented 4 years ago

Will this be enough to disable NMEA and enable only UBX?

myGPS.setUART1Output(COM_TYPE_UBX);

You are talking about disabling NMEA and using only UBX right?

Though for development/testing I can manually configure using u-center, I would like to configure everything through this library. That's the main reason + using UBX (no more NMEA parsing etc.) makes this library attractive.

Appreciate your help @PaulZC

PaulZC commented 4 years ago

Hi Sukesh,

Correct. The critical thing to do is stop the NMEA messages and the easiest way to do that is myGPS.setUART1Output(COM_TYPE_UBX);

If your M8 board has battery back-up and you want the module to remember the settings then you can also call saveConfigSelective to save (only) the IO port settings to battery-backed RAM:

  // Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
  //myGPS.factoryDefault(); delay(5000);

  myGPS.setUART1Output(COM_TYPE_UBX); //Set the UART1 port to output UBX only (turn off NMEA noise)
  myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save the communications port settings to flash and BBR

I try to avoid calling saveConfiguration as that saves all the settings to BBR, including which individual messages are enabled or what power-saving state the module is in. I normally want it to forget all that and only remember to stop sending NMEA messages.

With Serial, you need to be careful that you don't overflow your serial receive buffer. This can happen if the serial buffer is small and it fills up with NMEA messages - before the UBX RATE message that .isConnected looks for arrives.

Another useful trick is putting this line before your .begin to make sure the serial buffer is completely empty:

while (GPSSerial.available()) GPSSerial.read();

One final check is to make sure you are using the correct baud rate. The u-blox 8 defaults to 9600. The newer 9 series defaults to 38400.

Best wishes, Paul

sukesh-ak commented 4 years ago

Correct. The critical thing to do is stop the NMEA messages and the easiest way to do that is myGPS.setUART1Output(COM_TYPE_UBX);

Done

If your M8 board has battery back-up and you want the module to remember the settings then you can also call saveConfigSelective to save (only) the IO port settings to battery-backed RAM:

It does so I am saving it. I will try selective option once the new module is here.

  // Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
  //myGPS.factoryDefault(); delay(5000);

  myGPS.setUART1Output(COM_TYPE_UBX); //Set the UART1 port to output UBX only (turn off NMEA noise)
  myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save the communications port settings to flash and BBR

I try to avoid calling saveConfiguration as that saves all the settings to BBR, including which individual messages are enabled or what power-saving state the module is in. I normally want it to forget all that and only remember to stop sending NMEA messages.

Ok got it. Will keep that in mind.

With Serial, you need to be careful that you don't overflow your serial receive buffer. This can happen if the serial buffer is small and it fills up with NMEA messages - before the UBX RATE message that .isConnected looks for arrives.

Another useful trick is putting this line before your .begin to make sure the serial buffer is completely empty:

while (GPSSerial.available()) GPSSerial.read();

Will try this as well.

One final check is to make sure you are using the correct baud rate. The u-blox 8 defaults to 9600. The newer 9 series defaults to 38400.

Yes the baud rate is 115200 and its set correctly by me. Also ESP32 is dual core 240Mhz so enough processing power to manage it. Later I will also implement circular buffer just to make sure I don't miss data when other sensors get added as well.

Thank you so much for your time and assistance. Will update once new modules are here (uBlox M8-KT)

PaulZC commented 4 years ago

Hi Sukesh (@sukesh-ak ), How's it going? Are you still having isConnected problems? Best wishes, Paul

sukesh-ak commented 4 years ago

Thanks for checking in @PaulZC I changed the code and instead of checking for whether connected, I am using it only to check for the correct baud rate. There it works fine. So we can close this now.

  if (myGPS.begin(GPSSerial)==true)
  {
    Serial.println("Baud:115200 so all good");
  }