fix: Endian 감지 간헐적 실패 수정 (19회 중 5회 ADC 값 폭발)

근본 원인: CH0 첫 샘플이 LE/BE 둘 다 4095 이하일 때
  감지 불가 → LE로 잘못 판정 → 전체 채널 값 폭발 (30000~65000)

수정:
- 확실한 경우: 기존 로직 유지 (LE>4095→BE, BE>4095→LE)
- 애매한 경우: forceBigEndian 기본값 사용
- VBT* 기기: forceBigEndian=true (기기 연결 시 자동 설정)
- 2025MEDIP: forceBigEndian=false
- Endian 결정 로그 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-27 12:09:57 +09:00
parent 7125e79fb9
commit fecb02dfde
2 changed files with 15 additions and 5 deletions
@@ -613,9 +613,10 @@ class BleManager private constructor(private val context: Context) {
if (idx >= 0) discoveredDevices[idx] = discoveredDevices[idx].copy(isConnected = true, isConnecting = false) if (idx >= 0) discoveredDevices[idx] = discoveredDevices[idx].copy(isConnected = true, isConnecting = false)
isConnected.value = true isConnected.value = true
connectedDeviceName.value = try { gatt.device.name ?: "Unknown" } catch (_: Exception) { "Unknown" } connectedDeviceName.value = try { gatt.device.name ?: "Unknown" } catch (_: Exception) { "Unknown" }
// Auto-detect device preset from name // Auto-detect device preset + endian from name
com.example.medilightv2android.managers.PiezoHW.autoDetectPreset(connectedDeviceName.value) com.example.medilightv2android.managers.PiezoHW.autoDetectPreset(connectedDeviceName.value)
logd { "Device preset: ${com.example.medilightv2android.managers.PiezoHW.presetName} (from '${connectedDeviceName.value}')" } piezoCollector.forceBigEndian = connectedDeviceName.value.startsWith("VBT")
logd { "Device preset: ${com.example.medilightv2android.managers.PiezoHW.presetName}, endian: ${if (piezoCollector.forceBigEndian) "BE" else "LE"} (from '${connectedDeviceName.value}')" }
lastConnectedAddress = gatt.device.address lastConnectedAddress = gatt.device.address
reconnectAttempt = 0 reconnectAttempt = 0
@@ -24,6 +24,7 @@ class PiezoPacketCollector {
private var rawData = mutableListOf<Byte>() private var rawData = mutableListOf<Byte>()
private var hasFirstPacket = false private var hasFirstPacket = false
private var detectedBigEndian = false private var detectedBigEndian = false
var forceBigEndian: Boolean = true // VBT 기기 기본 BE, 기기 연결 시 설정
// Multi-channel // Multi-channel
var isMultiChannel: Boolean = false; private set var isMultiChannel: Boolean = false; private set
@@ -87,13 +88,21 @@ class PiezoPacketCollector {
hasFirstPacket = true hasFirstPacket = true
rawData.clear() rawData.clear()
// Endian detection: first channel only → lock for remaining // Endian detection: first channel → lock for remaining
if (currentChannel == 0 || !hasFirstPacket) { // VBT 기기 = Big Endian, 2025MEDIP = Little Endian
// 자동 감지 fallback: 첫 샘플 기반
if (currentChannel == 0) {
val b6 = bytes.getOrElse(6) { 0 }.toInt() and 0xFF val b6 = bytes.getOrElse(6) { 0 }.toInt() and 0xFF
val b7 = bytes.getOrElse(7) { 0 }.toInt() and 0xFF val b7 = bytes.getOrElse(7) { 0 }.toInt() and 0xFF
val firstSampleLE = b6 or (b7 shl 8) val firstSampleLE = b6 or (b7 shl 8)
val firstSampleBE = (b6 shl 8) or b7 val firstSampleBE = (b6 shl 8) or b7
detectedBigEndian = firstSampleLE > 4095 && firstSampleBE <= 4095
detectedBigEndian = when {
firstSampleLE > 4095 && firstSampleBE <= 4095 -> true // 확실히 BE
firstSampleBE > 4095 && firstSampleLE <= 4095 -> false // 확실히 LE
else -> forceBigEndian // 둘 다 범위 내면 기기 기반 기본값 사용
}
onLog?.invoke("Endian: ${if (detectedBigEndian) "BE" else "LE"} (LE=$firstSampleLE BE=$firstSampleBE force=$forceBigEndian)")
} }
// Parse repeat count // Parse repeat count