1、Modbus协议
- Modbus协议操作四个对象
对象 | 含义 |
---|---|
线圈 | PCL的输出位,开关量,在Modbus中可读可写 |
离散量 | PLC的输入位,开关量,在Modbus中只读 |
输入寄存器 | PLC中只能从模拟量输入端改变的寄存器,在Modbus中只读 |
保存寄存器 | PLC中用于输出模拟量信号的寄存器,在Modbuszhong可读可写 |
- Modbus 的功能码
功能码 | 含义 |
---|---|
0x01 | 读线圈 |
0x05 | 写单个线圈 |
0x0F | 写多个线圈 |
0x02 | 读离散量输入 |
0x04 | 读输入寄存器 |
0x03 | 读保持寄存器 |
0x06 | 写单个保持寄存器 |
0x10 | 写多个保持寄存器 |
2、Modbus Tcp 仿真实验
仿真使用的软件有:
Modbus Poll和Modbus Slave,激活教程在下载文件里面;
下载地址:
链接:https://pan.baidu.com/s/1E-UyaZ4AyVuuLuy7WDVjAA
提取码:vmuy
-
modbus slave 从机寄存器配置
-
初始化解释
03对应的输入寄存器
-
首先配置配置Modbus Tcp 协议和502端口
按F3,配置如下,点击ok;
- 配置寄存器
按F8,
按照以上配置完成如下:
以上便是从机配置完成,下面配置主机。 - Modbus poll 主机配置
初始换界面
- 首先配置Modbus Tcp协议、端口、Modbus slave IP地址
按F3
点击ok
- 配置功能码、寄存器编号、寄存器地址、寄存器数量
按F8
按照上图配置完成,大功告成。
- 演示
点击ok
成功!!!!!!!!!!!!!!!!!!!
3 、使用pymodbus 类库读取Modbus Slave寄存器数据
功能码 | 含义 | pymodbus 函数 |
---|---|---|
0x01 | 读线圈 | def read_coils(self, address, count=1, **kwargs): |
0x05 | 写单个线圈 | def write_coil(self, address, value, **kwargs): |
0x0F | 写多个线圈 | def write_coils(self, address, values, **kwargs): |
0x02 | 读离散量输入 | def read_discrete_inputs(self, address, count=1, **kwargs): |
0x04 | 读输入寄存器 | def read_input_registers(self, address, count=1, **kwargs): |
0x03 | 读保持寄存器 | def read_holding_registers(self, address, count=1, **kwargs): |
0x06 | 写单个保持寄存器 | def write_register(self, address, value, **kwargs): |
0x10 | 写多个保持寄存器 | def write_registers(self, address, values, **kwargs): |
DEMO
配置
"""
功能:读线圈
时间:2020/11
作者:吕布
邮箱:1071283996@qq.com
"""
from pymodbus.client.sync import ModbusTcpClient
import time
# 配置寄存器IP地址和端口号
client = ModbusTcpClient('Modbus slave IP', port=502, timeout=1)
# 配置 寄存器地址:0、寄存器数量:30、寄存器ID:2;功能码:0x01=read_coils: 操作对象:线圈
def DSY_read_coils():
request1 = client.read_coils(0, 10, unit=2)
result1 = request1.bits
# print(result.bits[0])
print(result1)
# print(result[0])
time.sleep(1)
if __name__=="__main__":
DSY_read_coils()
效果:
4 、modbus tcp数据报文结构
请求:00 00 00 00 00 06 09 03 00 00 00 01
响应:00 00 00 00 00 05 09 03 02 12 34
一次modbus tcp读取保持寄存器的通信分析(省略了ip/tcp头):从左向右分析该数据报文:
请求:
00 00为此次通信事务处理标识符,一般每次通信之后将被要求加1以区别不同的通信数据报文;
00 00表示协议标识符,00 00为modbus协议;
00 06为数据长度,用来指示接下来数据的长度,单位字节;
09为设备地址,用以标识连接在串行线或者网络上的远程服务端的地址。以上七个字节也被称为modbus报文头;
03为功能码,此时代码03为读取保持寄存器数据;
00 00为起始地址;
00 01为寄存器数量,(word数量)。
响应:
00 00为此次通信事务处理标识符,应答报文要求与先前对应的请求保持一致;
00 00为协议标识符,与先前对应的请求保持一致;
00 05为数据长度,用来指示接下来数据的长度,单位字节;
09为设备地址,应答报文要求与先前对应的请求保持一致;
03为功能码,正常情况下应答报文要求与先前对应的请求保持一致,如果出错则返回80h+先前的功能码;
02指示接下来数据的字节长度;
12 34为被读取的保持寄存器中的数据值,即要求被读取的地址为00 00的保持寄存器中的数值为1234h。
以上是全部博客,谢谢。
需要全部代码的可以访问:地址