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

树莓派3使用pymodbus写入输入寄存器及HMI显示问题咨询

解答:树莓派3上的PyModbus输入寄存器写入与HMI显示问题

一、关于使用PyModbus写入输入寄存器的说明

首先得明确:Modbus协议规范中,输入寄存器(Input Registers)是只读类型,对应的功能码是04(读取输入寄存器),标准协议里没有写入输入寄存器的功能码。如果你的设备确实支持写入输入寄存器(部分厂商自定义了功能),可以参考以下方式:

  1. 确认设备支持的写入功能码:有些设备可能用自定义功能码来写入输入寄存器,比如复用写保持寄存器的06/16功能码,这需要你查设备文档确认。
  2. 使用PyModbus发送自定义功能码请求:
from pymodbus.client.sync import ModbusTcpClient as ModbusClient

client = ModbusClient('192.168.4.189')
client.connect()

# 假设设备支持用功能码06写入输入寄存器(地址0,值200),需根据设备文档调整参数
rq = client.execute(0, 6, address=0, value=200)
# 检查写入结果
if not rq.isError():
    print("写入输入寄存器成功")
else:
    print(f"写入失败: {rq}")

client.close()

如果你是混淆了输入寄存器和保持寄存器,实际想写入的是保持寄存器,那你原有代码里的client.write_register(0,100)已经是正确写法(单个保持寄存器写入,功能码06),批量写入可以用client.write_registers(起始地址, [值列表])。

二、HMI Droid Studio无法显示保持寄存器值的排查与解决

你的代码能正常读取并打印寄存器值,但HMI不显示,大概率是参数不匹配或网络配置问题,按以下步骤逐一排查:

1. 检查地址偏移问题

PyModbus默认使用0-based地址(起始地址为0),而很多HMI工具(包括HMI Droid Studio)默认用1-based地址(起始地址为1)。比如你代码里读的是寄存器0,在HMI里需要设置为寄存器1,这是最常见的坑。

2. 确认Modbus功能码匹配

  • 你的代码用read_holding_registers,对应Modbus功能码03;
  • 在HMI Droid Studio中,要确保选择的寄存器类型是“保持寄存器”,功能码设置为03,别选错成输入寄存器(功能码04)。

3. 验证数据类型与字节序

  • 确认HMI设置的数据类型和你写入的一致:比如你写入的是16位无符号整数,HMI里也要选对应的类型,别误选成32位或有符号整数;
  • 部分设备和HMI存在字节序差异(大端/小端),如果值显示异常(比如写入100却显示25600),需要在HMI里调整字节序设置。

4. 检查网络与端口

  • 确认树莓派和HMI设备在同一个局域网,能互相ping通;
  • 树莓派的防火墙要开放502端口(Modbus TCP默认端口),可以用命令临时关闭防火墙测试:
sudo iptables -F
  • 检查PyModbus客户端连接的IP和端口是否和HMI设置一致,你的代码里用的是192.168.4.189,HMI里要填这个IP,端口设为502。

5. 优化你的测试代码

你的现有代码有部分截断,这里补全并优化,方便你测试:

from pymodbus.client.sync import ModbusTcpClient as ModbusClient
import time

Kanban1 = 0
# 明确指定Modbus TCP默认端口502
client = ModbusClient('192.168.4.189', port=502)
connection = client.connect()

if not connection:
    print("无法连接到Modbus服务器,请检查网络和设备状态")
else:
    # 先写入测试值,确保寄存器有数据
    write_rq = client.write_register(0, 100)
    if write_rq.isError():
        print(f"写入保持寄存器失败: {write_rq}")
    
    try:
        while True:
            rr = client.read_holding_registers(0, 50)
            if not rr.isError():
                print(f"读取到的寄存器值: {rr.registers}")
                if rr.registers[Kanban1] < 100:
                    # 补充你原来的逻辑
                    print(f"Kanban1的值小于100: {rr.registers[Kanban1]}")
            else:
                print(f"读取寄存器失败: {rr}")
            time.sleep(1)
    except KeyboardInterrupt:
        print("程序手动终止")
    finally:
        client.close()

总结

  • 输入寄存器标准为只读,若需写入必须确认设备是否支持自定义写入功能;
  • HMI不显示的核心问题通常是地址偏移、功能码不匹配或数据类型设置错误,按上面的步骤排查基本能解决。

内容的提问来源于stack exchange,提问作者Aditya fedriansyah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:37:03