Я пытаюсь запустить простой Modbus, и у меня возникают проблемы с последовательностью команд.
Сначала я понял, что не могу запускать несколько функций в функции. Если я сделаю это, то будет похоже, что соединение было установлено, но оно не работает. Если я создам 2 кнопки («Подключить», «Прочитать») и сначала щелкну «Подключиться», а затем «Прочитать», значит, подключение было успешным, и я могу прочитать ответ.
Итак, как я могу изменить код, чтобы он подключился к TCP Modbus, прочитал некоторые данные, а затем закрыл соединение с помощью одной функции / кнопки?
Это пример моего кода:
В файле modbusmaster.hpp:
#ifndef MODBUSMASTER_HPP
#define MODBUSMASTER_HPP
#include <QMainWindow>
#include <QModbusTcpClient>
#include <QModbusDevice>
#include <QModbusDataUnit>
#include <QDebug>
#include <QUrl>
class QModbusClient;
class ModbusMaster : public QMainWindow
{
Q_OBJECT
public:
explicit ModbusMaster(QWidget *parent = nullptr);
QModbusClient *_modbus = nullptr;
QModbusClient *modbusDevice = nullptr;
bool open(QString host, int port);
bool read(QModbusDataUnit::RegisterType type, int startAddress, quint16 count);
void readReady();
signals:
};
#endif // MODBUSMASTER_HPP
В файле modbusmaster. cpp:
#include "modbusmaster.hpp"
ModbusMaster::ModbusMaster(QWidget *parent) : QMainWindow(parent)
{
}
bool ModbusMaster::open(QString host, int port)
{
if (_modbus) {
_modbus->disconnectDevice();
delete _modbus;
_modbus = nullptr;
}
_modbus = new QModbusTcpClient(this);
connect(_modbus, &QModbusClient::errorOccurred, [this](QModbusDevice::Error) {
qDebug() << _modbus->errorString();
});
if(!_modbus) {
qDebug() << "Could not create Modbus Client.";
} else {
qDebug() << "Modbus Client is created.";
}
if (_modbus->state() != QModbusDevice::ConnectedState) {
_modbus->setConnectionParameter(QModbusDevice::NetworkPortParameter, port);
_modbus->setConnectionParameter(QModbusDevice::NetworkAddressParameter, host);
_modbus->setTimeout(1000);
_modbus->setNumberOfRetries(3);
if (!_modbus->connectDevice()) {
qDebug() << "Connect failed: " << _modbus->errorString();
} else {
qDebug() << "Modbus Client is Connected";
return true;
}
}
return false;
}
bool ModbusMaster::read(QModbusDataUnit::RegisterType type, int startAddress, quint16 count)
{
if (!_modbus) {
qDebug() << "!_modbus";
return false;
}
if (_modbus->state() != QModbusDevice::ConnectedState){
qDebug() << "Modbus Client is not Connected in read section";
return false;
}
QModbusDataUnit req(type, startAddress, count);
if (auto *reply = _modbus->sendReadRequest(req, 1))
{
qDebug() << "auto *reply = _modbus->sendReadRequest(req, 1)";
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)
{
qDebug() << reply;
}
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);
}
}
В файле mainwindow. cpp:
#include "modbusmaster.hpp"
.......
void mainwindow::on_button_clicked()
{
ModbusMaster test;
test.open("172.19.1.54", 54);
test.read(QModbusDataUnit::HoldingRegisters, 0, 10);
}
.......
"on_button_clicked" не работай. Он показывает только результаты qDebug ():
Modbus Client is created.
Modbus Client is Connected
Modbus Client is not Connected in read section
Если я использую 2 кнопки, одну для test.open, а другую с test.read, тогда все в порядке.
И что я здесь пропал?