Fix U-Blox detection code. (#5014)

Recently there have been reports of intermittent difficulties
detecting U-Blox chips. This patch proposes a new approach that should
be more reliable.

Previously we were fighting with NMEA messages to try and send binary
commands. We unusually also tried changing the Baud rate of U-Blox
chips, something we don't do with any other GPS.

It turns out U-Blox has another method to disable NMEA
messages. PUBX,40 is a text-based command, supported on all the
U-Blox versions we care about that can set the rate of NMEA messages
to zero.

This is what we attempt to do with all other GPS and it works quite
well.

So this patch alters the probe code to:
1. Remove UBX binary code to stop NMEA messages
2. Remove code that tries to reset UBX chips to 9600 baud
3. Add UBX proprietary text commands messages to stop the NMEA flood
4. Improve log strings sent to the user.

Tested on Ublox 6, Ublox 9, and Ublox 10 on multiple devices.

Also tested on several devices with
non-Ublox GPS to ensure it does not interfere with their detection
(heltec-wireless-tracker, wio-tracker-wm11110)
This commit is contained in:
Tom Fifield 2024-10-10 19:45:40 +08:00 committed by GitHub
parent 3b21856a76
commit 1b04d41b9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1106,6 +1106,11 @@ GnssModel_t GPS::probe(int serialSpeed)
// Close all NMEA sentences, valid for L76K, ATGM336H (and likely other AT6558 devices)
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
delay(20);
// Close NMEA sequences on Ublox
_serial_gps->write("$PUBX,40,GLL,0,0,0,0,0,0*5C\r\n");
_serial_gps->write("$PUBX,40,GSV,0,0,0,0,0,0*59\r\n");
_serial_gps->write("$PUBX,40,VTG,0,0,0,0,0,0*5E\r\n");
delay(20);
// Unicore UFirebirdII Series: UC6580, UM620, UM621, UM670A, UM680A, or UM681A
PROBE_SIMPLE("UC6580", "$PDTINFO", "UC6580", GNSS_MODEL_UC6580, 500);
@ -1138,35 +1143,10 @@ GnssModel_t GPS::probe(int serialSpeed)
// Check that the returned response class and message ID are correct
GPS_RESPONSE response = getACK(0x06, 0x08, 750);
if (response == GNSS_RESPONSE_NONE) {
LOG_WARN("Failed to find UBlox & MTK GNSS Module using baudrate %d\n", serialSpeed);
LOG_WARN("Failed to find GNSS Module (baudrate %d)\n", serialSpeed);
return GNSS_MODEL_UNKNOWN;
} else if (response == GNSS_RESPONSE_FRAME_ERRORS) {
LOG_INFO("UBlox Frame Errors using baudrate %d\n", serialSpeed);
} else if (response == GNSS_RESPONSE_OK) {
LOG_INFO("Found a UBlox Module using baudrate %d\n", serialSpeed);
}
// tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after
// setting will not output command messages in UART1, resulting in unrecognized module information
if (serialSpeed != 9600) {
// Set the UART port to 9600
uint8_t _message_prt[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00,
0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
UBXChecksum(_message_prt, sizeof(_message_prt));
_serial_gps->write(_message_prt, sizeof(_message_prt));
delay(500);
serialSpeed = 9600;
#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL)
_serial_gps->end();
_serial_gps->begin(serialSpeed);
#elif defined(ARCH_RP2040)
_serial_gps->end();
_serial_gps->setFIFOSize(256);
_serial_gps->begin(serialSpeed);
#else
_serial_gps->updateBaudRate(serialSpeed);
#endif
delay(200);
LOG_INFO("UBlox Frame Errors (baudrate %d)\n", serialSpeed);
}
memset(buffer, 0, sizeof(buffer));
@ -1218,12 +1198,6 @@ GnssModel_t GPS::probe(int serialSpeed)
for (int i = 0; i < info.extensionNo; ++i) {
if (!strncmp(info.extension[i], "MOD=", 4)) {
strncpy((char *)buffer, &(info.extension[i][4]), sizeof(buffer));
// LOG_DEBUG("GetModel:%s\n", (char *)buffer);
if (strlen((char *)buffer)) {
LOG_INFO("%s detected, using GNSS_MODEL_UBLOX\n", (char *)buffer);
} else {
LOG_INFO("Generic Ublox detected, using GNSS_MODEL_UBLOX\n");
}
} else if (!strncmp(info.extension[i], "PROTVER", 7)) {
char *ptr = nullptr;
memset(buffer, 0, sizeof(buffer));
@ -1238,18 +1212,23 @@ GnssModel_t GPS::probe(int serialSpeed)
}
}
if (strncmp(info.hwVersion, "00040007", 8) == 0) {
LOG_INFO(DETECTED_MESSAGE, "U-blox 6", GNSS_MODEL_UBLOX6);
return GNSS_MODEL_UBLOX6;
} else if (strncmp(info.hwVersion, "00070000", 8) == 0) {
LOG_INFO(DETECTED_MESSAGE, "U-blox 7", GNSS_MODEL_UBLOX7);
return GNSS_MODEL_UBLOX7;
} else if (strncmp(info.hwVersion, "00080000", 8) == 0) {
LOG_INFO(DETECTED_MESSAGE, "U-blox 8", GNSS_MODEL_UBLOX8);
return GNSS_MODEL_UBLOX8;
} else if (strncmp(info.hwVersion, "00190000", 8) == 0) {
LOG_INFO(DETECTED_MESSAGE, "U-blox 9", GNSS_MODEL_UBLOX9);
return GNSS_MODEL_UBLOX9;
} else if (strncmp(info.hwVersion, "000A0000", 8) == 0) {
LOG_INFO(DETECTED_MESSAGE, "U-blox 10", GNSS_MODEL_UBLOX10);
return GNSS_MODEL_UBLOX10;
}
}
LOG_WARN("Failed to find GNSS Module (baudrate %d)\n", serialSpeed);
return GNSS_MODEL_UNKNOWN;
}