Как обрабатывать исключение Modbus 0x5

Я пишу клиентскую программу Modbus, используя Qt5 и класс QModbusTcpClient. Вот код, который я использую для открытия соединения и чтения чего-либо:

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. Читая официальную документацию Modbus, на странице 48 я прочитал:

Специализированное использование в сочетании с командами программирования. Сервер принял запрос и обрабатывает его, но для этого потребуется длительное время. Этот ответ возвращается, чтобы предотвратить возникновение ошибки тайм-аута на клиенте. Затем клиент может отправить сообщение о завершении программы опроса, чтобы определить, завершена ли обработка.

[жирный мой]

Я не могу найти описание этого «Сообщения о завершении программы опроса», которое, кажется, я должен использовать для обработки исключения 0x5.

Я неправильно искал? Есть ли другой способ обработать это исключение?


person Mark    schedule 02.11.2018    source источник


Ответы (1)


Это зависит от типа оборудования, с которым вы работаете. Вам просто нужно следовать логике, описанной в руководстве по оборудованию для этого конкретного исключения.

Как правило, специального события «Завершение программы» не существует. Значит, как написано для 0x5 - "Специальное использование совместно с командами программирования". Таким образом, вам просто нужно опросить (прочитать) какой-либо флаг с вашего устройства, означающий, что внутренний процесс в устройстве, вызвавший это исключение, завершен.

Просто, например, я встречал такое исключение в устройстве релейной защиты, которое выдавало его, когда оно находилось в процессе записи протокола о нарушении. Мне оставалось только проверить готовность этой записи через какое-то время.

person grapes    schedule 22.11.2018
comment
Понятно. Я думаю, что документ вводит в заблуждение, потому что он пишет Poll Program Complete заглавными буквами, как если бы это было известное сообщение стандарта Modbus. - person Mark; 23.11.2018