modbus 协议初体验
最近被拉去支援硬件部分,又写了几天对接嵌入式的上位机程序 _(ˊཀˋ」∠)_
和下位机通信是用 modbus 协议的。趁机学习了一下这个上古协议。(奇怪的知识又增加了
modbus 是用 req/res
的模式来通信的。和 http 是一样的,如果要拿传感器信息只能轮询
关于 modbus 协议的一大特点,就是支持设备并连,可以通过一个串口控制最多 256 个设备(每次发送请求时要发送目标地址)
由于 modbus.org
不支持 https 。所以就不放标准文档的连接了(迫真,上古协议)
以这个读取状态的请求为例 03 (0x03) Read Holding Registers
Name | Length | Value |
---|---|---|
Function code | 1 Byte | 0x03 |
Starting Address | 2 Bytes | 0x0000 to 0xFFFF |
Quantity of Registers | 2 Bytes | 1 to 125 (0x7D) |
每个请求要有 Function code
字段。用到的 Function code
是有标准的定义的。(当然是可以不按照标准实现)
当然不同的 Function code
对应的参数也不同。
这个协议的读写是直接写到对应地址里的。
比如有一个地址为 0x01
的存温度,地址为 0x02
存湿度
由于这两个地址是连续的。可以一口气全部读出来
我们先来发送一个 0x03
的请求
当然 Starting Address
是 0x01
,Quantity of Registers
是 0x02
(一共读两个: 0x01
和 0x02
)
然后请求转换成这样一段东西:['0x03', '0x00', '0x01', '0x00', '0x02']
(我应该不用解释这一串是怎么生成的吧。。。)
这个叫 pdu
(Protocol Data Unit)也就是 Function code
加上 Function code
对应的 Data
之后把 pdu
emmmmm 。之后分成多种情况。这个和你的传输方式有关。modbus 可以使用RTU
(串口传输)也可以使用 TCP
来传输。
如果是 RTU
传输,加入目标地址,加入 crc 校验字段,然后就可以直接发送出去了
Name | Value |
---|---|
Slave Address | 1 byte |
Function | 1 byte |
Data | 0 up to 252 bytes |
CRC | 2 byte |
如果使用 TCP
就多出了很多字段
Name | Value |
---|---|
Transaction identifier | 2 bytes |
Protocol identifier | 2 bytes |
Length | 2 bytes |
Unit identifier | 1 byte |
Function code | 1 byte |
Data | n bytes |
modbus 也就这点东西了,其实没什么。
modbus 还可以的。就是,如果个厂商能按照 modbus 标准来实现就好了(我写的时候,坑人的硬件厂商没有按照 modbus 标准实现)
这协议要是支持订阅某个地址的值,然后当数值变化的时候自动推送消息就好了(设置个最小推送时间间隔,这样就可以不用轮询了)