Python中pymodbus模块详细讲解

Written by

in

文章目录
  • pymodbus 是一个用纯 Python 实现的 Modbus 协议栈。Modbus 是一种广泛应用于工业自动化领域的串行通信协议,常用于连接 PLC(可编程逻辑控制器)、传感器、仪表等设备。pymodbus 支持 Modbus TCP(基于 TCP/IP)和 Modbus RTU/ASCII(基于串行线路,如 RS-232/RS-485)两种主要传输方式。
  • 协议类型: Modbus TCP: 使用 TCP/IP 协议进行通信,端口号通常为 502。 Modbus RTU: 使用串行通信(RS-232/485),数据以二进制形式传输。 Modbus ASCII: 使用串行通信,数据以 ASCII 字符形式传输(较少见)。 角色: Client (主站/Master): 发起请求的设备。通常由上位机(如运行 Python 程序的 PC)充当。 Server (从站/Slave): 响应请求的设备。通常是 PLC、传感器等现场设备。pymodbus 也可以用来模拟从站设备。 数据模型 (寄存器类型): 线圈 (Coils): 1 位,可读写。通常表示开关量输出状态(如继电器开/关)。 离散输入 (Discrete Inputs): 1 位,只读。通常表示开关量输入状态(如按钮按下/松开)。 保持寄存器 (Holding Registers): 16 位,可读写。通常存储设备参数、设定值等。 输入寄存器 (Input Registers): 16 位,只读。通常存储设备采集的实时数据(如温度、压力)。 常用功能码: 01 (0x01): 读取线圈状态。 02 (0x02): 读取离散输入状态。 03 (0x03): 读取保持寄存器。 04 (0x04): 读取输入寄存器。 05 (0x05): 写单个线圈。 06 (0x06): 写单个保持寄存器。 15 (0x0F): 写多个线圈。 16 (0x10): 写多个保持寄存器。
  • pip install pymodbus
  • 异步客户端: 使用 AsyncModbusTcpClient 或 AsyncModbusSerialClient,配合 asyncio 库进行异步编程,提高并发性能。 数据解析: 寄存器通常存储 16 位数据。对于 32 位浮点数、64 位整数等,需要将多个寄存器组合起来并按特定字节序解析。pymodbus 提供了 payload 模块中的工具(如 BinaryPayloadBuilder, BinaryPayloadDecoder)来帮助处理这些复杂数据类型。 自定义数据存储: 可以继承 ModbusSparseDataBlock 或实现自己的存储类,用于更灵活地管理数据。 回调: 服务器端可以设置回调函数,在数据被读取或写入时执行自定义逻辑。
  • 地址偏移: Modbus 协议中的寄存器地址通常从 0 开始。但有些设备手册或软件习惯使用从 1 开始的地址(如 40001 代表保持寄存器地址 0)。使用 pymodbus 时,传入的 address 参数通常是基于 0 的索引。务必查阅设备文档确认地址映射规则。 字节序 (Endianness): 处理多寄存器数据(如浮点数)时,必须了解设备使用的字节序(大端序 Big-Endian / 小端序 Little-Endian)和字序(高低字顺序)。 超时: 在创建客户端时设置合理的 timeout 参数,避免网络或设备响应慢导致程序长时间阻塞。 错误处理: 始终检查 response.isError() 并处理可能的异常(如超时、连接失败、Modbus 异常响应)。 资源释放: 使用 try…finally 确保连接 (client.close()) 或服务器 (StopTcpServer() / StopSerialServer()) 被正确关闭。
  • pymodbus 是一个功能强大且灵活的 Python Modbus 库,适用于开发需要与工业设备通信的应用程序。通过理解 Modbus 协议基础、数据模型和 pymodbus 提供的接口,开发者可以高效地实现主站(数据采集、控制)或从站(模拟设备、数据提供)功能。务必参考官方文档和示例代码以获取更详细的信息:https://pymodbus.readthedocs.io/。 到此这篇关于Python中pymodbus模块详细讲解的文章就介绍到这了,更多相关Python pymodbus模块内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: python pymodbus模块的具体使用 python如何用pymodbus库进行modbus tcp通信
  • 目录
    • 概述
    • 核心功能与概念
    • 安装
    • 使用示例
      • 作为客户端 (Client) – 读取数据
        • Modbus TCP 示例 (同步)
        • Modbus RTU 示例 (同步)
      • 作为服务器 (Server) – 提供数据
        • Modbus TCP 服务器示例
    • 高级特性
      • 注意事项
        • 总结

          好的,我们来详细讲解一下 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
          

          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 服务器")
          

          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()
          

          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 pymodbus模块的具体使用
          • python如何用pymodbus库进行modbus tcp通信

          站内搜索