diff --git a/app/src/main/java/com/ismart/ib86/app/MainActivity.java b/app/src/main/java/com/ismart/ib86/app/MainActivity.java index 5f3bf62..55737b9 100644 --- a/app/src/main/java/com/ismart/ib86/app/MainActivity.java +++ b/app/src/main/java/com/ismart/ib86/app/MainActivity.java @@ -172,10 +172,22 @@ public class MainActivity extends AppCompatActivity { @Override public void onAlgoResultReceived(ASR5515Protocol.AlgoResultResponse response) { LogManager.d(TAG, "算法结果: " + response.toString()); - // 在这里处理心率结果 - if (response.heartRate > 0) { - LogManager.d(TAG, "心率值: " + response.heartRate); + + // 根据类型处理不同的算法结果 + if (response.type == ASR5515Protocol.AlgoResultResponse.TYPE_HEART_RATE) { + // 处理心率结果 + LogManager.d(TAG, "心率值: " + response.getHeartRate()); + // LogManager.d(TAG, "信噪比: " + response.getSignalNoiseRatio()); + LogManager.d(TAG, "置信度: " + response.getConfidence() + "%"); // 可以在这里更新UI或进行其他操作 + } else if (response.type == ASR5515Protocol.AlgoResultResponse.TYPE_SPO2) { + // 处理血氧结果 + if (response.getSpo2() > 0) { + LogManager.d(TAG, "血氧值: " + response.getSpo2() + "%"); + LogManager.d(TAG, "R值: " + response.getRValue()); + LogManager.d(TAG, "置信度: " + response.getConfidence() + "%"); + // 可以在这里更新UI或进行其他操作 + } } } }); @@ -198,11 +210,12 @@ public class MainActivity extends AppCompatActivity { // deviceManager.queryBtVersion(); // } // }, 2000); - deviceManager.stopGH3220Measure((byte) 0x02); + deviceManager.stopGH3220Measure(ASR5515Protocol.GH3220MeasureType.HR); + deviceManager.stopGH3220Measure(ASR5515Protocol.GH3220MeasureType.SPO2); handler.postDelayed(new Runnable() { @Override public void run() { - deviceManager.startGH3220Measure((byte) 0x02); + deviceManager.startGH3220Measure(ASR5515Protocol.GH3220MeasureType.SPO2); } }, 1000); diff --git a/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/ASR5515DeviceManager.java b/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/ASR5515DeviceManager.java index ba83a9c..76860d8 100644 --- a/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/ASR5515DeviceManager.java +++ b/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/ASR5515DeviceManager.java @@ -88,8 +88,10 @@ public class ASR5515DeviceManager { */ public interface AlgoResultListener { /** - * 接收到心率算法结果 - * @param response 心率结果响应 + * 接收到算法结果(心率或血氧) + * @param response 算法结果响应,可以通过response.type判断是心率还是血氧数据 + * 当type为TYPE_HEART_RATE时,使用getHeartRate()和getSignalNoiseRatio()获取心率相关数据 + * 当type为TYPE_SPO2时,使用getSpo2()、getRValue()获取血氧相关数据 */ void onAlgoResultReceived(ASR5515Protocol.AlgoResultResponse response); } diff --git a/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/ASR5515Protocol.java b/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/ASR5515Protocol.java index 2d9e041..7e323df 100644 --- a/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/ASR5515Protocol.java +++ b/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/ASR5515Protocol.java @@ -217,6 +217,7 @@ public class ASR5515Protocol { public static final short CMD_GH3220_MEASURE_STOP = 0x01F7; // GH3220停止测量 [503 0 len type] public static final short CMD_GH3220_MEASURE_STOP_RESP = 0x01F8; // GH3220停止测量响应 [504 sn len status] public static final short CMD_ALGO_RESULT = 0x01FE; // 主动上报算法结果(心率) [510 sn len AlgoResult] + public static final short CMD_SPO2_RESULT = 0x0200; // 主动上报算法结果(血氧) [512 sn len AlgoResult] } public static class Frame { @@ -710,51 +711,140 @@ public class ASR5515Protocol { return new GH3220MeasureResponse(frame.data[0], frame.data[1], frame.data[2]); } - // 算法结果响应类 [510 sn len AlgoResult] + // 算法结果响应类 [510/512 sn len AlgoResult] public static class AlgoResultResponse { - public int heartRate; // 心率值 (snResult[0]) - public int confidence; // 置信度 (snResult[1]) - public int signalNoiseRatio; // 信噪比 (snResult[2]) + public static final int TYPE_HEART_RATE = 0; // 心率类型 + public static final int TYPE_SPO2 = 1; // 血氧类型 + + public int type; // 算法类型:0-心率,1-血氧 + public int value; // 主要值(心率值或血氧值) + public int confidence; // 置信度 + public int signalQuality; // 信号质量(心率为信噪比,血氧为R值) + public int confidenceLevel; // 置信等级(仅用于血氧,范围-2到5) - public AlgoResultResponse(int heartRate, int confidence, int signalNoiseRatio) { - this.heartRate = heartRate; + public AlgoResultResponse(int type, int value, int confidence, int signalQuality, int confidenceLevel) { + this.type = type; + this.value = value; this.confidence = confidence; - this.signalNoiseRatio = signalNoiseRatio; + this.signalQuality = signalQuality; + this.confidenceLevel = confidenceLevel; + } + + // 获取心率值(仅当type为TYPE_HEART_RATE时有效) + public int getHeartRate() { + return type == TYPE_HEART_RATE ? value : 0; + } + + // 获取信噪比(仅当type为TYPE_HEART_RATE时有效) + public int getSignalNoiseRatio() { + return type == TYPE_HEART_RATE ? signalQuality : 0; + } + + // 获取血氧值(仅当type为TYPE_SPO2时有效) + public int getSpo2() { + return type == TYPE_SPO2 ? value : 0; + } + + // 获取R值(仅当type为TYPE_SPO2时有效) + public int getRValue() { + return type == TYPE_SPO2 ? signalQuality : 0; + } + + // 获取置信度 + public int getConfidence() { + return confidence; } @Override public String toString() { - return "AlgoResultResponse{" + - ", heartRate=" + heartRate + - ", confidence=" + confidence + - ", signalNoiseRatio=" + signalNoiseRatio + - '}'; + if (type == TYPE_HEART_RATE) { + return "AlgoResultResponse{" + + "type=HeartRate" + + ", heartRate=" + value + + ", confidence=" + confidence + + ", signalNoiseRatio=" + signalQuality + + '}'; + } else { + return "AlgoResultResponse{" + + "type=SpO2" + + ", spo2=" + value + + ", confidence=" + confidence + + ", rValue=" + signalQuality + + ", confidenceLevel=" + confidenceLevel + + '}'; + } } } - // 解析算法结果响应帧 [updateFlag resultNum resultBit(2byte) heartRate(4) confidence(4) signalNoiseRatio(4)] + // 解析算法结果响应帧 [updateFlag resultNum resultBit(2byte) value(4) confidence(4) signalQuality(4) confidenceLevel(4)] public static AlgoResultResponse parseAlgoResultResponse(Frame frame) { - if (frame == null || frame.command != Commands.CMD_ALGO_RESULT || frame.data.length < 4) { + if (frame == null || frame.data.length < 4) { return null; } try { - // 解析心率值,只取第一个字节 - int heartRate = frame.data[4]; + // 根据命令类型确定是心率还是血氧 + int type = (frame.command == Commands.CMD_ALGO_RESULT) ? + AlgoResultResponse.TYPE_HEART_RATE : AlgoResultResponse.TYPE_SPO2; + // 解析主要值(心率或血氧),只取第一个字节 + // int value = frame.data[4]; + int value = (frame.data[7] & 0xFF) << 24 | + (frame.data[6] & 0xFF) << 16 | + (frame.data[5] & 0xFF) << 8 | + (frame.data[4] & 0xFF); + int confidence = 0; - int signalNoiseRatio = 0; + int signalQuality = 0; // 信噪比或R值 + int confidenceLevel = 0; // 血氧的置信等级 // 如果数据长度足够,解析置信度,只取第一个字节 - if (frame.data.length >= 8) { - confidence = frame.data[8]; + if (frame.data.length >= 12) { + if(type == AlgoResultResponse.TYPE_SPO2) + { + //R值 + signalQuality = (frame.data[11] & 0xFF) << 24 | + (frame.data[10] & 0xFF) << 16 | + (frame.data[9] & 0xFF) << 8 | + (frame.data[8] & 0xFF); + }else{ + confidence = (frame.data[11] & 0xFF) << 24 | + (frame.data[10] & 0xFF) << 16 | + (frame.data[9] & 0xFF) << 8 | + (frame.data[8] & 0xFF); + } + } - // 如果数据长度足够,解析信噪比,只取第一个字节 + // 如果数据长度足够,解析信号质量,只取第一个字节 if (frame.data.length >= 16) { - signalNoiseRatio = frame.data[16]; + if(type == AlgoResultResponse.TYPE_SPO2) + { + //置信度 + confidence = (frame.data[15] & 0xFF) << 24 | + (frame.data[14] & 0xFF) << 16 | + (frame.data[13] & 0xFF) << 8 | + (frame.data[12] & 0xFF); + }else{ + signalQuality = (frame.data[15] & 0xFF) << 24 | + (frame.data[14] & 0xFF) << 16 | + (frame.data[13] & 0xFF) << 8 | + (frame.data[12] & 0xFF); + } } - return new AlgoResultResponse(heartRate, confidence, signalNoiseRatio); + + // 如果是血氧数据且数据长度足够,解析置信等级 + if (type == AlgoResultResponse.TYPE_SPO2 && frame.data.length >= 20) { + confidenceLevel = (frame.data[19] & 0xFF) << 24 | + (frame.data[18] & 0xFF) << 16 | + (frame.data[17] & 0xFF) << 8 | + (frame.data[16] & 0xFF); + } + + LogManager.d(TAG, "Parse algo result - type: " + (type == AlgoResultResponse.TYPE_HEART_RATE ? "HeartRate" : "SpO2") + + ", value: " + value + ", confidence: " + confidence); + + return new AlgoResultResponse(type, value, confidence, signalQuality, confidenceLevel); } catch (Exception e) { LogManager.e(TAG, "Parse algo result error: " + e.getMessage()); return null; diff --git a/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/SerialPortHelper.java b/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/SerialPortHelper.java index 22e5993..408a00c 100644 --- a/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/SerialPortHelper.java +++ b/app/src/main/java/com/ismart/ib86/feature/serial/SerialPort/SerialPortHelper.java @@ -113,8 +113,10 @@ public class SerialPortHelper { */ public interface AlgoResultCallback { /** - * 接收到心率算法结果 - * @param response 心率结果响应 + * 接收到算法结果(心率或血氧) + * @param response 算法结果响应,可以通过response.type判断是心率还是血氧数据 + * 当type为TYPE_HEART_RATE时,使用getHeartRate()和getSignalNoiseRatio()获取心率相关数据 + * 当type为TYPE_SPO2时,使用getSpo2()、getRValue()获取血氧相关数据 */ void onAlgoResultReceived(ASR5515Protocol.AlgoResultResponse response); } @@ -549,7 +551,6 @@ public class SerialPortHelper { if (receiveCallback != null) { receiveCallback.onDataReceived(frame.command, frame.data); } - LogManager.d(TAG,"CMD TYPE:"+frame.command); // 处理特定类型的响应 switch (frame.command) { case ASR5515Protocol.Commands.CMD_CHECK_DEVICE_RESP: @@ -650,6 +651,7 @@ public class SerialPortHelper { break; case ASR5515Protocol.Commands.CMD_ALGO_RESULT: + case ASR5515Protocol.Commands.CMD_SPO2_RESULT: ASR5515Protocol.AlgoResultResponse algoResultResponse = ASR5515Protocol.parseAlgoResultResponse(frame); if (algoResultResponse != null && algoResultCallback != null) { algoResultCallback.onAlgoResultReceived(algoResultResponse);