本文是使用python制作MODBUS RTU主站调试工具(一)—— GUI编程 的后续。
OS:win10 x64 1909
开发工具:VS Code
Python 库:modbus_tk/serial
1 modbus_tk
modbus_tk是使用python实现的modbus协议栈,通过调用modbus_tk可以很方便的实现modbus通信。
在VS CODE中需要先通过pip安装modbus_tk库,其方法可参见:vscode 如何导入python库
modbus_tk支持以下功能码:
功能码 | 编号 | 含义 |
READ_COILS | H01 | 读线圈 |
READ_DISCRETE_INPUTS | H02 | 读离散输入 |
READ_HOLDING_REGISTERS | H03 | 读寄存器 |
READ_INPUT_REGISTERS | H04 | 读输入寄存器 |
WRITE_SINGLE_COIL | H05 | 写单一线圈 |
WRITE_SINGLE_REGISTER | H06 | 写单一寄存器 |
WRITE_MULTIPLE_COILS | H15 | 写多个线圈 |
WRITE_MULTIPLE_REGISTERS | H16 | 写多寄存器 |
python程序需要进行两部分配置:串口配置和modbus协议配置。
导入库和串口配置:
import serial
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
#设定串口为从站
master = modbus_rtu.RtuMaster(serial.Serial(port="COM1",
baudrate=9600, bytesize=8, parity='N', stopbits=1))
master.set_timeout(5.0)
modbus协议配置(举例):
#读线圈 01H 1站号 地址2 长度5
out1 = master.execute(1, cst.READ_COILS, 2, 5) #长度指读取的寄存器数,寄存器从指定地址起连续读取
print(out1) #输出读取的结果
#读保持寄存器 01H 2站号 地址1 长度6
out2 = master.execute(2, cst.READ_HOLDING_REGISTERS, 1, 6)
print(out2) #输出读取的结果
#写单一线圈 05H 1站号 地址8 写入值1
master.execute(1, cst.WRITE_SINGLE_COIL, 8, output_value=1)
#写单一寄存器 06H 1站号 地址4 写入值500
master.execute(1, cst.WRITE_SINGLE_REGISTER, 4, output_value=500)
可参考:modbus_tk模块
2 软件模拟测试
2.1模拟软件
编写好程序后,需要进行测试,由于我并没有可以进行连接的modbus从站设备,因此采用软件模拟来测试代码的正确性。
modbus从站采用modbus slave模拟,并使用vspd虚拟串口工具建立主站和从站间的通讯。
配置方法可参考:Modbus测试工具ModbusPoll与Modbus Slave使用方法 另附modbus slave序列号:5A5742575C5D10
vspd虚拟串口工具
在vspd虚拟串口工具中需要创建新串口。串口都是成对创建的,也就是说由两个串口建立连接,而不是像PC同实机通讯那样经由一个串口建立通讯:
这里创建了COM1和COM2两个虚拟串口(左侧列表),COM1分配给主站(vs code),COM2分配给从站(modbus slave):
串口编号旁中括号内为设置的连接参数,由VSPD读取与之连接的设备得到,COM1无显示是因为测试程序只执行一次便断开连接。
————
modbus slave
在modbus slave中需要配置的地方有两块:
- 串口配置:
- modbus协议配置:
2.2测试结果
配置好VSPD和modbus slave后,运行以下python代码:
import serial
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
#设定串口为从站
master = modbus_rtu.RtuMaster(serial.Serial(port="COM1",
baudrate=9600, bytesize=8, parity='N', stopbits=1))
master.set_timeout(5.0)
master.execute(1, cst.WRITE_SINGLE_REGISTER, 7, output_value=500)
观察modbus slave窗口:
可看到主站成功向从站写入值。
下一步,就是将tkinter和modbus_tk联系在一起。