Better TX congestion detection, don't stall on reading battery status

This commit is contained in:
2026-03-01 21:49:59 +01:00
parent 1bd2ecc339
commit 11baa814c9
2 changed files with 43 additions and 19 deletions

View File

@@ -110,9 +110,16 @@ float cachedTempC = 25.0f;
#ifdef FEATURE_IMU_STREAM
bool imuStreamEnabled = false;
uint32_t streamNotifyFails = 0; // notify() returned false (TX buffer full)
uint32_t streamNotifyFails = 0;
uint32_t streamNotifyOk = 0;
unsigned long lastStreamDiag = 0;
// Back-off state: after STREAM_BACKOFF_THRESH consecutive fails, skip notifies
// for STREAM_BACKOFF_MS to let the SoftDevice HVN TX semaphore drain.
// Without this, every notify() blocks for BLE_GENERIC_TIMEOUT (100ms).
uint8_t streamConsecFails = 0;
unsigned long streamBackoffUntil = 0;
const uint8_t STREAM_BACKOFF_THRESH = 2; // fails before backing off
const unsigned long STREAM_BACKOFF_MS = 500; // cooldown window
#endif
uint32_t loopStalls = 0; // loop iterations where dt > 20ms (behind schedule)
@@ -307,7 +314,9 @@ void loop() {
float dt = (now - lastTime) / 1000.0f;
lastTime = now;
if (dt <= 0.0f || dt > 0.5f) return;
if (dt > 0.020f) { loopStalls++; Serial.print("[STALL] dt="); Serial.print(dt*1000.f,1); Serial.print("ms stalls="); Serial.println(loopStalls); }
// Threshold 50ms: intentional heartbeat blink (30ms) won't false-trigger;
// real SoftDevice stalls (100ms+) and unexpected delays still get flagged.
if (dt > 0.050f) { loopStalls++; Serial.print("[STALL] dt="); Serial.print(dt*1000.f,1); Serial.print("ms stalls="); Serial.println(loopStalls); }
cachedTempC = readIMUTemp();
@@ -378,22 +387,33 @@ void loop() {
if (!safeMode && imuStreamEnabled && Bluefruit.connected()
&& (now - lastImuStream >= IMU_STREAM_RATE_MS)) {
lastImuStream = now;
ImuPacket pkt;
pkt.gyroY_mDPS = (int16_t)constrain(gy*(180.f/PI)*1000.f, -32000, 32000);
pkt.gyroZ_mDPS = (int16_t)constrain(gz*(180.f/PI)*1000.f, -32000, 32000);
pkt.accelX_mg = (int16_t)constrain(ax*1000.f, -32000, 32000);
pkt.accelY_mg = (int16_t)constrain(ay*1000.f, -32000, 32000);
pkt.accelZ_mg = (int16_t)constrain(az*1000.f, -32000, 32000);
pkt.moveX = moveX;
pkt.moveY = moveY;
pkt.flags = flags;
pkt._pad = 0;
if (cfgImuStream.notify((uint8_t*)&pkt, sizeof(pkt))) {
streamNotifyOk++;
if (now < streamBackoffUntil) {
// Backing off — host TX buffer congested, skip to avoid 100ms block
} else {
streamNotifyFails++;
Serial.print("[STREAM] notify fail #"); Serial.print(streamNotifyFails);
Serial.print(" ok="); Serial.println(streamNotifyOk);
ImuPacket pkt;
pkt.gyroY_mDPS = (int16_t)constrain(gy*(180.f/PI)*1000.f, -32000, 32000);
pkt.gyroZ_mDPS = (int16_t)constrain(gz*(180.f/PI)*1000.f, -32000, 32000);
pkt.accelX_mg = (int16_t)constrain(ax*1000.f, -32000, 32000);
pkt.accelY_mg = (int16_t)constrain(ay*1000.f, -32000, 32000);
pkt.accelZ_mg = (int16_t)constrain(az*1000.f, -32000, 32000);
pkt.moveX = moveX;
pkt.moveY = moveY;
pkt.flags = flags;
pkt._pad = 0;
if (cfgImuStream.notify((uint8_t*)&pkt, sizeof(pkt))) {
streamNotifyOk++;
streamConsecFails = 0;
} else {
streamNotifyFails++;
streamConsecFails++;
if (streamConsecFails >= STREAM_BACKOFF_THRESH) {
streamBackoffUntil = now + STREAM_BACKOFF_MS;
streamConsecFails = 0;
Serial.print("[STREAM] TX congested — backing off ");
Serial.print(STREAM_BACKOFF_MS); Serial.println("ms");
}
}
}
// Periodic stream health report every 10 seconds