diff --git a/air-mouse.ino b/air-mouse.ino index 1bc6f8f..09adacc 100644 --- a/air-mouse.ino +++ b/air-mouse.ino @@ -219,8 +219,7 @@ const float BATT_EMPTY = 3.00f; const float BATT_CRITICAL = 3.10f; #ifdef FEATURE_TAP_DETECTION - const unsigned long CLICK_HOLD_MS = 40; - const unsigned long DOUBLE_TAP_WINDOW_MS = 400; + const unsigned long CLICK_HOLD_MS = 60; #endif #ifdef FEATURE_TEMP_COMPENSATION const float TEMP_COMP_COEFF_DPS_C = 0.004f; @@ -237,10 +236,8 @@ float calTempC = 25.0f; float cachedTempC = 25.0f; #ifdef FEATURE_TAP_DETECTION - bool tapPending = false; bool clickButtonDown = false; uint8_t clickButton = 0; - unsigned long tapSeenMs = 0; unsigned long clickDownMs= 0; uint32_t statLeftClicks = 0; uint32_t statRightClicks = 0; @@ -293,43 +290,39 @@ float readIMUTemp() { void setupTapDetection() { imuWriteReg(REG_CTRL1_XL, 0x60); // ODR=416Hz, FS=±2g imuWriteReg(REG_TAP_CFG, 0x8E); // INT_EN + LIR + TAP_Z/Y/X - imuWriteReg(REG_TAP_THS_6D, 0x08); // threshold 500 mg - imuWriteReg(REG_INT_DUR2, 0x77); // DUR=7, QUIET=01, SHOCK=11 + imuWriteReg(REG_TAP_THS_6D, 0x0C); // threshold 750 mg (was 500 mg — too easy to false-trigger) + imuWriteReg(REG_INT_DUR2, 0x7A); // DUR=7(538ms), QUIET=2(19ms), SHOCK=2(38ms) imuWriteReg(REG_WAKE_UP_THS, 0x80); // enable double-tap imuWriteReg(REG_MD1_CFG, 0x48); // route taps to INT1 Serial.println("[TAP] Engine configured — single=LEFT, double=RIGHT"); } void processTaps(unsigned long now) { + // Release held button after CLICK_HOLD_MS if (clickButtonDown && (now - clickDownMs >= CLICK_HOLD_MS)) { blehid.mouseButtonPress(clickButton, false); clickButtonDown = false; clickButton = 0; } + if (clickButtonDown) return; // Don't start a new click while one is held + + // The LSM6DS3 (with D_TAP_EN) already disambiguates at hardware level: + // SINGLE_TAP is only set after the DUR window expires with no second tap. + // DOUBLE_TAP is set immediately when the second tap arrives within DUR. + // We trust this directly — no software delay needed. uint8_t tapSrc = imuReadReg(REG_TAP_SRC); - bool singleTap = (tapSrc & 0x20) != 0; - bool doubleTap = (tapSrc & 0x10) != 0; - bool tapEvent = (tapSrc & 0x40) != 0; - if (!tapEvent) { - if (tapPending && (now - tapSeenMs >= DOUBLE_TAP_WINDOW_MS)) { - tapPending = false; - if (!clickButtonDown) { - Serial.println("[TAP] Single → LEFT"); - blehid.mouseButtonPress(MOUSE_BUTTON_LEFT, true); - clickButton = MOUSE_BUTTON_LEFT; clickButtonDown = true; clickDownMs = now; - statLeftClicks++; - } - } - return; - } - if (doubleTap && !clickButtonDown) { - tapPending = false; + if (!(tapSrc & 0x40)) return; // TAP_IA not set — no event + + if (tapSrc & 0x10) { // DOUBLE_TAP → right click Serial.println("[TAP] Double → RIGHT"); blehid.mouseButtonPress(MOUSE_BUTTON_RIGHT, true); clickButton = MOUSE_BUTTON_RIGHT; clickButtonDown = true; clickDownMs = now; statRightClicks++; - return; + } else if (tapSrc & 0x20) { // SINGLE_TAP → left click + Serial.println("[TAP] Single → LEFT"); + blehid.mouseButtonPress(MOUSE_BUTTON_LEFT, true); + clickButton = MOUSE_BUTTON_LEFT; clickButtonDown = true; clickDownMs = now; + statLeftClicks++; } - if (singleTap && !tapPending && !clickButtonDown) { tapPending = true; tapSeenMs = now; } } #endif // FEATURE_TAP_DETECTION