Skip to main content

Modbus RTU 协议

使用方式

关于 Modbus RTU 协议的所有使用方法全部封装成了 ModbusRTU 类,该类的提供实例化方式和直接调用静态方法两种方式使用,两种方式的适用环境如下:

  • 实例化:减少传参,适用于在上下文环境下使用。
  • 静态调用:直接调用,代码精简,适合轻度或测试使用。

ModbusRTU类引用与使用

引用:

import { ModbusRTU } from '@iot9x.com/ipc-utils'

实例化:

const rtu = new ModbusRTU({slaveId:1})

实例化参数:

字段类型是否必传默认值描述备注
slaveIdnumber-从机地址可填写 0-255 ,标准规定合法的地址是 0–247
crcOrderenumCRCOrder.LH小端CRC校验大小端
i16enumI16Encode.AB16位整型(有符号+无符号)编码格式
i32enumI32Encode.ABCD32位整型(有符号+无符号)编码格式
f32enumF32Encode.ABCD32位浮点型(FLOAT)编码格式
i64enumI64Encode.ABCDEFG64位整型(有符号+无符号)编码格式
f64enumF64Encode.ABCD64位浮点型(DOUBLE)编码格式

读取指令

生成读取指令是最常用的功能之一,按照协议标准可以读取四个区域的数据:

  • 线圈寄存器:采用01功能码,读取到的是0|1这样的开关量值
  • 离散输入寄存器:采用02功能码,读取到的是0|1这样的开关量值
  • 保持寄存器:采用03功能码,读取到的是十六进制信息,配合解析,可以得到数值或者字符串。
  • 输入寄存器:采用04功能码,读取到的内容同上。
tip

所有读取命令的返回结果均为十六进制字符串格式,通常需要转换后下发。

  • NodeJSElectron环境通常转换成Buffer格式。
  • 小程序环境由于天生不支持Buffer,需要转换成TypedArray格式,一般为UInt8Array

读线圈寄存器——01功能码

使用实例化方式:

const rtu = new ModbusRTU({slaveId:1})
const cmdHex = rtu.readCoilCMD(1, 1); // 获取从机地址为1,起始地址为1,读取1个线圈值的命令
expect(cmdHex).toBe('010100010001AC0A');

使用静态方式:

const cmdHex = ModbusRTU.readCoilCMD(1, 1, 1);  // 获取从机地址为1,起始地址为1,读取1个线圈值的命令
expect(cmdHex).toBe('010100010001AC0A');

读离散输入寄存器——02功能码

使用实例化方式:

const rtu = new ModbusRTU({slaveId:1})
const cmdHex = rtu.readDiscreteInputCMD(1, 1); // 获取从机地址为1,起始地址为1,读取1个离散值的命令
expect(cmdHex).toBe('010200010001E80A');

使用静态方式:

const cmdHex = ModbusRTU.readDiscreteInputCMD(1, 1, 1);  // 获取从机地址为1,起始地址为1,读取1个离散值的命令
expect(cmdHex).toBe('010200010001E80A');

读保持寄存器——03功能码

使用实例化方式:

const rtu = new ModbusRTU({slaveId:1})
const cmdHex = rtu.readHoldCMD(1, 1); // 获取从机地址为1,起始地址为1,读取1个输入寄存器值的命令
expect(cmdHex).toBe('010300010001D5CA');

由于保持寄存器的内容可以有很多特殊用途,因此我们基于实际情况扩充了数据类型的概念,详见:数据类型

在获取读取指令的时候,提供根据数据类型来生成指令的方法,避免手动计算寄存器数量了:

const rtu = new ModbusRTU({slaveId:1})
const cmdHex = rtu.readHoldCMD(1, 1); // 获取从机地址为1,起始地址为1,读取1个输入寄存器值的命令
expect(cmdHex).toBe('010300010001D5CA');