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 通信的各种功能。在实际应用中,还可以根据具体需求进行更复杂的开发,例如与数据库结合、实现多线程通信等。

相关推荐
景彡先生8 小时前
Python Flask详解:从入门到实战,轻量级Web框架的魅力
前端·python·flask
JJJJ_iii8 小时前
【机器学习12】无监督学习:K-均值聚类与异常检测
人工智能·笔记·python·学习·机器学习·均值算法·聚类
Tony Bai9 小时前
从 Python 到 Go:我们失去了什么,又得到了什么?
开发语言·后端·python·golang
wudl55669 小时前
python字符串处理与正则表达式--之八
开发语言·python·正则表达式
程序员爱钓鱼9 小时前
Python编程实战 - 面向对象与进阶语法 - 继承与多态
后端·python·ipython
程序员爱钓鱼9 小时前
Python编程实战 - 面向对象与进阶语法 - 封装与私有属性
后端·python·ipython
nvd119 小时前
python异步编程 -- 理解协程函数和协程对象
开发语言·python
木土雨成小小测试员9 小时前
简单创建一个flask项目
后端·python·flask
java1234_小锋10 小时前
PyTorch2 Python深度学习 - transform预处理转换模块
开发语言·python·深度学习·pytorch2