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

相关推荐
VidDown6 小时前
24fps 转 25fps 不只是改个数字:帧率转换、PAL/NTSC 与音频补偿
python·网络协议·音视频·视频编解码·视频
死磕音视频8 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
凤山老林8 小时前
Spring Boot 接入国密 SM2/SM3/SM4 的一些实践记录
spring boot·后端·python
pride.li10 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉
databook10 小时前
用 Pydantic AI 从零搭建一个能干活的 AI Agent
人工智能·python
康小旺10 小时前
把 markitdown 做成 Windows 桌面版:拖进文档就出 Markdown,附 233MB→64MB 打包裁剪全过程
python
启观川11 小时前
数据结构与算法-第 3 章 常用算法-贪心算法
数据结构·笔记·python·算法·贪心算法
南笙北梦11 小时前
本地开源大模型多轮对话显存泄漏排查与修复实录
python
小羊没烦恼!11 小时前
如何在IIS6,7中部署ASP.NET网站?
数据库·后端·python·web安全·asp.net
钱栈up12 小时前
扫完 3.5 万文件后,我发现了 521 组散落的同名文件
爬虫·python·数据分析