Qt 6.11 is out! See what's new in the release
blog
Weird QModbusClient output
-
I have a simple class that reads data from a Modbus RTU device. Some code:
Modbus485::Modbus485(QObject *parent) : QThread(parent) { _device = nullptr; } bool Modbus485::open(QString serialPort, QString DE_bank, int DE_pin, QSerialPort::BaudRate baudRate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits) { _gpio->set(PIN_DE, false); if (_device) delete _device; _device = new QModbusRtuSerialMaster(); QObject::connect(_device, &QModbusClient::errorOccurred, [this](QModbusDevice::Error) { qInfo().noquote() << Utils::timestamp() << "[RS485] Error occurred:" << _device->errorString(); return false; }); _device->setConnectionParameter(QModbusDevice::SerialPortNameParameter, serialPort); _device->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, baudRate); _device->setConnectionParameter(QModbusDevice::SerialParityParameter, parity); _device->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBits); _device->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBits); _device->setTimeout(250); _device->setNumberOfRetries(0); if (!_device->connectDevice()) { qInfo().noquote() << Utils::timestamp() << "[RS485] Connection failed:" << _device->errorString(); return false; } return true; } bool Modbus485::read(int startAddress, quint16 count) { _gpio->set(PIN_DE, true); QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::HoldingRegisters, startAddress, count); if (auto *reply = _device->sendReadRequest(request, _serverAddress)) { QTimer::singleShot(30, [this]() { _gpio->set(PIN_DE, false); }); if (!reply->isFinished()) QObject::connect(reply, &QModbusReply::finished, [reply]() { if (reply->error() == QModbusDevice::NoError) { const QModbusDataUnit unit = reply->result(); qDebug() << unit.values(); // read ok!!! return true; } else if (reply->error() == QModbusDevice::ProtocolError) { qInfo().noquote() << Utils::timestamp() << "[RS485] Protocol error:" << reply->errorString() << reply->rawResult().exceptionCode(); return false; } else { qInfo().noquote() << Utils::timestamp() << "[RS485] Error occurred:" << reply->errorString(); return false; } reply->deleteLater(); }); else { qDebug() << "REPLY FINISHED!"; delete reply; return false; } } else { qInfo().noquote() << Utils::timestamp() << "[RS485] Generic error:" << _device->errorString(); _gpio->set(PIN_DE, false); return false; } return false; }But when I try to read something I get this debug output:
>> "Tx: 0x01030031000295c4" Debug: (RTU client) Sent Serial ADU: 0x01030031000295c4 ((null):0, (null)) Debug: (RTU client) Send failed: 0x0300310002 ((null):0, (null)) [RS485] Error occurred: Request timeout Debug: (RTU client) Sent Serial PDU: 0x0300310002 ((null):0, (null)) >> "Tx: 0x01030031000295c4" Debug: (RTU client) Sent Serial ADU: 0x01030031000295c4 ((null):0, (null)) Debug: (RTU client) Send successful: 0x0300310002 ((null):0, (null)) << 37 "Rx: 0x0103040000138d37" Debug: (RTU client) Response buffer: "0103040000138d37" ((null):0, (null)) Debug: (RTU client) Incomplete ADU received, ignoring ((null):0, (null)) << 39 "Rx: 0x0103040000138d3766" Debug: (RTU client) Response buffer: "0103040000138d3766" ((null):0, (null)) Debug: (RTU client) Received ADU: "0103040000138d3766" ((null):0, (null)) Debug: QVector(0, 5003)Questions:
- how can the sending fail?
- what does mean Sent Serial PDU after Send failed?
- why there are two receiving events, where the first one is incomplete? Is there anything I can set to avoid this?