如何向医疗设备写入ASTM帧?Node.js实现ASTM协议发送故障求助
Node.js开发ASTM协议发送消息失败(针对SELECTRA/COBAS E411设备)
针对你用Node.js向SELECTRA和COBAS E411设备发送ASTM消息失败的问题,从ASTM协议规范和设备兼容性角度,给你几个核心排查和解决方向:
1. 补全ASTM协议必需的帧结构
你提供的示例消息只是纯文本内容,完全不符合ASTM协议的帧格式要求,设备根本无法识别。标准ASTM帧必须包含:
- 起始符(STX):ASCII码
0x02 - 消息主体:你的业务内容(行结束必须用
\r\n) - 结束符(ETX/ETB):ASCII码
0x03(单帧用ETX,多帧用ETB) - 校验和:消息主体的ASCII码累加后取模256,转成两位十六进制
- 回车符(CR):ASCII码
0x0D
2. 核对通信参数与方式
SELECTRA和COBAS E411常用串口或TCP通信,必须确保参数完全匹配:
- 串口通信:波特率(通常9600)、数据位(8)、停止位(1)、奇偶校验(None),Node.js推荐用
serialport库实现 - TCP通信:确认设备的IP、端口,ASTM over TCP用原始套接字,需处理字节流粘包问题,发送时用ASCII编码
3. 校验消息内容细节
- 日期格式:检查H段、O段的时间戳是否符合设备要求,部分设备可能限制长度或格式
- 字段完整性:必填字段不能留空,比如P段的患者ID、性别等,空字段需按设备文档填默认值
- 分隔符使用:
|(字段分隔)、!(子字段分隔)的使用要严格遵循设备手册,部分设备可能对特定字段的子分隔符有不同要求
4. 修正Node.js发送逻辑
- 编码转换:发送时必须将字符串转为ASCII字节流,而非默认UTF-8,用
Buffer.from(msg, 'ascii')处理 - 行结束符:业务内容的每行必须用
\r\n(CRLF),不能只用\n - 响应处理:ASTM是请求-响应协议,必须等待设备返回ACK(
0x06)后再发送下一条消息,收到NAK(0x15)则需要重发
修正后的示例代码(串口版)
const SerialPort = require('serialport'); const Readline = require('@serialport/parser-readline'); // 串口配置,根据设备实际参数调整 const port = new SerialPort('COM3', { baudRate: 9600, dataBits: 8, stopBits: 1, parity: 'none' }); const parser = port.pipe(new Readline({ delimiter: '\r' })); // 构建符合ASTM标准的消息帧 function buildASTMFrame(content) { const STX = String.fromCharCode(0x02); const ETX = String.fromCharCode(0x03); // 计算校验和 let checksum = 0; for (let i = 0; i < content.length; i++) { checksum += content.charCodeAt(i); } checksum = checksum % 256; const checksumHex = checksum.toString(16).toUpperCase().padStart(2, '0'); return STX + content + ETX + checksumHex + '\r'; } // 原始业务消息(行结束用\r\n) const rawContent = `H|!~|||LISHOST|||||||P|LIS2-A2|20040318235959\r\nP|1||12345677||AHMED!SARMOUM||20120112!4!Y|M|||||\r\nO|1|SID_133||!!!CD|||20160510111238||||N||||WB\r\nL|1|N`; const astmFrame = buildASTMFrame(rawContent); // 发送消息 port.write(Buffer.from(astmFrame, 'ascii'), (err) => { if (err) { console.error('发送失败:', err); return; } console.log('消息已发送'); }); // 监听设备响应 parser.on('data', (data) => { console.log('设备响应:', data); if (data.includes(String.fromCharCode(0x06))) { console.log('设备确认接收'); } else if (data.includes(String.fromCharCode(0x15))) { console.log('设备拒绝接收,需重发'); } });
内容的提问来源于stack exchange,提问作者Ahmed SARMOUM
相关产品推荐
相关产品推荐

