使用Node.js modbus-serial连接Modbus RTU PLC寄存器读取异常问题
Modbus RTU读取欧姆龙PLC返回全false问题排查
一、先修复代码的异步连接缺陷
你的代码中connectRTUBuffered是异步操作,直接在其后执行setID和定时读取会导致连接未建立就发起请求,引发隐性错误。修改为异步链式调用并添加错误捕获:
const ModbusRTU = require("modbus-serial"); const client = new ModbusRTU(); client.connectRTUBuffered("/dev/ttyUSB0", { baudRate: 9600, dataBits: 8, stopBits: 1, parity: "none" // 需与PLC串口参数完全匹配 }) .then(() => { client.setID(1); // 必须与PLC设置的从站地址一致 console.log("串口连接成功"); setInterval(async () => { try { // 示例:读取DM5100起始的10个保持寄存器 const data = await client.readHoldingRegisters(5100, 10); console.log("读取结果:", data.data); } catch (err) { console.error("读取异常:", err.message); } }, 1000); }) .catch(err => { console.error("连接失败:", err.message); });
二、欧姆龙PLC地址映射核心规则
你之前的地址参数错误源于混淆了PLC内部地址与Modbus协议地址:
- 欧姆龙DM区与Modbus保持寄存器(函数码03)的映射:PLC内部
DMxxxx地址对应的Modbus0起始地址就是xxxx的十进制值。
比如DM5100对应Modbus起始地址为十进制5100(或十六进制0x13E8),而非你之前使用的十六进制0x5100(十进制20736,对应DM20736)。 - 若文档中给出的是Modbus 4xxxx格式地址(如45101),需转换为0起始地址:
45101 - 40001 = 5100。
三、其他关键排查项
- 串口参数一致性:确认PLC的波特率、数据位、停止位、奇偶校验与代码完全匹配,部分欧姆龙PLC默认参数为
9600,7,E,1,若代码用8N1会导致数据校验失败。 - RS485接线检查:A/B线接反会导致RX/TX灯正常闪烁但数据无效,需确认接线与适配器、PLC的标识一致。
- PLC Modbus功能启用:通过编程软件(如CX-Programmer)确认已启用Modbus RTU功能,且从站地址与代码中
setID(1)一致。 - 寄存器类型匹配:确保读取的是保持寄存器(函数码03),若目标是输入寄存器或线圈,需使用对应函数
readInputRegisters或readCoils。
内容的提问来源于stack exchange,提问作者Danillo Monteiro
相关产品推荐
相关产品推荐

