firmware: prevent RS485 echo starvation

This commit is contained in:
2026-07-17 02:44:47 -06:00
parent 4f96902068
commit 75845a18e3
3 changed files with 26 additions and 3 deletions
@@ -5,6 +5,7 @@
namespace {
String commandBuffer;
bool discardCommandUntilNewline = false;
void sendJson(HardwareSerial& serial, JsonDocument& doc) {
digitalWrite(RS485_DE_PIN, HIGH); delayMicroseconds(20);
serializeJson(doc, serial); serial.write('\n'); serial.flush();
@@ -63,12 +64,25 @@ void publishCalibrationResult(HardwareSerial& serial, const String& result) {
}
void pollRs485Commands(HardwareSerial& serial, const ImuState& imu) {
while (serial.available()) {
// Bound RX work so an electrically echoed or noisy bus cannot starve sensors.
int bytesRemaining = RS485_COMMAND_MAX_LENGTH * 2;
while (serial.available() && bytesRemaining-- > 0) {
char c = serial.read();
if (c == '\r') continue;
if (c != '\n') {
if (commandBuffer.length() < RS485_COMMAND_MAX_LENGTH) commandBuffer += c;
else commandBuffer = "";
if (discardCommandUntilNewline) continue;
if (commandBuffer.length() < RS485_COMMAND_MAX_LENGTH) {
commandBuffer += c;
} else {
commandBuffer = "";
discardCommandUntilNewline = true;
}
continue;
}
if (discardCommandUntilNewline) {
discardCommandUntilNewline = false;
commandBuffer = "";
continue;
}
@@ -77,6 +91,8 @@ void pollRs485Commands(HardwareSerial& serial, const ImuState& imu) {
commandBuffer = "";
if (error) { publishCalibrationResult(serial, "invalid_json"); continue; }
String type = request["type"] | "";
// Some RS485 boards echo transmitted frames into RX. Ignore our own output.
if (type == "sensor_status" || type == "calibration_response") continue;
if (type == "calibrate_level") {
publishCalibrationResult(serial, startLevelCalibration(imu) ? "started" : "imu_unavailable");
} else if (type == "clear_level_calibration") {