LINUX.ORG.RU

Сообщения alexandra

 

Ошибка Request timeout, но данные по Modbus получены

Форум — Development

Добрый день. Настраиваю modbus RTU для обмена данными приложения и PLC, но при отправке данных я получаю ошибку «Request timeout». При этом данные отправлены и получены контроллером (у меня стоит приложение на компьютере, которое может это отследить и показать). Я не могу понять, почему возникает эта ошибка. Сначала я думала увеличить время таймаута, но это ни на что не повлияло (при этом по ощущениям значение таймаута будто и не менялось вовсе). Потом я подумала, что, может, у меня посылается несколько раз пакет данных, когда первый нормально считывается, а второй выдает ошибку выхода времени, но при проверке через дебаггер часть кода, которая отвечает за полную передачу, даже не вызывается. Если у кого-нибудь будут предположения, что может быть не так, я буду рада проверить.

Код класса modbus:

modbus.h:

class QModbusClient;
class QModbusReply;

class Modbus : public QObject
{
    Q_OBJECT
public:
    Modbus(QObject *parent = nullptr);
    ~Modbus();
    QModbusDataUnit readRequest() const;
    QModbusDataUnit writeRequest() const;

private:
    void init();
    void on_writeButton_clickedRegisters(qint32 registers[], qint32 values[]);
    QModbusClient *modbusDevice;

    const int SERVER_ADDRESS = 1;
    const int START_ADDRESS = 0;
    const int AMOUNT = 24;
    const int WRITE_SIZE = 24;

    const int BAUDS = 9600;
    const int STOP_BITS = 1;
    const int DATA_BITS = 8;
    const QString PORT = "ttyUSB0";
    const int PARITY = QSerialPort::NoParity;
    const int RESPONSE_TIME = 250;
};
#endif // MODBUS_H

modbus.cpp:

    Modbus::Modbus(QObject *parent) :
    QObject(parent),
    modbusDevice(nullptr)
{
    init();
}

void Modbus::init() {
    modbusDevice = new QModbusRtuSerialMaster(this);
    connect(modbusDevice, &QModbusClient::errorOccurred, [this](QModbusDevice::Error) {
        emit sendData(modbusDevice->errorString());});
    qDebug() << "Error message: " << modbusDevice->errorString();
    if(modbusDevice) {
        connect(modbusDevice, &QModbusClient::stateChanged,this, &Modbus::onStateChanged);
    }

    if (modbusDevice->state() != QModbusDevice::ConnectedState) {
        modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,PORT);
        modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,PARITY);
        modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,BAUDS);
        modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,DATA_BITS);
        modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,STOP_BITS);
        modbusDevice->setTimeout(RESPONSE_TIME);
        modbusDevice->setNumberOfRetries(1);
        if (!modbusDevice->connectDevice()) {
            emit sendData(modbusDevice->errorString());
        }
    } else {
        modbusDevice->disconnectDevice();
    }
}

void Modbus::on_writeButton_clickedRegisters(qint32 registers[], qint32 values[])
{

    <часть кода>
    if (auto *lastRequest = modbusDevice->sendWriteRequest(writeUnit, SERVER_ADDRESS)) {
        if (!lastRequest->isFinished()) {
            connect(lastRequest, &QModbusReply::finished, this, [ lastRequest]() {
                if (lastRequest->error() == QModbusDevice::ProtocolError) {
                    qDebug()<<"1"<<lastRequest->errorString();
                } else if (lastRequest->error() != QModbusDevice::NoError) {
                    qDebug()<<"2"<<lastRequest->errorString();
                    //ошибка проходит через эту часть кода
                }
                lastRequest->deleteLater();
            });
        } else {
            qDebug()<<"yes send";   //это не вызывается
            lastRequest->deleteLater();
        }
    } else {
        qDebug()<<lastRequest->errorString();
    }
}

П.С. Особенности кода:

  1. У меня приложение, в котором много окон, взаимодействующих друг с другом и, соответственно, много файлов. Чтобы не создавать в каждом файле свой объект modbus, я создала класс, в котором обозначила глобальный объект класса Modbus, к которому обращается каждое окно, если ему это необходимо. Выглядит это так:
#ifndef GLOBALVARIABLE_H
#define GLOBALVARIABLE_H

#include "modbus.h"
inline Modbus connect_modbus = Modbus();

#endif // GLOBALVARIABLE_H
  1. Файлы не посылают одновременно запросы Modbus’у, так как у меня работает всего один поток, то есть запросы пересекаться не будут.

 ,

alexandra
()

RSS подписка на новые темы