Modbus TCP客户端脚本读取传感器值报错,求解决方案
解决Modbus客户端读取传感器数值的错误问题
错误原因分析
你遇到的IllegalFunction异常,本质是用错了Modbus功能码:
read_coils()对应功能码01,用于读取离散输出线圈(开关量,比如继电器状态),而传感器数值属于模拟量,根本不存在线圈类型的存储区中。- 服务器收到不匹配的功能码请求后,返回非法功能的异常响应,这也是你拿到
ExceptionResponse对象而非正常结果的原因。
正确解决步骤
1. 确认映射表关键信息
你需要从Modbus映射表中找到黄色高亮传感器的两个核心信息:
- 寄存器类型:传感器数值一般存储在「保持寄存器(功能码03)」或「输入寄存器(功能码04)」中,前者支持读写,后者为只读(通常用于存储传感器采集的原始数据)
- 地址规则:注意Modbus地址的两种标注方式:
- 1-based地址:比如标注为
30500(3开头代表保持寄存器),转换成pymodbus需要的0-based地址,计算方式为30500 - 30001 = 499 - 0-based地址:如果映射表直接标注为
500,则直接使用该数值即可
- 1-based地址:比如标注为
2. 修改客户端脚本
根据寄存器类型选择对应的读取函数,同时修正地址,以下是两种常见场景的示例:
场景1:传感器在保持寄存器(地址对应映射表30500)
from pymodbus.client import ModbusTcpClient client = ModbusTcpClient('192.168.0.111') # 先确认连接成功 if not client.connect(): print("连接Modbus服务器失败") client.close() exit() # 读取保持寄存器:0-based地址499,读取1个寄存器 result = client.read_holding_registers(address=499, count=1) # 判断读取结果是否正常 if hasattr(result, 'registers'): print(f"传感器数值:{result.registers[0]}") else: print(f"读取错误:{result}") client.close()
场景2:传感器在输入寄存器
只需把read_holding_registers替换为read_input_registers,地址计算逻辑同上:
# 替换成输入寄存器读取函数 result = client.read_input_registers(address=499, count=1)
3. 额外注意事项
- 部分设备可能需要指定端口(默认Modbus TCP端口是502),如果你的服务器使用了其他端口,初始化客户端时要补充端口参数:
ModbusTcpClient('192.168.0.111', port=5020) - 如果读取的是16位以上的数值(比如32位浮点数),需要读取多个寄存器后再根据映射表的编码规则做数据解析
内容的提问来源于stack exchange,提问作者bbartling
相关产品推荐
相关产品推荐

