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

使用modbus-serial库向Radioshuttle写寄存器无响应,求排查

Modbus TCP写入Radioshuttle设备无响应问题分析

问题代码

const ModbusRTU = require("modbus-serial");

const gatewayIpAddress = "XXX.XXX.XXX.XXX";
const tcpPort = 502;
const unitId = 1;

const storePallet = async (shuttle) => {
    console.log("Storepallet function");
    console.log("ShuttleNumber: " + shuttle);
    const client = new ModbusRTU();

    try {
        await client.connectTCP(gatewayIpAddress, { port: tcpPort });
        console.log("Connected to Radioshuttle device over Modbus TCP");

        // Write store request
        await client.setID(unitId);
        await client.writeRegister(0, 1); // Address 0 represents tag #4 BIT 02.0.1

        console.log("Pallet stored successfully");
        client.close();
    } catch (error) {
        console.error("Error storing pallet:", error);
        client.close();
        throw error;
    }
};

storePallet(1).catch((error) => {
    // Handle the error here
    console.error("Unhandled error:", error);
});

设备文档关键信息

连接的Modbus TCP客户端(主站)设置
常规设置
RS网关IP地址:XXX.XXX.XXX.XXX
TCP端口:502
单元ID/从站地址:1
写入Radioshuttle输入数据
功能码:16 – 写入多个寄存器
写入数据起始地址:1
写入数据长度:5

寄存器 - RS输入标签对应Register 1和2,存储请求相关信息如下:

Tag #FormatAddressName
4BIT002.0.1Store request

描述:由MCS设为1以启动将托盘存入货架的命令;当RS回复RS输出标签#5设为1时,由MCS设为0。

错误点分析

  • 功能码不匹配:设备要求写入使用功能码16(写入多个寄存器),但代码中使用writeRegister方法,对应Modbus功能码06(写入单个寄存器),不符合设备通信规范。
  • 寄存器地址错误:文档中Store request的地址是002.0.1,其中002是1-based的寄存器地址,对应modbus-serial库中0-based的地址为1(库的寄存器地址从0开始计数);而代码中写的地址0对应的是文档里的Register 1,完全不对。
  • 位操作逻辑错误:Store request是寄存器中的单个BIT(第1位,文档中位编号从1开始),不能直接将整个寄存器值设为1,这样会覆盖该寄存器的其他位数据,导致设备无法正确识别命令。正确做法是先读取寄存器当前值,仅将目标位设为1,再写回寄存器。
  • 未遵循写入长度要求:设备要求写入起始地址1、长度5的寄存器组,即使只需要修改其中一个位,也需要按照设备要求的长度构造写入数据(保持其他寄存器原有值不变)。

修正后的代码

const ModbusRTU = require("modbus-serial");

const gatewayIpAddress = "XXX.XXX.XXX.XXX";
const tcpPort = 502;
const unitId = 1;
const WRITE_START_ADDR = 0; // 对应文档中1-based起始地址1,转换为0-based
const WRITE_LENGTH = 5; // 文档要求的写入长度
const STORE_REQUEST_REG_INDEX = 1; // 对应文档中002寄存器(1-based),0-based索引为1
const STORE_REQUEST_BIT = 1; // 文档中BIT 02.0.1,位编号从1开始

const storePallet = async (shuttle) => {
    console.log("Storepallet function");
    console.log("ShuttleNumber: " + shuttle);
    const client = new ModbusRTU();

    try {
        await client.connectTCP(gatewayIpAddress, { port: tcpPort });
        console.log("Connected to Radioshuttle device over Modbus TCP");
        await client.setID(unitId);

        // 1. 读取当前的输入寄存器组(5个寄存器)
        const response = await client.readInputRegisters(WRITE_START_ADDR, WRITE_LENGTH);
        const currentRegisters = response.data;

        // 2. 修改目标寄存器的对应位:将Store request位设为1
        const bitMask = 1 << (STORE_REQUEST_BIT - 1); // 转换为0-based位的掩码
        currentRegisters[STORE_REQUEST_REG_INDEX] |= bitMask; // 仅将目标位设为1,其他位保留

        // 3. 使用功能码16写入多个寄存器(对应writeRegisters方法)
        await client.writeRegisters(WRITE_START_ADDR, currentRegisters);

        console.log("Store request sent successfully");

        // 可选:轮询设备响应,确认完成后将Store request位设为0
        // let isCompleted = false;
        // while (!isCompleted) {
        //     const outputResponse = await client.readInputRegisters(0, 10); // 文档中读取起始地址1(0-based为0),长度10
        //     // 根据文档找到输出标签#5对应的寄存器位,判断是否完成
        //     // isCompleted = /* 检查对应位是否为1 */;
        //     await new Promise(resolve => setTimeout(resolve, 1000));
        // }
        // // 将Store request位重置为0
        // currentRegisters[STORE_REQUEST_REG_INDEX] &= ~bitMask;
        // await client.writeRegisters(WRITE_START_ADDR, currentRegisters);
        // console.log("Store request reset to 0");

        client.close();
    } catch (error) {
        console.error("Error storing pallet:", error);
        if (client.isOpen) {
            client.close();
        }
        throw error;
    }
};

storePallet(1).catch((error) => {
    console.error("Unhandled error:", error);
});

修正说明

  1. 功能码修正:使用writeRegisters方法对应Modbus功能码16,完全符合设备要求。
  2. 地址修正:将文档中的1-based地址转换为库的0-based地址,确保操作到正确的寄存器。
  3. 位操作修正:通过读取原有寄存器值,仅修改目标位,避免覆盖其他关键配置数据。
  4. 遵循写入长度:按照设备要求写入5个寄存器,保持其他寄存器值不变,确保通信格式与设备预期一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 03:38:17