You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解析Nonin 3231血氧仪USB串口数据获取SpO2与心率?

解析Nonin Pulse Oximeter 3231的串口血氧/心率数据

协议核心说明

Nonin 3231采用9位串口传输,第9位作为帧标志:1表示帧起始/结束,0表示有效数据。数据帧以0x14(ENQ,第9位为1)开头,随后是两个8位数据字节(第9位为0,分别对应SpO2和心率),最后以0x03(ETX,第9位为1)结束。

解析步骤

  1. 识别帧起始标志:筛选出第9位为1且字节值为0x14的单元;
  2. 读取后续两个数据单元:直接取低8位数值作为SpO2(有效范围70-100)和心率(有效范围20-250);
  3. 验证帧尾:确认后续单元为第9位1且字节值0x03的ETX,确保帧完整。

修改后的Python解析代码

import serial

# 初始化串口,严格匹配设备参数
s = serial.Serial(
    port="/dev/cu.usbmodem5055968061",
    baudrate=9600,
    bytesize=serial.NINEBITS,
    stopbits=serial.STOPBITS_ONE,
    parity=serial.PARITY_NONE
)

try:
    while True:
        # 读取单个9位数据单元(返回字节,需转换为整数)
        raw_unit = s.read()
        if not raw_unit:
            continue
        
        data_val = ord(raw_unit)
        ninth_bit = (data_val >> 8) & 1
        byte_data = data_val & 0xFF

        # 检测帧起始(ENQ标志)
        if ninth_bit == 1 and byte_data == 0x14:
            # 读取SpO2数据
            spo2_raw = s.read()
            spo2 = ord(spo2_raw) & 0xFF
            # 读取心率数据
            hr_raw = s.read()
            hr = ord(hr_raw) & 0xFF
            # 读取并验证帧尾(ETX标志)
            etx_raw = s.read()
            etx_val = ord(etx_raw)
            if (etx_val >> 8) & 1 == 1 and (etx_val & 0xFF) == 0x03:
                # 输出有效数据(过滤异常值)
                if 70 <= spo2 <= 100 and 20 <= hr <= 250:
                    print(f"SpO2: {spo2}%, 心率: {hr} bpm")
except KeyboardInterrupt:
    s.close()
    print("串口已关闭")

常见问题处理

  • 若未读取到有效数据:尝试在串口初始化后发送s.write(b'\x15')(ACK命令),触发设备输出实时数据;
  • 数值异常:大概率是帧同步错误,可增加帧起始的重试逻辑,跳过无效字节直到找到正确的ENQ标志;
  • 串口连接失败:检查设备路径是否正确,确保无其他进程占用串口。

内容的提问来源于stack exchange,提问作者Sylvia M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 03:07:52