PyModbus 从入门到精通教程

一、Modbus 协议简介

Modbus 是一种串行通信协议,用于电子设备之间的通信。它是工业领域中常用的通信协议,可实现设备之间的数据交换。Modbus 有几种传输模式,常见的是 Modbus RTU(通过串口)和 Modbus TCP(通过以太网)。

二、PyModbus 简介

PyModbus 是一个用 Python 实现的 Modbus 协议库,支持 Modbus RTU、Modbus TCP 等多种模式,方便开发者在 Python 环境中进行 Modbus 通信开发。

三、安装 PyModbus

使用 pip 可以轻松安装 PyModbus:

pip install pymodbus

四、入门:基本的 Modbus TCP 通信示例

  1. Modbus TCP 服务器示例

以下是一个简单的 Modbus TCP 服务器示例,它模拟了一个 Modbus 设备,存储了一些保持寄存器的值:

from pymodbus.server.sync import StartTcpServer

from pymodbus.datastore import ModbusSequentialDataBlock

from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

def run_modbus_server():

初始化数据块,这里模拟了 100 个保持寄存器,初始值都为 0

store = ModbusSlaveContext(

di=ModbusSequentialDataBlock(0, [0]*100),

co=ModbusSequentialDataBlock(0, [0]*100),

hr=ModbusSequentialDataBlock(0, [0]*100),

ir=ModbusSequentialDataBlock(0, [0]*100))

context = ModbusServerContext(slaves=store, single=True)

启动 Modbus TCP 服务器,监听本地的 5020 端口

StartTcpServer(context, address=("localhost", 5020))

if name == "main":

run_modbus_server()

代码解释:

● ModbusSequentialDataBlock 用于创建一个连续的数据块,这里分别为离散输入( di )、线圈( co )、保持寄存器( hr )和输入寄存器( ir )创建了初始值都为 0 的数据块。

● ModbusSlaveContext 表示从站的上下文,包含了各种寄存器的数据块。

● ModbusServerContext 表示服务器的上下文,管理从站的上下文。

● StartTcpServer 用于启动 Modbus TCP 服务器。

  1. Modbus TCP 客户端示例

以下是一个简单的 Modbus TCP 客户端示例,用于读取服务器的保持寄存器的值:

from pymodbus.client.sync import ModbusTcpClient

def run_modbus_client():

创建 Modbus TCP 客户端,连接到本地的 5020 端口

client = ModbusTcpClient('localhost', port=5020)

连接到服务器

if client.connect():

读取从地址 0 开始的 10 个保持寄存器的值

result = client.read_holding_registers(address=0, count=10, unit=1)

if not result.isError():

print("读取到的保持寄存器的值:", result.registers)

else:

print("读取失败:", result)

else:

print("无法连接到服务器")

关闭连接

client.close()

if name == "main":

run_modbus_client()

代码解释:

● ModbusTcpClient 用于创建一个 Modbus TCP 客户端。

● client.connect() 用于连接到 Modbus 服务器。

● client.read_holding_registers 用于读取保持寄存器的值, address 表示起始地址, count 表示要读取的寄存器数量, unit 表示从站地址。

● result.isError() 用于检查读取是否成功。

● client.close() 用于关闭客户端连接。

五、进阶:写入寄存器值

  1. 写入单个保持寄存器

from pymodbus.client.sync import ModbusTcpClient

def write_single_register():

client = ModbusTcpClient('localhost', port=5020)

if client.connect():

向地址为 0 的保持寄存器写入值 100

result = client.write_single_register(address=0, value=100, unit=1)

if not result.isError():

print("写入成功")

else:

print("写入失败:", result)

client.close()

else:

print("无法连接到服务器")

if name == "main":

write_single_register()

  1. 写入多个保持寄存器

from pymodbus.client.sync import ModbusTcpClient

def write_multiple_registers():

client = ModbusTcpClient('localhost', port=5020)

if client.connect():

向从地址 0 开始的保持寄存器写入值 [1, 2, 3, 4, 5]

values = [1, 2, 3, 4, 5]

result = client.write_multiple_registers(address=0, values=values, unit=1)

if not result.isError():

print("写入成功")

else:

print("写入失败:", result)

client.close()

else:

print("无法连接到服务器")

if name == "main":

write_multiple_registers()

六、Modbus RTU 通信

  1. Modbus RTU 服务器示例

from pymodbus.server.sync import StartSerialServer

from pymodbus.datastore import ModbusSequentialDataBlock

from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

def run_modbus_rtu_server():

store = ModbusSlaveContext(

di=ModbusSequentialDataBlock(0, [0]*100),

co=ModbusSequentialDataBlock(0, [0]*100),

hr=ModbusSequentialDataBlock(0, [0]*100),

ir=ModbusSequentialDataBlock(0, [0]*100))

context = ModbusServerContext(slaves=store, single=True)

启动 Modbus RTU 服务器,使用串口 COM1(Windows)或 /dev/ttyUSB0(Linux)

StartSerialServer(context, method='rtu', port='COM1', baudrate=9600)

if name == "main":

run_modbus_rtu_server()

  1. Modbus RTU 客户端示例

from pymodbus.client.sync import ModbusSerialClient

def run_modbus_rtu_client():

client = ModbusSerialClient(method='rtu', port='COM1', baudrate=9600)

if client.connect():

result = client.read_holding_registers(address=0, count=10, unit=1)

if not result.isError():

print("读取到的保持寄存器的值:", result.registers)

else:

print("读取失败:", result)

client.close()

else:

print("无法连接到服务器")

if name == "main":

run_modbus_rtu_client()

七、精通:异常处理和日志记录

  1. 异常处理

在实际应用中,需要对各种异常情况进行处理,例如连接失败、读取或写入错误等。以下是一个带有异常处理的客户端示例:

from pymodbus.client.sync import ModbusTcpClient

from pymodbus.exceptions import ConnectionException

def run_modbus_client_with_error_handling():

client = ModbusTcpClient('localhost', port=5020)

try:

if client.connect():

result = client.read_holding_registers(address=0, count=10, unit=1)

if not result.isError():

print("读取到的保持寄存器的值:", result.registers)

else:

print("读取失败:", result)

else:

print("无法连接到服务器")

except ConnectionException as e:

print("连接异常:", e)

finally:

client.close()

if name == "main":

run_modbus_client_with_error_handling()

  1. 日志记录

PyModbus 支持日志记录,可以方便地调试和监控程序的运行情况。以下是一个启用日志记录的示例:

import logging

from pymodbus.client.sync import ModbusTcpClient

配置日志记录

logging.basicConfig()

log = logging.getLogger()

log.setLevel(logging.DEBUG)

def run_modbus_client_with_logging():

client = ModbusTcpClient('localhost', port=5020)

if client.connect():

result = client.read_holding_registers(address=0, count=10, unit=1)

if not result.isError():

print("读取到的保持寄存器的值:", result.registers)

else:

print("读取失败:", result)

client.close()

else:

print("无法连接到服务器")

if name == "main":

run_modbus_client_with_logging()

通过以上步骤,你可以从入门到精通掌握 PyModbus 的使用,实现 Modbus 通信的各种功能。在实际应用中,还可以根据具体需求进行更复杂的开发,例如与数据库结合、实现多线程通信等。

相关推荐
亓才孓5 小时前
[Class类的应用]反射的理解
开发语言·python
小镇敲码人5 小时前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
摘星编程5 小时前
深入理解CANN ops-nn BatchNormalization算子:训练加速的关键技术
python
魔芋红茶5 小时前
Python 项目版本控制
开发语言·python
lili-felicity5 小时前
CANN批处理优化技巧:从动态批处理到流水线并行
人工智能·python
一个有梦有戏的人6 小时前
Python3基础:进阶基础,筑牢编程底层能力
后端·python
摘星编程6 小时前
解析CANN ops-nn中的Transpose算子:张量维度变换的高效实现
python
Liekkas Kono6 小时前
RapidOCR Python 贡献指南
开发语言·python·rapidocr
玄同7656 小时前
Python 后端三剑客:FastAPI/Flask/Django 对比与 LLM 开发选型指南
人工智能·python·机器学习·自然语言处理·django·flask·fastapi
爱吃泡芙的小白白6 小时前
环境数据多维关系探索利器:Pairs Plot 完全指南
python·信息可视化·数据分析·环境领域·pairs plot