firmware: auto-detect GPS UART baud
This commit is contained in:
@@ -9,7 +9,7 @@ This Arduino sketch reads a BNO086 IMU and MAX-M10S GPS and publishes versioned,
|
|||||||
| GPS TX to XIAO RX | D9 |
|
| GPS TX to XIAO RX | D9 |
|
||||||
| GPS RX from XIAO TX | D10 |
|
| GPS RX from XIAO TX | D10 |
|
||||||
|
|
||||||
Power both sensors from 3.3V with shared ground. Required Arduino libraries are Adafruit BNO08x, TinyGPSPlus, and ArduinoJson 6.x. Enable **USB CDC On Boot** for diagnostics. GPS uses hardware UART0 and RS485 uses hardware UART1.
|
Power both sensors from 3.3V with shared ground. Required Arduino libraries are Adafruit BNO08x, TinyGPSPlus, and ArduinoJson 6.x. Enable **USB CDC On Boot** for diagnostics. GPS uses hardware UART0 and RS485 uses hardware UART1. Startup probes 9600, 38400, 115200, and 4800 baud and reports the first rate producing checksum-valid NMEA.
|
||||||
|
|
||||||
At startup the firmware scans D7/D8 and accepts either valid BNO08x address, `0x4A` or `0x4B`. If neither appears in the scan, verify 3.3V/GND, swap-check SDA and SCL, and confirm the breakout's PS0/PS1 jumpers are configured for I2C.
|
At startup the firmware scans D7/D8 and accepts either valid BNO08x address, `0x4A` or `0x4B`. If neither appears in the scan, verify 3.3V/GND, swap-check SDA and SCL, and confirm the breakout's PS0/PS1 jumpers are configured for I2C.
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,48 @@
|
|||||||
#include "sensor_node_config.h"
|
#include "sensor_node_config.h"
|
||||||
namespace { TinyGPSPlus parser; }
|
namespace { TinyGPSPlus parser; }
|
||||||
|
|
||||||
void initGps(HardwareSerial& serial) { serial.begin(GPS_BAUD, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); }
|
namespace {
|
||||||
|
uint32_t activeBaud = GPS_FALLBACK_BAUD;
|
||||||
|
|
||||||
|
bool baudHasValidNmea(HardwareSerial& serial, uint32_t baud) {
|
||||||
|
TinyGPSPlus probe;
|
||||||
|
serial.end();
|
||||||
|
serial.begin(baud, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
|
||||||
|
unsigned long started = millis();
|
||||||
|
while (millis() - started < GPS_BAUD_DETECT_MS) {
|
||||||
|
while (serial.available()) probe.encode(serial.read());
|
||||||
|
if (probe.passedChecksum() > 0) return true;
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initGps(HardwareSerial& serial) {
|
||||||
|
const uint32_t candidates[] = {9600, 38400, 115200, 4800};
|
||||||
|
Serial.println("Detecting GPS UART baud...");
|
||||||
|
for (uint32_t baud : candidates) {
|
||||||
|
Serial.print("Trying GPS baud ");
|
||||||
|
Serial.println(baud);
|
||||||
|
if (!baudHasValidNmea(serial, baud)) continue;
|
||||||
|
activeBaud = baud;
|
||||||
|
Serial.print("Valid GPS NMEA detected at ");
|
||||||
|
Serial.println(activeBaud);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
activeBaud = GPS_FALLBACK_BAUD;
|
||||||
|
serial.end();
|
||||||
|
serial.begin(activeBaud, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
|
||||||
|
Serial.println("No valid GPS NMEA detected; falling back to 9600 baud");
|
||||||
|
}
|
||||||
|
|
||||||
void updateGps(HardwareSerial& serial, GpsState& s) {
|
void updateGps(HardwareSerial& serial, GpsState& s) {
|
||||||
while (serial.available()) { s.lastByteMs = millis(); parser.encode(serial.read()); }
|
while (serial.available()) { s.lastByteMs = millis(); parser.encode(serial.read()); }
|
||||||
s.charactersProcessed = parser.charsProcessed();
|
s.charactersProcessed = parser.charsProcessed();
|
||||||
s.sentencesPassed = parser.passedChecksum();
|
s.sentencesPassed = parser.passedChecksum();
|
||||||
s.sentencesFailed = parser.failedChecksum();
|
s.sentencesFailed = parser.failedChecksum();
|
||||||
|
s.baud = activeBaud;
|
||||||
s.online = s.lastByteMs && millis() - s.lastByteMs <= SENSOR_STALE_MS;
|
s.online = s.lastByteMs && millis() - s.lastByteMs <= SENSOR_STALE_MS;
|
||||||
s.fix = parser.location.isValid() && parser.location.age() <= SENSOR_STALE_MS;
|
s.fix = parser.location.isValid() && parser.location.age() <= SENSOR_STALE_MS;
|
||||||
s.satellites = parser.satellites.isValid() ? parser.satellites.value() : 0;
|
s.satellites = parser.satellites.isValid() ? parser.satellites.value() : 0;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ void publishSensorStatus(HardwareSerial& serial, const ImuState& imu, const GpsS
|
|||||||
i["yaw_degrees"] = imu.yawDegrees; i["pitch_degrees"] = imu.pitchDegrees; i["roll_degrees"] = imu.rollDegrees;
|
i["yaw_degrees"] = imu.yawDegrees; i["pitch_degrees"] = imu.pitchDegrees; i["roll_degrees"] = imu.rollDegrees;
|
||||||
JsonObject g = doc.createNestedObject("gps");
|
JsonObject g = doc.createNestedObject("gps");
|
||||||
g["online"] = gps.online; g["fix"] = gps.fix; g["satellites"] = gps.satellites;
|
g["online"] = gps.online; g["fix"] = gps.fix; g["satellites"] = gps.satellites;
|
||||||
|
g["baud"] = gps.baud;
|
||||||
JsonObject nmea = g.createNestedObject("nmea");
|
JsonObject nmea = g.createNestedObject("nmea");
|
||||||
nmea["characters"] = gps.charactersProcessed;
|
nmea["characters"] = gps.charactersProcessed;
|
||||||
nmea["sentences_passed"] = gps.sentencesPassed;
|
nmea["sentences_passed"] = gps.sentencesPassed;
|
||||||
|
|||||||
@@ -14,7 +14,8 @@
|
|||||||
#define BNO086_I2C_ADDRESS 0x4A
|
#define BNO086_I2C_ADDRESS 0x4A
|
||||||
#define BNO086_I2C_ADDRESS_ALTERNATE 0x4B
|
#define BNO086_I2C_ADDRESS_ALTERNATE 0x4B
|
||||||
#define BNO086_I2C_CLOCK_HZ 100000
|
#define BNO086_I2C_CLOCK_HZ 100000
|
||||||
#define GPS_BAUD 9600
|
#define GPS_FALLBACK_BAUD 9600
|
||||||
|
#define GPS_BAUD_DETECT_MS 2500
|
||||||
#define RS485_BAUD 115200
|
#define RS485_BAUD 115200
|
||||||
#define IMU_REPORT_INTERVAL_US 20000
|
#define IMU_REPORT_INTERVAL_US 20000
|
||||||
#define TELEMETRY_INTERVAL_MS 200
|
#define TELEMETRY_INTERVAL_MS 200
|
||||||
|
|||||||
@@ -19,5 +19,6 @@ struct GpsState {
|
|||||||
uint32_t charactersProcessed = 0;
|
uint32_t charactersProcessed = 0;
|
||||||
uint32_t sentencesPassed = 0;
|
uint32_t sentencesPassed = 0;
|
||||||
uint32_t sentencesFailed = 0;
|
uint32_t sentencesFailed = 0;
|
||||||
|
uint32_t baud = 0;
|
||||||
unsigned long lastByteMs = 0;
|
unsigned long lastByteMs = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ def test_imu_scans_both_bno08x_i2c_addresses():
|
|||||||
assert "findBnoAddress()" in imu
|
assert "findBnoAddress()" in imu
|
||||||
assert "Wire.endTransmission()" in imu
|
assert "Wire.endTransmission()" in imu
|
||||||
|
|
||||||
|
def test_gps_auto_detects_common_nmea_baud_rates():
|
||||||
|
gps = source("gps.cpp")
|
||||||
|
assert "baudHasValidNmea" in gps
|
||||||
|
assert "{9600, 38400, 115200, 4800}" in gps
|
||||||
|
assert "passedChecksum() > 0" in gps
|
||||||
|
|
||||||
def test_node_does_not_take_cargo_or_ble_authority():
|
def test_node_does_not_take_cargo_or_ble_authority():
|
||||||
combined = "\n".join(p.read_text() for p in NODE.glob("*.*"))
|
combined = "\n".join(p.read_text() for p in NODE.glob("*.*"))
|
||||||
assert "NimBLE" not in combined and "JBD" not in combined and "server.on(" not in combined
|
assert "NimBLE" not in combined and "JBD" not in combined and "server.on(" not in combined
|
||||||
|
|||||||
Reference in New Issue
Block a user