diff --git a/air-mouse.ino b/air-mouse.ino index 0f6ac3d..c668688 100644 --- a/air-mouse.ino +++ b/air-mouse.ino @@ -211,6 +211,9 @@ const unsigned long TELEMETRY_MS = 1000; const unsigned long HEARTBEAT_MS = 2000; const int HEARTBEAT_DUR = 30; const unsigned long BOOT_SAFE_MS = 5000; +#ifdef FEATURE_IMU_STREAM + const unsigned long IMU_STREAM_RATE_MS = 50; // 20 Hz max — 100 Hz overwhelms BLE conn interval +#endif const float BATT_FULL = 4.20f; const float BATT_EMPTY = 3.00f; const float BATT_CRITICAL = 3.10f; @@ -259,6 +262,9 @@ unsigned long lastBattTime = 0; unsigned long lastHeartbeat = 0; unsigned long lastTelemetry = 0; unsigned long bootStartMs = 0; +#ifdef FEATURE_IMU_STREAM + unsigned long lastImuStream = 0; +#endif #ifdef FEATURE_TELEMETRY uint16_t statRecalCount = 0; @@ -601,7 +607,7 @@ void setup() { Bluefruit.begin(1, 0); Bluefruit.setTxPower(4); Bluefruit.setName(safeMode ? "IMU Mouse (safe)" : "IMU Mouse"); - Bluefruit.Periph.setConnInterval(6, 12); + Bluefruit.Periph.setConnInterval(12, 24); // 15-30ms — less aggressive, prevents stream disconnect Wire1.begin(); // LSM6DS3 is on internal I2C bus (Wire1), must init before imu.begin() if (imu.begin() != 0) { @@ -643,30 +649,14 @@ void setup() { startAdvertising(); Serial.print("[OK] Advertising — features:"); - #ifdef FEATURE_CONFIG_SERVICE - Serial.print(" CFG"); - #endif - #ifdef FEATURE_TELEMETRY - Serial.print(" TELEM"); - #endif - #ifdef FEATURE_IMU_STREAM - Serial.print(" STREAM"); - #endif - #ifdef FEATURE_TAP_DETECTION - Serial.print(" TAP"); - #endif - #ifdef FEATURE_TEMP_COMPENSATION - Serial.print(" TEMPCOMP"); - #endif - #ifdef FEATURE_AUTO_RECAL - Serial.print(" AUTORECAL"); - #endif - #ifdef FEATURE_BATTERY_MONITOR - Serial.print(" BATT"); - #endif - #ifdef FEATURE_BOOT_LOOP_DETECT - Serial.print(" BOOTDET"); - #endif + #ifdef FEATURE_CONFIG_SERVICE Serial.print(" CFG"); #endif + #ifdef FEATURE_TELEMETRY Serial.print(" TELEM"); #endif + #ifdef FEATURE_IMU_STREAM Serial.print(" STREAM"); #endif + #ifdef FEATURE_TAP_DETECTION Serial.print(" TAP"); #endif + #ifdef FEATURE_TEMP_COMPENSATION Serial.print(" TEMPCOMP"); #endif + #ifdef FEATURE_AUTO_RECAL Serial.print(" AUTORECAL"); #endif + #ifdef FEATURE_BATTERY_MONITOR Serial.print(" BATT"); #endif + #ifdef FEATURE_BOOT_LOOP_DETECT Serial.print(" BOOTDET"); #endif Serial.println(); bootStartMs = millis(); @@ -771,7 +761,9 @@ void loop() { } #ifdef FEATURE_IMU_STREAM - if (!safeMode && imuStreamEnabled && Bluefruit.connected()) { + 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);