Python中pymodbus模块详细讲解

 更新时间:2026年02月25日 11:09:11   作者:我是一只小青蛙888  
pymodbus是一个基于Python的开源库,用于实现Modbus通信协议,Modbus是一种广泛应用于工业自动化领域的串行通信协议,支持主从架构,这篇文章主要介绍了Python中pymodbus模块的相关资料,需要的朋友可以参考下

好的,我们来详细讲解一下 Python 的 pymodbus 模块。

概述

pymodbus 是一个用纯 Python 实现的 Modbus 协议栈。Modbus 是一种广泛应用于工业自动化领域的串行通信协议,常用于连接 PLC(可编程逻辑控制器)、传感器、仪表等设备。pymodbus 支持 Modbus TCP(基于 TCP/IP)和 Modbus RTU/ASCII(基于串行线路,如 RS-232/RS-485)两种主要传输方式。

核心功能与概念

  1. 协议类型:

    • Modbus TCP: 使用 TCP/IP 协议进行通信,端口号通常为 502。
    • Modbus RTU: 使用串行通信(RS-232/485),数据以二进制形式传输。
    • Modbus ASCII: 使用串行通信,数据以 ASCII 字符形式传输(较少见)。
  2. 角色:

    • Client (主站/Master): 发起请求的设备。通常由上位机(如运行 Python 程序的 PC)充当。
    • Server (从站/Slave): 响应请求的设备。通常是 PLC、传感器等现场设备。pymodbus 也可以用来模拟从站设备。
  3. 数据模型 (寄存器类型):

    • 线圈 (Coils): 1 位,可读写。通常表示开关量输出状态(如继电器开/关)。
    • 离散输入 (Discrete Inputs): 1 位,只读。通常表示开关量输入状态(如按钮按下/松开)。
    • 保持寄存器 (Holding Registers): 16 位,可读写。通常存储设备参数、设定值等。
    • 输入寄存器 (Input Registers): 16 位,只读。通常存储设备采集的实时数据(如温度、压力)。
  4. 常用功能码:

    • 01 (0x01): 读取线圈状态。
    • 02 (0x02): 读取离散输入状态。
    • 03 (0x03): 读取保持寄存器。
    • 04 (0x04): 读取输入寄存器。
    • 05 (0x05): 写单个线圈。
    • 06 (0x06): 写单个保持寄存器。
    • 15 (0x0F): 写多个线圈。
    • 16 (0x10): 写多个保持寄存器。

安装

pip install pymodbus

使用示例

作为客户端 (Client) - 读取数据

Modbus TCP 示例 (同步)

from pymodbus.client import ModbusTcpClient

# 连接到 Modbus TCP 服务器 (假设地址为 192.168.1.100, 端口 502)
client = ModbusTcpClient('192.168.1.100', port=502)
connection = client.connect()  # 建立连接

if connection:
    try:
        # 读取从站地址为 1 的设备上的保持寄存器 (功能码 03)
        # 起始地址 = 0, 读取数量 = 5 个寄存器
        response = client.read_holding_registers(address=0, count=5, slave=1)

        if not response.isError():
            # 获取寄存器值列表 (每个寄存器是 16 位无符号整数)
            registers = response.registers
            print(f"读取到的寄存器值: {registers}")
        else:
            print(f"读取错误: {response}")
    finally:
        client.close()  # 关闭连接
else:
    print("无法连接到 Modbus 服务器")

Modbus RTU 示例 (同步)

from pymodbus.client import ModbusSerialClient

# 连接到串口设备 (例如 COM3, 波特率 9600, 8N1)
# method='rtu' 表示使用 RTU 模式
client = ModbusSerialClient(
    port='COM3',
    baudrate=9600,
    bytesize=8,
    parity='N',
    stopbits=1,
    method='rtu'
)
connection = client.connect()

if connection:
    try:
        # 读取从站地址为 1 的设备上的输入寄存器 (功能码 04)
        # 起始地址 = 100, 读取数量 = 3 个寄存器
        response = client.read_input_registers(address=100, count=3, slave=1)

        if not response.isError():
            registers = response.registers
            print(f"读取到的输入寄存器值: {registers}")
        else:
            print(f"读取错误: {response}")
    finally:
        client.close()

作为服务器 (Server) - 提供数据

Modbus TCP 服务器示例

from pymodbus.server import StartTcpServer
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

# 定义数据存储
# 初始化各个数据区域 (起始地址, 初始值列表)
coils = ModbusSequentialDataBlock(0, [False] * 100)  # 100 个线圈,初始为 False
discrete_inputs = ModbusSequentialDataBlock(0, [True] * 100)  # 100 个离散输入,初始为 True
holding_registers = ModbusSequentialDataBlock(0, [0] * 100)  # 100 个保持寄存器,初始为 0
input_registers = ModbusSequentialDataBlock(0, [0] * 100)  # 100 个输入寄存器,初始为 0

# 创建从站上下文 (Slave Context),关联数据块
slave_context = ModbusSlaveContext(
    di=discrete_inputs,  # 离散输入
    co=coils,            # 线圈
    hr=holding_registers, # 保持寄存器
    ir=input_registers,   # 输入寄存器
)

# 创建服务器上下文 (Server Context),可以包含多个从站 (这里只定义了一个从站,地址为 1)
context = ModbusServerContext(slaves={1: slave_context}, single=False)

# 启动 TCP 服务器,监听所有接口 (0.0.0.0) 的 502 端口
StartTcpServer(context=context, address=("0.0.0.0", 502))

高级特性

  • 异步客户端: 使用 AsyncModbusTcpClientAsyncModbusSerialClient,配合 asyncio 库进行异步编程,提高并发性能。
  • 数据解析: 寄存器通常存储 16 位数据。对于 32 位浮点数、64 位整数等,需要将多个寄存器组合起来并按特定字节序解析。pymodbus 提供了 payload 模块中的工具(如 BinaryPayloadBuilder, BinaryPayloadDecoder)来帮助处理这些复杂数据类型。
  • 自定义数据存储: 可以继承 ModbusSparseDataBlock 或实现自己的存储类,用于更灵活地管理数据。
  • 回调: 服务器端可以设置回调函数,在数据被读取或写入时执行自定义逻辑。

注意事项

  1. 地址偏移: Modbus 协议中的寄存器地址通常从 0 开始。但有些设备手册或软件习惯使用从 1 开始的地址(如 40001 代表保持寄存器地址 0)。使用 pymodbus 时,传入的 address 参数通常是基于 0 的索引。务必查阅设备文档确认地址映射规则。
  2. 字节序 (Endianness): 处理多寄存器数据(如浮点数)时,必须了解设备使用的字节序(大端序 Big-Endian / 小端序 Little-Endian)和字序(高低字顺序)。
  3. 超时: 在创建客户端时设置合理的 timeout 参数,避免网络或设备响应慢导致程序长时间阻塞。
  4. 错误处理: 始终检查 response.isError() 并处理可能的异常(如超时、连接失败、Modbus 异常响应)。
  5. 资源释放: 使用 try...finally 确保连接 (client.close()) 或服务器 (StopTcpServer() / StopSerialServer()) 被正确关闭。

总结

pymodbus 是一个功能强大且灵活的 Python Modbus 库,适用于开发需要与工业设备通信的应用程序。通过理解 Modbus 协议基础、数据模型和 pymodbus 提供的接口,开发者可以高效地实现主站(数据采集、控制)或从站(模拟设备、数据提供)功能。务必参考官方文档和示例代码以获取更详细的信息:https://pymodbus.readthedocs.io/。

到此这篇关于Python中pymodbus模块详细讲解的文章就介绍到这了,更多相关Python pymodbus模块内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 学会Python数据可视化必须尝试这7个库

    学会Python数据可视化必须尝试这7个库

    数据可视化是使用一些绘图和图形更详细地理解数据的过程.最著名的库之一是 matplotlib,它可以绘制几乎所有您可以想象的绘图类型.matplotlib 唯一的问题是初学者很难掌握.在本文中,我将介绍七个数据可视化库,你可以尝试使用它们来代替 matplotlib ,需要的朋友可以参考下
    2021-06-06
  • pygame库pgu使用示例代码

    pygame库pgu使用示例代码

    pgu全称是Phil’s pyGame Utilities,是pygame的一组模块与脚本,其中还有gui集成了一些小模块,现在用pygame制作小游戏的人越来越多,但是pygame它是没有弹窗机制的,今天通过本文给大家介绍pygame库pgu使用示例代码,需要的朋友参考下吧
    2021-08-08
  • Python高效编程技巧

    Python高效编程技巧

    我已经使用Python编程有多年了,即使今天我仍然惊奇于这种语言所能让代码表现出的整洁和对DRY编程原则的适用。这些年来的经历让我学到了很多的小技巧和知识,大多数是通过阅读很流行的开源软件,如Django, Flask, Requests中获得的
    2013-01-01
  • Python中非常实用的一些功能和函数分享

    Python中非常实用的一些功能和函数分享

    这篇文章主要介绍了Python中非常实用的一些功能和函数分享,本文讲解了带任意数量参数的函数、使用Glob()查找文件、调试、生成唯一ID等内容,需要的朋友可以参考下
    2015-02-02
  • python实现将range()函数生成的数字存储在一个列表中

    python实现将range()函数生成的数字存储在一个列表中

    这篇文章主要介绍了python实现将range()函数生成的数字存储在一个列表中,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • Python绘制简单散点图的方法

    Python绘制简单散点图的方法

    这篇文章主要为大家详细介绍了Python绘制简单散点图的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Python使用ctypes调用C/C++的方法

    Python使用ctypes调用C/C++的方法

    今天小编就为大家分享一篇关于Python使用ctypes调用C/C++的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Jupyter Notebook读入csv文件时出错的解决方案

    Jupyter Notebook读入csv文件时出错的解决方案

    这篇文章主要介绍了Jupyter Notebook读入csv文件时出错的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Python列表切片操作实例探究(提取复制反转)

    Python列表切片操作实例探究(提取复制反转)

    在Python中,列表切片是处理列表数据非常强大且灵活的方法,本文将全面探讨Python中列表切片的多种用法,包括提取子列表、复制列表、反转列表等操作,结合丰富的示例代码进行详细讲解
    2024-01-01
  • Python添加进度条tqdm进阶使用实例

    Python添加进度条tqdm进阶使用实例

    这篇文章主要为大家介绍了Python添加进度条tqdm进阶使用实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06

最新评论