第四章:数据采集协议解析:串口通信(RS232/RS485)基础、Modbus RTU协议详解、如何从呼吸机读取实时数据帧
各位同学,欢迎来到第四章。这一章,我们要啃一块硬骨头——数据采集协议。说白了,就是搞明白呼吸机到底是怎么把数据“说”出来的,而我们又该怎么“听懂”。
我刚开始做呼吸机数据采集那会儿,最头疼的就是这个环节。设备接上了,灯也亮了,但就是读不到数据。后来才发现,不是协议没配对,就是字节顺序搞反了。嗯,这些坑,今天咱们一个一个填上。
4.1 串口通信基础:RS232 与 RS485
呼吸机这类医疗设备,最常用的通信接口就是串口。别被 RS232、RS485 这些名字吓到,它们本质上就是两种不同的“说话方式”。
4.1.1 RS232:点对点的老将
RS232 是最经典的串口标准。它的特点是:
- 传输距离短:一般不超过 15 米。我在医院机房调试时,经常得把电脑搬到呼吸机旁边,就是因为线长了信号就飘。
- 速率不高:常见的是 9600、19200、115200 bps。呼吸机数据量不大,9600 就够用。
- 信号电平:用 ±12V 表示逻辑 0 和 1。所以不能直接连单片机,得用 MAX232 这类芯片转换。
- 全双工:可以同时收发数据。
关键参数速查表
| 参数 | RS232 | RS485 |
|---|---|---|
| 传输方式 | 单端 | 差分 |
| 最大距离 | 约15米 | 1200米 |
| 最大节点数 | 1对1 | 最多256个 |
| 常用速率 | 9600-115200 | 9600-115200 |
| 抗干扰能力 | 弱 | 强 |
4.1.2 RS485:远距离多节点的利器
RS485 就厉害多了。它用差分信号传输,抗干扰能力特别强。我在一个 ICU 项目中,呼吸机放在病房,采集主机放在护士站,中间隔了 50 多米,用的就是 RS485。
RS485 的几个要点:
- 半双工:同一时间只能发或收。需要程序控制收发切换。
- 总线拓扑:所有设备挂在一根总线上。注意要加终端电阻,一般是 120Ω。
- 地址寻址:每个设备有唯一地址。主机轮询,从机应答。
我的经验:RS485 布线时,一定要用双绞线。我见过有人用普通平行线,结果 20 米外数据全是错的。还有,屏蔽层单端接地,别两头都接,否则会形成地环路。
4.2 Modbus RTU 协议详解
Modbus 是工业领域最通用的协议之一。呼吸机厂商也特别喜欢用 Modbus RTU。为什么?因为它简单、可靠、占用资源少。
4.2.1 协议帧结构
Modbus RTU 的每一帧数据,就像一封信。结构如下:
| 地址码 (1字节) | 功能码 (1字节) | 数据区 (N字节) | CRC校验 (2字节) |
举个例子,读取呼吸机当前潮气量:
- 地址码:0x01(呼吸机地址)
- 功能码:0x03(读取保持寄存器)
- 数据区:起始地址 + 读取数量
- CRC:循环冗余校验,保证数据没被干扰
常见功能码
| 功能码 | 含义 | 用途 |
|---|---|---|
| 0x01 | 读取线圈状态 | 读取开关量 |
| 0x02 | 读取离散输入 | 读取状态位 |
| 0x03 | 读取保持寄存器 | 读取模拟量(最常用) |
| 0x04 | 读取输入寄存器 | 读取只读参数 |
| 0x06 | 写单个寄存器 | 设置参数 |
| 0x10 | 写多个寄存器 | 批量设置 |
4.2.2 数据模型与寄存器映射
呼吸机里的数据,都映射到 Modbus 的寄存器空间。比如:
- 寄存器 0x0000:潮气量(单位 mL)
- 寄存器 0x0001:呼吸频率(单位 次/分)
- 寄存器 0x0002:气道压力(单位 cmH₂O)
- 寄存器 0x0003:氧浓度(单位 %)
每个寄存器是 16 位(2 字节)。如果数据超过 16 位,比如 32 位的累计值,就会占用连续两个寄存器。
注意字节序:Modbus RTU 默认是大端模式(Big-Endian),即高字节在前。但有些呼吸机厂商会改成小端。我曾经被这个坑过——读出来的潮气量是 65535,后来才发现是字节序反了。
4.3 实战:从呼吸机读取实时数据帧
理论讲完了,咱们来点实际的。下面是我写的一个 Python 示例,演示如何通过串口读取呼吸机的实时数据。
4.3.1 准备工作
你需要:
- 一台支持 Modbus RTU 的呼吸机(或模拟器)
- USB 转 RS232/RS485 转换器
- Python 环境 + pymodbus 库
安装 pymodbus:
pip install pymodbus
4.3.2 读取潮气量和呼吸频率
from pymodbus.client import ModbusSerialClient
# 初始化串口客户端
client = ModbusSerialClient(
method='rtu',
port='COM3', # 根据实际情况修改
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
timeout=1
)
# 连接设备
if client.connect():
print("连接成功!")
# 读取保持寄存器,从地址0开始,读2个寄存器
result = client.read_holding_registers(
address=0,
count=2,
slave=1
)
if not result.isError():
tidal_volume = result.registers[0] # 潮气量
resp_rate = result.registers[1] # 呼吸频率
print(f"潮气量: {tidal_volume} mL")
print(f"呼吸频率: {resp_rate} 次/分")
else:
print("读取失败:", result)
client.close()
else:
print("连接失败,请检查串口设置")
4.3.3 连续采集与数据解析
实际项目中,我们需要连续采集。我习惯用一个循环,每秒读一次:
import time
import struct
def parse_ventilator_data(registers):
"""解析呼吸机数据帧"""
data = {}
# 假设寄存器映射如下:
# 0: 潮气量 (uint16)
# 1: 呼吸频率 (uint16)
# 2-3: 累计通气量 (uint32, 大端)
data['tidal_volume'] = registers[0]
data['resp_rate'] = registers[1]
# 解析32位值
combined = (registers[2] << 16) | registers[3]
data['total_volume'] = combined
return data
# 连续采集
client = ModbusSerialClient(method='rtu', port='COM3', baudrate=9600)
client.connect()
try:
while True:
result = client.read_holding_registers(0, 4, slave=1)
if not result.isError():
data = parse_ventilator_data(result.registers)
print(f"时间: {time.strftime('%H:%M:%S')}, "
f"潮气量: {data['tidal_volume']} mL, "
f"呼吸频率: {data['resp_rate']} bpm, "
f"累计通气量: {data['total_volume']} L")
time.sleep(1)
except KeyboardInterrupt:
print("采集停止")
finally:
client.close()
避坑指南:我曾经遇到一个情况,呼吸机每隔 5 秒才更新一次寄存器。我每秒读一次,读到的全是旧数据。后来加了时间戳比对,才发现这个问题。建议先读几次,观察数据变化规律。
4.4 常见问题与调试技巧
做串口通信,难免遇到问题。我总结了几条经验:
- 先确认物理连接:用示波器或逻辑分析仪看 TX/RX 引脚有没有波形。没有波形,说明硬件没通。
- 用串口助手验证:先用 SSCOM 或 Putty 发一条 Modbus 命令,看呼吸机有没有回复。能回复,说明协议没问题。
- 检查 CRC 校验:很多问题出在 CRC 计算错误。可以用在线 CRC 计算器验证。
- 注意超时时间:呼吸机响应时间可能比较慢,我一般设 500ms 到 1s 的超时。
- 日志记录:把原始数据帧打印出来,方便排查。比如:
def hex_dump(data):
return ' '.join(f'{b:02X}' for b in data)
# 发送前打印
print(f"发送: {hex_dump(request)}")
# 接收后打印
print(f"接收: {hex_dump(response)}")
重要提醒:医疗设备的数据采集,一定要确保不影响设备正常运行。我建议先用模拟器测试,确认无误后再接真实设备。另外,采集频率不要太高,一般 1-2 秒一次就够了,避免给呼吸机增加负担。
好了,这一章的内容就到这里。串口通信和 Modbus 协议,是呼吸机数据采集的基石。你想想看,掌握了这些,市面上 80% 的医疗设备你都能搞定。下一章,我们会把这些数据存到数据库里,并搭建一个 Web 监控界面。到时候,你就可以在手机上实时查看呼吸机数据了。
记住,实践出真知。找个呼吸机模拟器练练手,比看十遍书都管用。有问题随时交流,咱们下章见。