在工业自动化领域,Modbus协议因其简单、可靠和广泛支持而备受青睐。其中,Modbus RTU(串行通信)以其低成本和易实施性在许多场景中发挥着重要作用。
01
Modbus RTU协议简介
Modbus RTU是一种基于串行通信的Modbus协议,它使用RS-485或RS-232接口,以字节为单位进行数据传输。Modbus RTU协议定义了主从设备之间的通信规则,主设备负责发起请求,从设备则响应请求并返回数据。
02
Python实现Modbus RTU通信的步骤
准备硬件环境 要实现Modbus RTU通信,首先需要准备支持RS-485或RS-232接口的硬件设备,如串口适配器、从设备(如传感器、执行器等)以及连接线材。安装Python库 要实现Modbus RTU通信,我们可以使用Python的第三方库pymodbus。通过pip可以轻松安装该库:
pip install pymodbus
03,导入库文件:
import time
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
注意pymodbus版本下载版本为pymodbus=== 2.5.3
否则导入ModbusSerialClient报错,
新版pymodbus版本导入写法如下:
from pymodbus.client import ModbusSerialClient as ModbusClient
废话不多说,直接上完整代码:
import time
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
# 配置参数
TIMER = 1 # 读取间隔时间(秒)
SERVER_ADDRESS = [1]
START_ADDRESS = 101
START_ADDRESS_2 = 1
QUANTITY = 100
QUANTITY_2 = 4
COM_PORT = "COM8"
BAUD_RATE = 9600
def modbus_master_rtu():
"""
Modbus RTU主站读取程序:循环从多个Modbus从站地址读取保持寄存器数据,
将读取结果直接写入指定CSV文件,并在控制台显示。同时具备异常处理能力。
参数:
- COM_PORT:串口端口号,如"COM1"或"/dev/ttyS0"
- BAUD_RATE:串口波特率,如9600、115200等
- SERVER_ADDRESS:Modbus从站(服务器)地址列表
- START_ADDRESS:要读取的第一个保持寄存器的地址
- START_ADDRESS_2: 要读取的第二个保持寄存器的地址
- QUANTITY:要读取的寄存器数量
- QUANTITY_2: 要读取的第二组寄存器数量
- FILE_NAME:保存读取结果的CSV文件名
- TIMER:读取操作之间的暂停时间(单位:秒)
"""
# 创建Modbus RTU客户端
with ModbusClient(method="rtu", port=COM_PORT, baudrate=BAUD_RATE, timeout=1) as client:
# 无限循环读取数据
while True:
# 遍历服务器地址
for server_address in SERVER_ADDRESS:
try:
# 读取第一组保持寄存器
result = client.read_holding_registers(START_ADDRESS, QUANTITY, unit=server_address)
# 读取第二组保持寄存器
result_2 = client.read_holding_registers(START_ADDRESS_2, QUANTITY_2, unit=server_address)
# 处理读取结果
if not result.isError() and not result_2.isError():
# 控制台输出读取到的寄存器值
print(", ".join(map(str, result.registers)))
print(", ".join(map(str, result_2.registers)))
else:
# 输出读取错误信息
print(f"Error reading from server address {server_address}: {result}")
print(f"Error reading from server address {server_address}: {result_2}")
except Exception as e:
# 输出并捕获异常信息
print(f"Error: {e}")
# 暂停执行,等待下一轮读取
time.sleep(TIMER)
if __name__ == "__main__":
modbus_master_rtu()
上述中的
这几个参数要根据自己的调整,之后运行界面如下: