kopia lustrzana https://github.com/meshtastic/firmware
GPS: Implement Power Management, Refactor Code and Fix GSA Message Configuration for U-Blox hardware (#2606)
rodzic
42d79d012e
commit
aa0b56e947
189
src/gps/GPS.cpp
189
src/gps/GPS.cpp
|
@ -60,9 +60,9 @@ bool GPS::getACK(uint8_t class_id, uint8_t msg_id)
|
||||||
// LOG_INFO("Got ACK for class %02X message %02X\n", class_id, msg_id);
|
// LOG_INFO("Got ACK for class %02X message %02X\n", class_id, msg_id);
|
||||||
return true; // ACK received
|
return true; // ACK received
|
||||||
}
|
}
|
||||||
if (millis() - startTime > 1500) {
|
if (millis() - startTime > 3000) {
|
||||||
LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id);
|
LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id);
|
||||||
return false; // No response received within 1.5 second
|
return false; // No response received within 3 seconds
|
||||||
}
|
}
|
||||||
if (_serial_gps->available()) {
|
if (_serial_gps->available()) {
|
||||||
b = _serial_gps->read();
|
b = _serial_gps->read();
|
||||||
|
@ -212,6 +212,7 @@ bool GPS::setupGPS()
|
||||||
_serial_gps->write("$PCAS11,3*1E\r\n");
|
_serial_gps->write("$PCAS11,3*1E\r\n");
|
||||||
delay(250);
|
delay(250);
|
||||||
} else if (gnssModel == GNSS_MODEL_UBLOX) {
|
} else if (gnssModel == GNSS_MODEL_UBLOX) {
|
||||||
|
|
||||||
// Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command)
|
// Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command)
|
||||||
// We need set it because by default it is GPS only, and we want to use GLONASS too
|
// We need set it because by default it is GPS only, and we want to use GLONASS too
|
||||||
// Also we need SBAS for better accuracy and extra features
|
// Also we need SBAS for better accuracy and extra features
|
||||||
|
@ -238,10 +239,19 @@ bool GPS::setupGPS()
|
||||||
_serial_gps->write(_message_GNSS, sizeof(_message_GNSS));
|
_serial_gps->write(_message_GNSS, sizeof(_message_GNSS));
|
||||||
|
|
||||||
if (!getACK(0x06, 0x3e)) {
|
if (!getACK(0x06, 0x3e)) {
|
||||||
LOG_WARN("Unable to reconfigure GNSS, keep factory defaults\n");
|
// It's not critical if the module doesn't acknowledge this configuration.
|
||||||
|
// The module should operate adequately with its factory or previously saved settings.
|
||||||
|
// It appears that there is a firmware bug in some GPS modules: When an attempt is made
|
||||||
|
// to overwrite a saved state with identical values, no ACK/NAK is received, contrary to
|
||||||
|
// what is specified in the Ublox documentation.
|
||||||
|
// There is also a possibility that the module may be GPS-only.
|
||||||
|
LOG_INFO("Unable to reconfigure GNSS - defaults maintained. Is this module GPS-only?\n");
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("GNSS set to GPS+SBAS+GLONASS, waiting before sending next command (0.75s)\n");
|
LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n");
|
||||||
|
// Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next commands
|
||||||
delay(750);
|
delay(750);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable interference resistance, because we are using LoRa, WiFi and Bluetoot on same board,
|
// Enable interference resistance, because we are using LoRa, WiFi and Bluetoot on same board,
|
||||||
|
@ -258,7 +268,8 @@ bool GPS::setupGPS()
|
||||||
// generalBits (General settings) is set to 0x31E as recommended
|
// generalBits (General settings) is set to 0x31E as recommended
|
||||||
// antSetting (Antenna setting, 0=unknown, 1=passive, 2=active) is set to 0 (unknown)
|
// antSetting (Antenna setting, 0=unknown, 1=passive, 2=active) is set to 0 (unknown)
|
||||||
// ToDo: Set to 1 (passive) or 2 (active) if known, for example from UBX-MON-HW, or from board info
|
// ToDo: Set to 1 (passive) or 2 (active) if known, for example from UBX-MON-HW, or from board info
|
||||||
// enable2 (Set to 1 to scan auxiliary bands, u-blox 8 / u-blox M8 only, otherwise ignored) is set to 1 (enabled)
|
// enable2 (Set to 1 to scan auxiliary bands, u-blox 8 / u-blox M8 only, otherwise ignored) is set to 1
|
||||||
|
// (enabled)
|
||||||
0x1E, 0x03, 0x00, 0x01, // config2: Extra settings for jamming/interference monitor
|
0x1E, 0x03, 0x00, 0x01, // config2: Extra settings for jamming/interference monitor
|
||||||
0x00, 0x00 // Checksum (calculated below)
|
0x00, 0x00 // Checksum (calculated below)
|
||||||
};
|
};
|
||||||
|
@ -271,6 +282,7 @@ bool GPS::setupGPS()
|
||||||
|
|
||||||
if (!getACK(0x06, 0x39)) {
|
if (!getACK(0x06, 0x39)) {
|
||||||
LOG_WARN("Unable to enable interference resistance.\n");
|
LOG_WARN("Unable to enable interference resistance.\n");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure navigation engine expert settings:
|
// Configure navigation engine expert settings:
|
||||||
|
@ -316,6 +328,7 @@ bool GPS::setupGPS()
|
||||||
|
|
||||||
if (!getACK(0x06, 0x23)) {
|
if (!getACK(0x06, 0x23)) {
|
||||||
LOG_WARN("Unable to configure extra settings.\n");
|
LOG_WARN("Unable to configure extra settings.\n");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -334,57 +347,179 @@ bool GPS::setupGPS()
|
||||||
|
|
||||||
// ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid
|
// ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid
|
||||||
|
|
||||||
// disable GGL
|
// Set GPS update rate to 1Hz
|
||||||
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01,
|
// Lowering the update rate helps to save power.
|
||||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
|
// Additionally, for some new modules like the M9/M10, an update rate lower than 5Hz
|
||||||
|
// is recommended to avoid a known issue with satellites disappearing.
|
||||||
|
byte _message_1Hz[] = {
|
||||||
|
0xB5, 0x62, // UBX protocol sync characters
|
||||||
|
0x06, 0x08, // Message class and ID (UBX-CFG-RATE)
|
||||||
|
0x06, 0x00, // Length of payload (6 bytes)
|
||||||
|
0xE8, 0x03, // Measurement Rate (1000ms for 1Hz)
|
||||||
|
0x01, 0x00, // Navigation rate, always 1 in GPS mode
|
||||||
|
0x01, 0x00, // Time reference
|
||||||
|
0x00, 0x00 // Placeholder for checksum, will be calculated next
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the checksum and update the message.
|
||||||
|
UBXChecksum(_message_1Hz, sizeof(_message_1Hz));
|
||||||
|
|
||||||
|
// Send the message to the module
|
||||||
|
_serial_gps->write(_message_1Hz, sizeof(_message_1Hz));
|
||||||
|
|
||||||
|
if (!getACK(0x06, 0x08)) {
|
||||||
|
LOG_WARN("Unable to set GPS update rate.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable GGL. GGL - Geographic position (latitude and longitude), which provides the current geographical
|
||||||
|
// coordinates.
|
||||||
|
byte _message_GGL[] = {
|
||||||
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x01, // NMEA ID for GLL
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x00, // Disable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the checksum and update the message.
|
||||||
|
UBXChecksum(_message_GGL, sizeof(_message_GGL));
|
||||||
|
|
||||||
|
// Send the message to the module
|
||||||
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
|
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
|
||||||
|
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to disable NMEA GGL.\n");
|
LOG_WARN("Unable to disable NMEA GGL.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable GSA
|
// Enable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and
|
||||||
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02,
|
// the DOP (Dilution of Precision)
|
||||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
|
byte _message_GSA[] = {
|
||||||
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x02, // NMEA ID for GSA
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x01, // Enable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
UBXChecksum(_message_GSA, sizeof(_message_GSA));
|
||||||
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
|
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to disable NMEA GSA.\n");
|
LOG_WARN("Unable to Enable NMEA GSA.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable GSV
|
// Disable GSV. GSV - Satellites in view, details the number and location of satellites in view.
|
||||||
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03,
|
byte _message_GSV[] = {
|
||||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x03, // NMEA ID for GSV
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x00, // Disable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
UBXChecksum(_message_GSV, sizeof(_message_GSV));
|
||||||
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
|
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to disable NMEA GSV.\n");
|
LOG_WARN("Unable to disable NMEA GSV.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable VTG
|
// Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to
|
||||||
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05,
|
// the ground.
|
||||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
|
byte _message_VTG[] = {
|
||||||
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x05, // NMEA ID for VTG
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x00, // Disable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
UBXChecksum(_message_VTG, sizeof(_message_VTG));
|
||||||
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
|
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to disable NMEA VTG.\n");
|
LOG_WARN("Unable to disable NMEA VTG.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable RMC
|
// Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data.
|
||||||
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04,
|
byte _message_RMC[] = {
|
||||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x04, // NMEA ID for RMC
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x01, // Enable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
UBXChecksum(_message_RMC, sizeof(_message_RMC));
|
||||||
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
|
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to enable NMEA RMC.\n");
|
LOG_WARN("Unable to enable NMEA RMC.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable GGA
|
// Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data.
|
||||||
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00,
|
byte _message_GGA[] = {
|
||||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x00, // NMEA ID for GGA
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x01, // Enable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
UBXChecksum(_message_GGA, sizeof(_message_GGA));
|
||||||
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
|
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to enable NMEA GGA.\n");
|
LOG_WARN("Unable to enable NMEA GGA.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Power Management configuration allows the GPS module to operate in different power modes for optimized power
|
||||||
|
// consumption.
|
||||||
|
// The modes supported are:
|
||||||
|
// 0x00 = Full power: The module operates at full power with no power saving.
|
||||||
|
// 0x01 = Balanced: The module dynamically adjusts the tracking behavior to balance power consumption.
|
||||||
|
// 0x02 = Interval: The module operates in a periodic mode, cycling between tracking and power saving states.
|
||||||
|
// 0x03 = Aggressive with 1 Hz: The module operates in a power saving mode with a 1 Hz update rate.
|
||||||
|
// 0x04 = Aggressive with 2 Hz: The module operates in a power saving mode with a 2 Hz update rate.
|
||||||
|
// 0x05 = Aggressive with 4 Hz: The module operates in a power saving mode with a 4 Hz update rate.
|
||||||
|
// The 'period' field specifies the position update and search period. It is only valid when the powerSetupValue is
|
||||||
|
// set to Interval; otherwise, it must be set to '0'. The 'onTime' field specifies the duration of the ON phase and
|
||||||
|
// must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise, it must
|
||||||
|
// be set to '0'.
|
||||||
|
byte UBX_CFG_PMS[14] = {
|
||||||
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x86, // Message class and ID (UBX-CFG-PMS)
|
||||||
|
0x06, 0x00, // Length of payload (6 bytes)
|
||||||
|
0x00, // Version (0)
|
||||||
|
0x03, // Power setup value
|
||||||
|
0x00, 0x00, // period: not applicable, set to 0
|
||||||
|
0x00, 0x00, // onTime: not applicable, set to 0
|
||||||
|
0x00, 0x00 // Placeholder for checksum, will be calculated next
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the checksum and update the message
|
||||||
|
UBXChecksum(UBX_CFG_PMS, sizeof(UBX_CFG_PMS));
|
||||||
|
|
||||||
|
// Send the message to the module
|
||||||
|
_serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS));
|
||||||
|
if (!getACK(0x06, 0x86)) {
|
||||||
|
LOG_WARN("Unable to enable powersaving for GPS.\n");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need save configuration to flash to make our config changes persistent
|
// We need save configuration to flash to make our config changes persistent
|
||||||
|
@ -407,8 +542,10 @@ bool GPS::setupGPS()
|
||||||
|
|
||||||
if (!getACK(0x06, 0x09)) {
|
if (!getACK(0x06, 0x09)) {
|
||||||
LOG_WARN("Unable to save GNSS module configuration.\n");
|
LOG_WARN("Unable to save GNSS module configuration.\n");
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("GNSS module configuration saved!\n");
|
LOG_INFO("GNSS module configuration saved!\n");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -824,8 +961,8 @@ GPS *createGps()
|
||||||
LOG_DEBUG("Using MSL altitude model\n");
|
LOG_DEBUG("Using MSL altitude model\n");
|
||||||
#endif
|
#endif
|
||||||
if (GPS::_serial_gps) {
|
if (GPS::_serial_gps) {
|
||||||
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just
|
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all.
|
||||||
// assume NMEA at 9600 baud.
|
// Just assume NMEA at 9600 baud.
|
||||||
GPS *new_gps = new NMEAGPS();
|
GPS *new_gps = new NMEAGPS();
|
||||||
new_gps->setup();
|
new_gps->setup();
|
||||||
return new_gps;
|
return new_gps;
|
||||||
|
|
Ładowanie…
Reference in New Issue