如何处理Modbus异常0x5

时间:2018-11-02 14:38:09

标签: exception-handling qt5 modbus

我正在使用Qt5和QModbusTcpClient类编写Modbus客户端程序。这是我用来打开连接并阅读内容的代码:

QModbusClient *_modbus;

bool ModbusMaster::open(QString host, int port)
{
    // Disconnect and delete any existing instance
    if (_modbus)
    {
        _modbus->disconnectDevice();
        delete _modbus;
    }

    // Create and open the new connection
    _modbus = new QModbusTcpClient(this);
    _modbus->setConnectionParameter(QModbusDevice::NetworkPortParameter, port);
    _modbus->setConnectionParameter(QModbusDevice::NetworkAddressParameter, host);    

    _modbus->setTimeout(250);
    _modbus->setNumberOfRetries(1);

    return _modbus->connectDevice();
}
bool ModbusMaster::read(QModbusDataUnit::RegisterType type, int startAddress, quint16 count)
{
    if (!_modbus) return false;
    if (_modbus->state() != QModbusDevice::ConnectedState) return false;

    QModbusDataUnit req(type, startAddress, count);
    if (auto *reply = _modbus->sendReadRequest(req, _id))
    {
        if (!reply->isFinished()) connect(reply, &QModbusReply::finished, this, &ModbusMaster::readReady);
        else delete reply;
        return true;
    }
    return false;
}

void ModbusMaster::readReady()
{
    auto reply = qobject_cast<QModbusReply *>(sender());
    if (!reply) return;
    reply->deleteLater();

    if (reply->error() == QModbusDevice::NoError)
    {
        // do something
    }
    else if (reply->error() == QModbusDevice::ProtocolError)
    {
        qDebug() << QString("Read response error: %1 (Mobus exception: 0x%2)").
                                    arg(reply->errorString()).
                                    arg(reply->rawResult().exceptionCode(), -1, 16);
    } else {
        qDebug() << QString("Read response error: %1 (code: 0x%2)").
                                    arg(reply->errorString()).
                                    arg(reply->error(), -1, 16);
    }
}

有时,当我从远程设备读取内容时,设备会返回异常0x5。读official Modbus documentation,在第48页,我读到:

  

结合编程的专门用途   命令。   服务器已接受该请求,并且   处理它,但是会持续很长时间   必须这样做。此响应返回到   防止发生超时错误   客户。 客户接下来可以发布投票计划   完整的消息,以确定是否正在处理   完成。

[大胆是我的]

我找不到此“轮询程序完成消息”的描述,似乎我必须使用它来处理异常0x5。

我搜索错了吗?还有另一种方法可以处理此异常吗?

1 个答案:

答案 0 :(得分:1)

这取决于您使用的设备的类型。您只需要遵循设备手册中针对此特殊异常所描述的逻辑即可。

通常没有特殊的“程序完成”事件。这就是说,因为它是为0x5编写的-“与编程命令一起专门使用”。因此,您只需要轮询(读取)设备中的一些标志,这意味着导致此异常的设备内部过程已完成。

仅作为示例,我在继电保护装置中遇到了这样的异常,该异常是在其正在编写故障记录的过程中发出的。我只需要一段时间检查一下记录是否准备就绪。