You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python(pymodbus)读取Modbus UDP/IP数据时遇TypeError求助

Modbus UDP客户端使用RTU帧时出现TypeError的排查与解决

问题场景

现有一台采用Modbus协议发送数据的设备,使用以下Python代码接收设备信息:

from pymodbus.client.sync import ModbusTcpClient, ModbusUdpClient
from pymodbus.transaction import ModbusRtuFramer as ModbusFramer

client = ModbusUdpClient("109.125.128.232", port=50450, framer=ModbusFramer)
success = client.connect()

print(success)

read = client.read_holding_registers(address=100, unit=2)

运行代码后触发如下类型错误:

Traceback (most recent call last):
  File "C:\Users\hossein\Desktop\modebuspool\modebus.py", line 9, in <module>
    read = client.read_holding_registers(address=100, unit=2)
  File "C:\Users\hossein\AppData\Local\Programs\Python\Python37\lib\site-packages\pymodbus\client\common.py", line 114, in read_holding_registers
    return self.execute(request)
  File "C:\Users\hossein\AppData\Local\Programs\Python\Python37\lib\site-packages\pymodbus\client\sync.py", line 109, in execute
    return self.transaction.execute(request)
  File "C:\Users\hossein\AppData\Local\Programs\Python\Python37\lib\site-packages\pymodbus\transaction.py", line 178, in execute
    broadcast=broadcast
  File "C:\Users\hossein\AppData\Local\Programs\Python\Python37\lib\site-packages\pymodbus\transaction.py", line 274, in _transact
    size = self._send(packet)
  File "C:\Users\hossein\AppData\Local\Programs\Python\Python37\lib\site-packages\pymodbus\transaction.py", line 309, in _send
    return self.client.framer.sendPacket(packet)
  File "C:\Users\hossein\AppData\Local\Programs\Python\Python37\lib\site-packages\pymodbus\framer\rtu_framer.py", line 263, in sendPacket
    timeout = start + self.client.timeout
TypeError: unsupported operand type(s) for +: 'float' and 'NoneType'

错误原因

这个错误的核心是客户端的timeout参数为None:RTU帧处理器在计算超时时间时,需要将当前时间(浮点数)与客户端的timeout值相加,但timeout未被初始化,导致类型不兼容的运算错误。

出现该问题的具体诱因是:使用ModbusUdpClient搭配ModbusRtuFramer时,UDP客户端默认不会自动设置timeout,而RTU帧逻辑依赖这个参数完成超时计算。

解决方法

方法1:显式指定客户端超时参数

创建ModbusUdpClient实例时,手动添加timeout参数(单位为秒,可根据实际场景调整),示例如下:

from pymodbus.client.sync import ModbusUdpClient
from pymodbus.transaction import ModbusRtuFramer as ModbusFramer

# 显式设置timeout为3秒
client = ModbusUdpClient("109.125.128.232", port=50450, framer=ModbusFramer, timeout=3)
success = client.connect()

print(success)

read = client.read_holding_registers(address=100, unit=2)

方法2:确认并匹配设备的Modbus传输帧格式

RTU帧主要用于串行通信(如RS485/RS232),而UDP属于网络传输,多数网络Modbus设备使用的是Modbus TCP帧。如果设备实际采用的是Modbus TCP over UDP协议,可以直接移除framer参数,使用默认的TCP帧处理器:

from pymodbus.client.sync import ModbusUdpClient

# 不指定framer,使用默认的TCP帧逻辑
client = ModbusUdpClient("109.125.128.232", port=50450)
success = client.connect()

print(success)

read = client.read_holding_registers(address=100, unit=2)

内容的提问来源于stack exchange,提问作者hossein ghorbanzadeh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 17:05:25