前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于纯JavaScript实现的MODBUS-RTU(串口和TCP) modbus-serial

基于纯JavaScript实现的MODBUS-RTU(串口和TCP) modbus-serial

作者头像
拿我格子衫来
发布2024-05-25 08:55:55
8540
发布2024-05-25 08:55:55
举报
文章被收录于专栏:TopFE

modbus-serial

如果你需要使用JavaScript来操作一台RS458的设备,那么你一定不能错过这个库 modbus-serial

安装和使用

代码语言:javascript
复制
npm install modbus-serial

支持的功能码

功能码

函数

FC1 读取读线圈寄存器

readCoils(coil, len)

FC2 读离散输入寄存器

readDiscreteInputs(addr, arg)

FC3 读保持寄存器

readHoldingRegisters(addr, len)

FC4 读输入寄存器

readInputRegisters(addr, len)

FC5 写单个线圈寄存器

writeCoil(coil, binary)

FC6 写单个保持寄存器

writeRegister(addr, value)

FC15 写多个线圈寄存器

writeCoils(addr, valueAry)

FC16 写多个保持寄存器

writeRegisters(addr, valueAry)

FC43/14 读保持寄存器

readDeviceIdentification(id, obj)

客户端串行:

  • modbus-RTU (SerialPort):通过串行线路,需要node serialport。
  • modbus-RTU (RTUBufferedPort):通过缓冲串行线路,需要node serialport。
  • modbus-ASCII (AsciiPort):通过串行线路,需要node serialport。

客户端TCP:

  • modbus-TCP (TcpPort):通过TCP/IP线路。
  • modbus-RTU (UdpPort):通过C701服务器,商业UDP到串行桥。
  • modbus-RTU (TcpRTUBufferedPort):通过TCP/IP线路,TCP/IP串行RTU缓冲设备。
  • modbus-RTU (TelnetPort):通过Telnet服务器,TCP/IP串行桥。

服务器

  • modbus-TCP (ServerTCP):通过TCP/IP线路。

示例

读取和写入
代码语言:javascript
复制
// create an empty modbus client
const ModbusRTU = require("modbus-serial");
const client = new ModbusRTU();

// open connection to a serial port
client.connectRTUBuffered("/dev/ttyUSB0", { baudRate: 9600 }, write);

function write() {
    client.setID(1);

    // write the values 0, 0xffff to registers starting at address 5
    // on device number 1.
    client.writeRegisters(5, [0 , 0xffff])
        .then(read);
}

function read() {
    // read the 2 registers starting at address 5
    // on device number 1.
    client.readHoldingRegisters(5, 2)
        .then(console.log);
}
读取多个从站
代码语言:javascript
复制
const ModbusRTU = require("modbus-serial");
// create an empty modbus client
const client = new ModbusRTU();
// open connection to a serial port
client.connectRTUBuffered("/dev/ttyS0", { baudRate: 9600 });
// set timeout, if slave did not reply back
client.setTimeout(500);

// list of meter's id
const metersIdList = [10, 11, 12, 13, 14];

const getMetersValue = async (meters) => {
    try{
        // get value of all meters
        for(let meter of meters) {
            // output value to console
            console.log(await getMeterValue(meter));
            // wait 100ms before get another device
            await sleep(100);
	}
    } catch(e){
        // if error, handle them here (it should not)
        console.log(e)
    } finally {
        // after get all data from slave, repeat it again
        setImmediate(() => {
            getMetersValue(metersIdList);
        })
    }
}

const getMeterValue = async (id) => {
    try {
        // set ID of slave
        await client.setID(id);
        // read the 1 registers starting at address 0 (first register)
        let val =  await client.readInputRegisters(0, 1);
        // return the value
        return val.data[0];
    } catch(e){
        // if error return -1
        return -1
    }
}

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));


// start get value
getMetersValue(metersIdList);
ModbusTCP 服务
代码语言:javascript
复制
// create an empty modbus client
const ModbusRTU = require("modbus-serial");
const vector = {
    getInputRegister: function(addr, unitID) {
        // Synchronous handling
        return addr;
    },
    getHoldingRegister: function(addr, unitID, callback) {
        // Asynchronous handling (with callback)
        setTimeout(function() {
            // callback = function(err, value)
            callback(null, addr + 8000);
        }, 10);
    },
    getCoil: function(addr, unitID) {
        // Asynchronous handling (with Promises, async/await supported)
        return new Promise(function(resolve) {
            setTimeout(function() {
                resolve((addr % 2) === 0);
            }, 10);
        });
    },
    setRegister: function(addr, value, unitID) {
        // Asynchronous handling supported also here
        console.log("set register", addr, value, unitID);
        return;
    },
    setCoil: function(addr, value, unitID) {
        // Asynchronous handling supported also here
        console.log("set coil", addr, value, unitID);
        return;
    },
    readDeviceIdentification: function(addr) {
        return {
            0x00: "MyVendorName",
            0x01: "MyProductCode",
            0x02: "MyMajorMinorRevision",
            0x05: "MyModelName",
            0x97: "MyExtendedObject1",
            0xAB: "MyExtendedObject2"
        };
    }
};

// set the server to answer for modbus requests
console.log("ModbusTCP listening on modbus://0.0.0.0:8502");
const serverTCP = new ModbusRTU.ServerTCP(vector, { host: "0.0.0.0", port: 8502, debug: true, unitID: 1 });

serverTCP.on("socketError", function(err){
    // Handle socket error if needed, can be ignored
    console.error(err);
});

市面上有非常多的设备时 RS485,如果你之前是前端,并且想接触硬件,就学习一下它吧。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • modbus-serial
  • 安装和使用
  • 示例
    • 读取和写入
      • 读取多个从站
        • ModbusTCP 服务
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档