From d1a5cfd4b43e689fe2bfbb4d1ee1bbdca8e04e04 Mon Sep 17 00:00:00 2001 From: jjangddu Date: Wed, 2 Sep 2026 17:05:08 +0900 Subject: [PATCH] =?UTF-8?q?fix(ble):=20=EC=A3=BC=ED=8C=8C=EC=88=98=C2=B7cy?= =?UTF-8?q?cle=20=EC=84=A4=EC=A0=95=EC=9D=80=20mpa=20=EA=B0=80=20=EC=95=84?= =?UTF-8?q?=EB=8B=88=EB=9D=BC=20mcs=20=E2=80=94=20=EC=95=B1=EC=9D=80=20?= =?UTF-8?q?=EC=97=AC=ED=83=9C=20=ED=95=9C=20=EB=B2=88=EB=8F=84=20=EC=95=88?= =?UTF-8?q?=20=EB=B0=94=EA=BE=B8=EA=B3=A0=20=EC=9E=88=EC=97=88=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 확인된 사실 (2026-09-02 펌웨어팀) 송신 주파수·cycle 설정 명령은 **`mcs?`** 다. `mpa?` 는 piezo power ON 이다. 이 앱은 여태 `mpa?` 에 [freq, cycles] 를 실어 보내며 그것이 주파수 설정이라고 가정하고 있었다(PlacementGuideView 의 `sendPiezoPowerOn()`, MeasurementService 의 `sendBurst(freqOption = 2, ...)`). `mcs` 는 코드에도 docs/BLE_PROTOCOL_REFERENCE.md 에도 **한 글자도 없다**. 즉 **지금까지 앱은 주파수·cycle 을 한 번도 바꾼 적이 없다.** 프로브 기본값으로만 측정해 온 셈이고, 그 사실을 아무도 몰랐다. 병원 임상 모드를 만들며 명령을 되짚다 드러났다. ## 고침 `BleManager.sendPiezoConfig(freqOption, cycles)` 를 추가하고 병원 임상 모드가 조합 진입마다 이것을 부른다. `sendPiezoPowerOn`(mpa)은 기존 호출부가 있어 그대로 둔다 — power ON 은 그 나름의 역할이 있을 수 있고, 확인 전에 건드리면 정렬 화면이 깨진다. 응답 태그는 `sendRaw` 가 m→r 로 바꿔 `rcs` 를 기다린다. 파서의 when 에 rcs 분기가 없어도 태그 처리가 when 밖에 있어 큐는 정상 해제된다(BleManager L1783). ## ⚠ 아직 확인 안 된 것 — 인자 구성 명령 **이름만** 확인됐다. 인자의 개수·순서·인코딩은 듣지 못해, 이 프로토콜의 다른 수치 명령과 같은 규약을 따른다고 **가정**했다: mcs? = 6D 63 73 3F | freq(BE 2B) | cycles(BE 2B) | CRC16-CCITT(LE 2B) 총 10 B (1,3) 6D 63 73 3F 00 01 00 03 42 64 (2,5) 6D 63 73 3F 00 02 00 05 D4 5D 값↔MHz 대응도 여전히 모른다. 파일에 실제 전송 정수를 남기는 안전장치는 그대로다. Co-Authored-By: Claude Opus 5 --- .../com/medithings/vesiscan/ble/BleManager.kt | 22 +++++++++++++++++++ .../ui/views/clinical/HospitalModeView.kt | 5 +++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/medithings/vesiscan/ble/BleManager.kt b/app/src/main/java/com/medithings/vesiscan/ble/BleManager.kt index 8ef1a59..18c6523 100644 --- a/app/src/main/java/com/medithings/vesiscan/ble/BleManager.kt +++ b/app/src/main/java/com/medithings/vesiscan/ble/BleManager.kt @@ -777,6 +777,28 @@ class BleManager private constructor(private val context: Context) { sendRaw(CRC16.buildCommandBE("mpa", intArrayOf(freqOption, cycles))) } + /** + * 송신 주파수 · cycle 설정 (`mcs?`). + * + * ## mpa 가 아니다 (2026-09-02 펌웨어팀 확인) + * 이 앱은 여태 `mpa?`(piezo power ON)에 [freq, cycles] 를 실어 보내고 있었고, 그것이 + * 주파수 설정이라고 코드가 가정하고 있었다. 실제 설정 명령은 **`mcs?`** 다. + * 즉 지금까지 앱은 주파수·cycle 을 **한 번도 바꾼 적이 없다** — 프로브 기본값으로만 + * 측정해 온 셈이다. + * + * ## ⚠ 인자 구성은 아직 확인 전이다 + * 명령 이름만 확인됐고, 인자의 개수·순서·인코딩은 듣지 못했다. 여기서는 이 프로토콜의 + * 다른 수치 명령과 같은 규약을 따른다고 **가정**한다: + * "mcs?" + freq(BE 2B) + cycles(BE 2B) + CRC16(LE 2B) = 10 B + * 그리고 값↔MHz 대응도 여전히 모른다(HospitalProtocol KDoc 참고). + * + * 확인되면 이 함수 한 곳만 고치면 된다. 응답 태그는 `sendRaw` 가 m→r 로 바꿔 + * `rcs` 를 기다린다 — 파서에 rcs 분기가 없어도 큐는 태그로 해제된다. + */ + fun sendPiezoConfig(freqOption: Int, cycles: Int) { + sendRaw(CRC16.buildCommandBE("mcs", intArrayOf(freqOption, cycles))) + } + fun sendPiezoStop() { sendRaw(CRC16.buildCommandASCII("mps", " ")) } diff --git a/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/HospitalModeView.kt b/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/HospitalModeView.kt index bc563c7..0218cd4 100644 --- a/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/HospitalModeView.kt +++ b/app/src/main/java/com/medithings/vesiscan/ui/views/clinical/HospitalModeView.kt @@ -10,7 +10,7 @@ * 다시 만들 수 없으므로, 그 자리에서 놓친 조합은 그날 데이터에서 영영 빈다. * * ## 측정 한 번의 흐름 - * sendPiezoPowerOn(freqOption, cycles) ← 조합 진입 시 1회 + * sendPiezoConfig(freqOption, cycles) ← 조합 진입 시 1회 (mcs?) * sendMtb() → piezoCollector.onComplete ← n회 반복 * * `sendMtb` 는 6채널+IMU 를 한 번에 받는 명령이고, 완료는 콜백으로 온다. 그래서 루프는 @@ -109,7 +109,8 @@ fun HospitalModeView(appState: AppState) { dir, patient, posture, fill, freq, cycle, startedAt) // 조합 진입 — 프로브에 주파수·cycle 을 실어 보낸다. - bleManager.sendPiezoPowerOn(freqOption = freq.freqOption, cycles = cycle.cycles) + // `mpa?`(power ON)가 아니라 `mcs?`(설정)다 — 2026-09-02 펌웨어팀 확인. + bleManager.sendPiezoConfig(freqOption = freq.freqOption, cycles = cycle.cycles) delay(COMBINATION_SETTLE_MS) var ok = 0; var fail = 0