Exception handling 如何处理Modbus异常0x5

Exception handling 如何处理Modbus异常0x5,exception-handling,qt5,modbus,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();

我正在使用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);
    }
}
QModbusClient*\u modbus;
bool ModbusMaster::打开(QString主机,int端口)
{
//断开并删除任何现有实例
如果(_modbus)
{
_modbus->disconnectDevice();
删除_modbus;
}
//创建并打开新连接
_modbus=新的QModbusTcpClient(此);
_modbus->setConnectionParameter(QModbusDevice::NetworkPortParameter,端口);
_modbus->setConnectionParameter(QModbusDevice::NetworkAddressParameter,主机);
_modbus->setTimeout(250);
_modbus->setNumberOfRetries(1);
返回_modbus->connectDevice();
}
bool ModbusMaster::read(QModbusDataUnit::RegisterType类型,int startAddress,quint16计数)
{
如果(!\u modbus)返回false;
如果(_modbus->state()!=QModbusDevice::ConnectedState)返回false;
QModbusDataUnit请求(类型、起始地址、计数);
如果(自动*回复=_modbus->sendReadRequest(请求,_id))
{
如果(!reply->isFinished())连接(reply,&QModbusReply::finished,this,&ModbusMaster::readreadready);
否则删除回复;
返回true;
}
返回false;
}
void ModbusMaster::readreadready()
{
自动回复=qobject_cast(发送方());
如果(!回复)返回;
回复->删除稍后();
如果(回复->错误()==QModbusDevice::NoError)
{
//做点什么
}
else if(回复->错误()==qmodbus设备::协议错误)
{
qDebug()错误字符串()。
arg(reply->rawResult().exceptionCode(),-1,16);
}否则{
qDebug()错误字符串()。
arg(回复->错误(),-1,16);
}
}
有时,当我从远程设备读取某些内容时,设备会返回异常0x5。在第48页,我读到:

与编程结合使用 命令。 服务器已接受该请求,正在运行 正在处理它,但需要很长的时间 必须这样做。此响应返回给 防止在中发生超时错误 客户客户端可以下一步发出轮询程序 完成消息以确定处理是否正确 已完成。

[粗体是我的]

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


我找错了吗?是否有其他方法处理此异常?

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

一般来说,没有特殊的“程序完成”事件。这意味着,正如为0x5编写的一样——“与编程命令结合使用的专用工具”。因此,您只需轮询(读取)设备中的某些标志,这意味着导致此异常的设备内部进程已完成


举个例子,我在继电保护装置中遇到过这样的异常情况,它是在写干扰记录的过程中发出的。我只需要在一段时间内检查记录是否准备就绪。

明白了。我认为doc有误导性,因为它用大写字母写“Poll Program Complete”,就像是Modbus标准的一条众所周知的消息一样。