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 标准实现)
这协议要是支持订阅某个地址的值,然后当数值变化的时候自动推送消息就好了(设置个最小推送时间间隔,这样就可以不用轮询了)




