使用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
相关产品推荐
相关产品推荐

