使用pymodbus连接Modbus TCP设备成功但无法读取保持寄存器值求助
解决Pymodbus Modbus TCP无响应问题
针对你遇到的No response received, expected at least 8 bytes (0 received)错误,按以下步骤排查:
1. 确认Modbus服务端口与设备配置匹配
Modbus TCP默认端口是502,但部分设备会自定义端口。检查设备手册或配置界面的Modbus TCP服务端口,确保代码中ModbusTcpClient的port参数与之一致。
2. 验证从站地址(Slave ID)正确性
多数设备默认从站ID为1,但部分设备可能设为其他值(如255)。确认设备的从站ID配置,在read_holding_registers等请求中传入正确的slave参数。
3. 检查寄存器地址的偏移规则
注意设备的寄存器地址计数方式:
- Pymodbus默认使用0-based地址(起始地址从0开始)
- 部分设备文档标注的是1-based地址,此时需要将文档中的地址减1后传入请求
4. 确认设备Modbus TCP服务已启用且允许当前客户端访问
- 部分工业设备需要手动开启Modbus TCP服务,进入设备配置界面检查服务状态
- 有些设备会设置IP白名单,确保你的主机IP已被添加到允许列表中
5. 测试端口连通性(排除防火墙/网络拦截)
Ping通仅说明ICMP可达,但Modbus TCP端口可能被防火墙拦截。用以下命令测试端口是否开放:
# Linux/macOS nc -zv <设备IP> 502 # Windows(PowerShell) Test-NetConnection <设备IP> -Port 502
如果端口不通,检查设备端防火墙、主机端防火墙或中间网络设备的端口过滤规则。
6. 调整Pymodbus客户端超时与帧格式
- 增加超时时间:默认超时可能过短,初始化客户端时设置
timeout=5(单位:秒) - 若设备使用Modbus RTU over TCP而非标准Modbus TCP,需指定帧格式:
from pymodbus.framer.rtu_framer import ModbusRtuFramer client = ModbusTcpClient('<设备IP>', port=502, framer=ModbusRtuFramer, timeout=5)
7. 抓包定位问题
用Wireshark抓取主机与设备之间的网络包,过滤modbus协议:
- 若能看到发送的Modbus请求包但无响应:问题出在设备端(服务未运行、配置错误)
- 若看不到请求包:检查客户端代码是否正确发送请求,或本地网络是否有异常
示例代码
from pymodbus.client import ModbusTcpClient # 初始化客户端 client = ModbusTcpClient( '<设备IP>', port=502, timeout=5 ) # 确认连接 if not client.connect(): print("无法连接到设备") exit() try: # 读取保持寄存器:起始地址0(若设备是1-based则对应文档中的1),数量10,从站ID1 response = client.read_holding_registers(address=0, count=10, slave=1) if response.isError(): print(f"读取错误: {response}") else: print(f"寄存器值: {response.registers}") finally: client.close()
内容的提问来源于stack exchange,提问作者Gagandeep Kaur
相关产品推荐
相关产品推荐

