Как обработать исключение Modbus 0x5 - PullRequest
0 голосов
/ 02 ноября 2018

Я пишу клиентскую программу 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.

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

1 Ответ

0 голосов
/ 22 ноября 2018

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

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

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

...