Modbus RTU 协议
使用方式
关于 Modbus RTU
协议的所有使用方法全部封装成了 ModbusRTU
类,该类的提供实例化方式和直接调用静态方法两种方式使用,两种方式的适用环境如下:
- 实例化:减少传参,适用于在上下文环境下使用。
- 静态调用:直接调用,代码精简,适合轻度或测试使用。
ModbusRTU类引用与使用
引用:
import { ModbusRTU } from '@iot9x.com/ipc-utils'
实例化:
const rtu = new ModbusRTU({slaveId:1})
实例化参数:
字段 | 类型 | 是否必传 | 默认值 | 描述 | 备注 |
---|---|---|---|---|---|
slaveId | number | ✅ | - | 从机地址 | 可填写 0-255 ,标准规定合法的地址是 0–247 |
crcOrder | enum | ❌ | CRCOrder.LH (小端) | CRC校验大小端 | |
i16 | enum | ❌ | I16Encode.AB | 16位整型(有符号+无符号)编码格式 | |
i32 | enum | ❌ | I32Encode.ABCD | 32位整型(有符号+无符号)编码格式 | |
f32 | enum | ❌ | F32Encode.ABCD | 32位浮点型(FLOAT)编码格式 | |
i64 | enum | ❌ | I64Encode.ABCDEFG | 64位整型(有符号+无符号)编码格式 | |
f64 | enum | ❌ | F64Encode.ABCD | 64位浮点型(DOUBLE)编码格式 |
读取指令
生成读取指令是最常用的功能之一,按照协议标准可以读取四个区域的数据:
- 读线圈寄存器:采用
01
功能码,读取到的是0|1
这样的开关量值。 - 读离散输入寄存器:采用
02
功能码,读取到的是0|1
这样的开关量值。 - 读保持寄存器:采用
03
功能码,读取到的是十六进制信息,配合解析,可以得到数值或者字符串。 - 读输入寄存器:采用
04
功能码,读取到的内容同上。
tip
所有读取命令的返回结果均为十六进制字符串格式,通常需要转换后下发。
NodeJS
和Electron
环境通常转换成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');