diff --git a/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt b/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt index dfd5f61..3958efb 100644 --- a/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt +++ b/app/src/main/java/com/example/medilightv2android/ble/BleManager.kt @@ -457,8 +457,11 @@ class BleManager private constructor(private val context: Context) { /** * 6채널 측정 명령(maa) 송신 가능 여부: * (A) 이전 응답이 아직 진행 중(isMultiChannel && !isComplete)이면 차단. - * 단 5초 넘게 응답이 안 오면 강제 통과(영영 deadlock 방지). - * (B) 마지막 송신으로부터 1500ms 미만이면 차단(펌웨어 burst 방어). + * 단 3초 넘게 응답이 안 오면 강제 통과(영영 deadlock 방지). + * (B) 마지막 송신으로부터 600ms 미만이면 차단(펌웨어 burst 방어). + * + * FW VBTFW0116 + MTU 247 + CONN_PRIORITY HIGH 조합에서 한 사이클 응답이 + * 약 280~420ms이므로, 600ms = 응답 평균 + 안전 마진 ~200ms. */ private var lastMaaSentMs = 0L private fun canSendMaa(caller: String): Boolean { @@ -466,13 +469,13 @@ class BleManager private constructor(private val context: Context) { val collectorBusy = piezoCollector.isMultiChannel && !piezoCollector.isComplete val sinceLast = now - lastMaaSentMs if (collectorBusy) { - if (sinceLast < 5000) { + if (sinceLast < 3000) { android.util.Log.w("BleManager", "maa BUSY [$caller] — prev response in progress (${sinceLast}ms)") return false } android.util.Log.w("BleManager", "maa FORCE [$caller] — prev incomplete after ${sinceLast}ms, abandoning") } - if (sinceLast < 1500) { + if (sinceLast < 600) { android.util.Log.w("BleManager", "maa THROTTLED [$caller] — ${sinceLast}ms since last") return false } diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt index aeb1cf5..c92664b 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt @@ -531,8 +531,9 @@ fun PiezoMonitoringView(appState: AppState) { autoVolumeWindow.clear() } - // Auto-measure: 측정 완료 대기 + 최소 800ms 간격 보장 - // 10개 모이면 trimmed mean (최대/최소 제외 8개 평균) + // Auto-measure: 측정 완료 대기 + 최소 간격 보장 + // FW VBTFW0116 + MTU 247 + CONN_PRIORITY HIGH 조합에서 응답 ~330ms. + // BleManager throttle 600ms와 동기화해 사이클당 ~0.6~0.7s로 회전. LaunchedEffect(isAutoMeasuring) { if (isAutoMeasuring) { while (isAutoMeasuring) { @@ -543,9 +544,8 @@ fun PiezoMonitoringView(appState: AppState) { kotlinx.coroutines.delay(100) } autoTickCount++ - // 최소 1500ms 간격 보장 (기기 연속 maa 채널 드롭 방지) val elapsed = System.currentTimeMillis() - measureStartMs - val remaining = 1500L - elapsed + val remaining = 600L - elapsed if (remaining > 0) kotlinx.coroutines.delay(remaining) } kotlinx.coroutines.delay(50) diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt index 78ef234..0fbf727 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PlacementGuideView.kt @@ -778,12 +778,14 @@ fun PlacementGuideView(appState: AppState) { } } - // Continuous scan loop (1초 간격) — LED는 스캔 콜백에서 동적 제어 + // Continuous scan loop (600ms 간격) — LED는 스캔 콜백에서 동적 제어 + // FW VBTFW0116 + MTU 247 + CONN_PRIORITY HIGH에서 응답 ~330ms이므로 + // BleManager throttle 600ms와 동기화. LaunchedEffect(isContinuousMode) { if (isContinuousMode) { performScan() while (isContinuousMode) { - kotlinx.coroutines.delay(1000) + kotlinx.coroutines.delay(600) if (isContinuousMode && !isScanning) performScan() } bleManager.sendLedMode(0) // OFF on stop