寄存器读取错误:Modbus 错误:[输入/输出] Modbus 错误:[无效消息] 未收到响应,预计至少 4 个字节(收到 0 个)

问题描述 投票:0回答:1

我有一个质量流量控制器(voegtlin red-y smart 系列),我想在其中设置气体体积流量并读取当前气体体积流量和温度。通信通过 Modbus RTU 进行。我设法使用正确的参数连接 MFC。 它已连接到我的 PC,因此无需使用以太网。

import logging
from pymodbus.client import ModbusSerialClient as ModbusClient
from pymodbus.exceptions import ModbusIOException
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder
from datetime import datetime

# Configure the logger
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Establish connection to the Modbus device
client = ModbusClient(method="rtu", port='COM3', stopbits=2, bytesize=8, parity='N', baudrate=57600, timeout=2)
logger.info("Establishing connection: %s", client.connect())


def set_gas_flow_set_point(client, set_point):
    try:
        # You can set the set point for the volume flow here
        set_point_gas_flow = 2

        # Code to set the set point for the volume flow
        set_point_registers = set_gas_flow_set_point(client, set_point_gas_flow)

        # Code to set the set point for the gas flow
        builder = BinaryPayloadBuilder(byteorder=Endian.Big)
        builder.add_32bit_float(set_point)
        client.write_registers(0x0006, builder.to_registers(), unit=2)

    except Exception as e:
        logger.error("Error setting set point: %s", e)


def read_current_measurements(client):
    try:
        # Read gas flow
        gas_flow_result = client.read_holding_registers(0x0000, 2, unit=2)
        if gas_flow_result.isError():
            logger.error("Error reading gas flow: %s", gas_flow_result)
            return None, None

        decoder = BinaryPayloadDecoder.fromRegisters(gas_flow_result.registers, byteorder=Endian.Big)
        current_gas_flow = decoder.decode_32bit_float()

        # Read temperature
        gas_temp_result = client.read_holding_registers(0x0002, 2, unit=2)
        if gas_temp_result.isError():
            logger.error("Error reading gas temperature: %s", gas_temp_result)
            return None, None

        decoder = BinaryPayloadDecoder.fromRegisters(gas_temp_result.registers, byteorder=Endian.Big)
        gas_temperature = decoder.decode_32bit_float()

        return current_gas_flow, gas_temperature

    except ModbusIOException as e:
        logger.error("Modbus communication error: %s", e)
        return None, None

    except Exception as e:
        logger.error("Unknown error reading measurements: %s", e)
        return None, None


current_gas_flow, gas_temperature = read_current_measurements(client)

if current_gas_flow is not None and gas_temperature is not None:
    logger.info("Current gas flow: %s", current_gas_flow)
    logger.info("Gas temperature: %s", gas_temperature)
else:
    logger.error("Error reading measurements.")

client.close()

这是我尝试运行代码时在终端中得到的答案:

INFO:main:建立连接:True 错误:main:读取气体流量时出错:Modbus 错误:[输入/输出] Modbus 错误:[无效消息] 未收到响应,预计至少 4 个字节(收到 0 个字节) 错误:主要:读取测量值时出错。

我的代码似乎无法读取寄存器。我使用记录器来获取更具体的错误通知。如果没有记录器命令,我总是收到错误:“ModbusIOException”对象没有属性“寄存器”

我对 Python 和 Modbus 还很陌生,所以请尽力解释你建议的更正。

感谢您提前的帮助。

python modbus pymodbus
1个回答
0
投票

Pymodbus v2 使用参数

unit
来识别从站,如此示例

所示
rr = client.read_coils(1, 1, unit=UNIT)

在版本 3 中,参数更改如下 如本示例所示

rr = client.read_coils(1, 1, slave=SLAVE)

在最初的 V3 版本中,仍处理

unit
参数(发出警告)。然而,在后续版本中,情况发生了变化(我相信
unit
现在已被忽略)。

请注意,Modbus RTU 规范使用术语“从站”,而 TCP 规范将其更改为“单元”(实际上是相同的字段)。

© www.soinside.com 2019 - 2024. All rights reserved.