From d26d25f6611411365f361f82b3f8b84baa373662 Mon Sep 17 00:00:00 2001 From: nasicurious Date: Tue, 2 Nov 2021 21:01:10 +0330 Subject: [PATCH] Add GetCoil --- Servo/include/ModbusMaster.h | 12 ++++ Servo/include/ModbusWrapper.h | 3 + Servo/src/ModbusMaster.cpp | 96 ++++++++++++++++++++++++++++ Servo/src/ModbusWrapper.cpp | 16 +++++ Test/MainWindow.cpp | 36 +++++++++++ Test/MainWindow.h | 2 + Test/MainWindow.ui | 115 +++++++++++++++++++++++++++++++++- 7 files changed, 278 insertions(+), 2 deletions(-) diff --git a/Servo/include/ModbusMaster.h b/Servo/include/ModbusMaster.h index 732b2f4..5f9e6a9 100644 --- a/Servo/include/ModbusMaster.h +++ b/Servo/include/ModbusMaster.h @@ -3,11 +3,14 @@ #include #include +#include +#include #include "ServoException.h" #include "ModbusConfig.h" class QModbusClient; +class QModbusReply; class ModbusMaster : public QObject { @@ -17,16 +20,25 @@ private: bool _initialized = false; QModbusClient* _modbusDevice = nullptr; int _clientAddress; + QModbusDataUnit _modbusReplyUnit; public: explicit ModbusMaster(QObject* parent = nullptr); + void readRequest(QModbusDataUnit::RegisterType registerType, + int startAddress, + quint16 readSize); + void checkForError(QModbusReply* _reply); + void modbusReplyRecieved(); + //uncrustify off public slots: //uncrustify on void init(); + void connectToDevice(ModbusConfig modbusConfig); void connectionStateChanged(QModbusDevice::State state); + QBitArray getCoil(int startAddress, quint16 readSize); }; #endif //MODBUSMASTER_H diff --git a/Servo/include/ModbusWrapper.h b/Servo/include/ModbusWrapper.h index 8c92459..2980a7a 100644 --- a/Servo/include/ModbusWrapper.h +++ b/Servo/include/ModbusWrapper.h @@ -3,6 +3,7 @@ #include #include +#include #include "ModbusMaster.h" #include "ModbusConfig.h" @@ -20,10 +21,12 @@ public: ~ModbusWrapper(); void connectToDevice(ModbusConfig modbusConfig); void init(); + QBitArray getCoil(int startAddress, quint16 readSize); signals: void connectOrder(ModbusConfig modbusConfig); void initOrder(); + QBitArray getCoilOrder(int startAddress, quint16 readSize); //uncrustify off public slots: diff --git a/Servo/src/ModbusMaster.cpp b/Servo/src/ModbusMaster.cpp index 1c315ab..657e507 100644 --- a/Servo/src/ModbusMaster.cpp +++ b/Servo/src/ModbusMaster.cpp @@ -1,6 +1,7 @@ #include "ModbusMaster.h" #include +#include ModbusMaster::ModbusMaster(QObject* parent) : QObject(parent) { @@ -68,3 +69,98 @@ void ModbusMaster::connectionStateChanged(QModbusDevice::State state) qDebug() << "internal connect"; } + +/*************************************************************************************************/ +QBitArray ModbusMaster::getCoil(int startAddress, quint16 readSize) +{ + try + { + readRequest(QModbusDataUnit::RegisterType::Coils, startAddress, readSize); + auto unit = _modbusReplyUnit; + + QBitArray coils; + auto num = unit.valueCount(); + coils.resize(static_cast(num)); + for(uint i = 0; i < num; i++) + { + if(unit.value(static_cast(i)) == 1) + coils.setBit(i); + else + coils.clearBit(i); + } + + return coils; + } + catch(const ServoException& ex) + { + qDebug() << ex.what(); + } +} + +/*************************************************************************************************/ +void ModbusMaster::readRequest(QModbusDataUnit::RegisterType registerType, + int startAddress, + quint16 readSize) +{ + auto table = registerType; + + auto reply = _modbusDevice->sendReadRequest(QModbusDataUnit(table, startAddress, readSize), + _clientAddress); + if(reply) + { + if(!reply->isFinished()) + { + QEventLoop loop; + connect(reply, + &QModbusReply::finished, + &loop, + &QEventLoop::quit + ); + loop.exec(); + + checkForError(reply); + _modbusReplyUnit = reply->result(); + + reply->deleteLater(); + } + else + delete reply; //broadcast replies return immediately + } + else + { + throw ServoException(_modbusDevice->errorString()); + } +} + +/*************************************************************************************************/ +void ModbusMaster::checkForError(QModbusReply* _reply) +{ + if(_reply->error() == QModbusDevice::NoError) + return; + + if(_reply->error() == QModbusDevice::ProtocolError) + { + throw ServoException(tr("Read response error: %1 (Mobus exception: 0x%2)"). + arg(_reply->errorString()). + arg(_reply->rawResult().exceptionCode(), -1, 16)); + } + else + { + throw ServoException(tr("Read response error: %1 (code: 0x%2)"). + arg(_reply->errorString()). + arg(_reply->error(), -1, 16)); + } +} + +void ModbusMaster::modbusReplyRecieved() +{ + auto reply = qobject_cast(sender()); + + if(!reply) + return; + + checkForError(reply); + _modbusReplyUnit = reply->result(); + + reply->deleteLater(); +} diff --git a/Servo/src/ModbusWrapper.cpp b/Servo/src/ModbusWrapper.cpp index 1267781..84ad915 100644 --- a/Servo/src/ModbusWrapper.cpp +++ b/Servo/src/ModbusWrapper.cpp @@ -33,15 +33,31 @@ void ModbusWrapper::init() &modbusMaster, &ModbusMaster::connectToDevice, Qt::BlockingQueuedConnection); + connect(this, + &ModbusWrapper::getCoilOrder, + &modbusMaster, + &ModbusMaster::getCoil, + Qt::BlockingQueuedConnection); emit initOrder(); qDebug() << "init done"; } +/*************************************************************************************************/ +QBitArray ModbusWrapper::getCoil(int startAddress, quint16 readSize) +{ + auto result = emit getCoilOrder(startAddress, readSize); + qDebug() << "getCoil done"; + + return result; +} + /*************************************************************************************************/ void ModbusWrapper::connectToDevice(ModbusConfig modbusConfig) { emit connectOrder(modbusConfig); qDebug() << "connect done"; } + +/*************************************************************************************************/ diff --git a/Test/MainWindow.cpp b/Test/MainWindow.cpp index ca1490f..f60ab69 100644 --- a/Test/MainWindow.cpp +++ b/Test/MainWindow.cpp @@ -6,6 +6,11 @@ MainWindow::MainWindow(QWidget* parent) , ui(new Ui::MainWindow) { ui->setupUi(this); + + ui->writeTable->addItem(tr("Coils"), 0); + ui->writeTable->addItem(tr("Discrete Inputs"), 1); + ui->writeTable->addItem(tr("Input Registers"), 2); + ui->writeTable->addItem(tr("Holding Registers"), 3); } /*************************************************************************************************/ @@ -35,3 +40,34 @@ void MainWindow::on_connect_clicked() qDebug() << ex.what(); } } + +void MainWindow::on_readButton_clicked() +{ + int startAddress = ui->startAddress->text().toInt(); + int numberOfEntries = ui->readSize->text().toInt(); + switch(ui->writeTable->currentData().toInt()) + { + case 0: + printCoilsDataFromClient(modbusWrapper.getCoil(startAddress, + static_cast(numberOfEntries))); + break; + //case 1: printCoilsDataFromSlave(modbusWrapper->getInputCoil(startAddress,static_cast(numberOfEntries))); + //break; + //case 2: printRegisterDataFromSlave(modbusWrapper->getInputRegister(startAddress,static_cast(numberOfEntries))); + //break; + //case 3: printRegisterDataFromSlave(modbusWrapper->getHoldingRegister(startAddress,static_cast(numberOfEntries))); + //break; + } +} + +void MainWindow::printCoilsDataFromClient(QBitArray uiCoils) +{ + QString readedData; + for(int i = 0; i < uiCoils.count(); i++) + { + const QString entry = tr("Number: %1, Value: %2").arg(i) + .arg(QString::number(uiCoils[i])); + readedData += (entry + "\n"); + } + ui->textEditRead->setText(readedData); +} diff --git a/Test/MainWindow.h b/Test/MainWindow.h index a86b711..cc2c3d8 100644 --- a/Test/MainWindow.h +++ b/Test/MainWindow.h @@ -23,11 +23,13 @@ private: public: MainWindow(QWidget* parent = nullptr); ~MainWindow(); + void printCoilsDataFromClient(QBitArray uiCoils); //uncrustify off private slots: void on_connect_clicked(); //uncrustify on + void on_readButton_clicked(); }; #endif //MAINWINDOW_H diff --git a/Test/MainWindow.ui b/Test/MainWindow.ui index 594c3eb..1fffe32 100644 --- a/Test/MainWindow.ui +++ b/Test/MainWindow.ui @@ -17,8 +17,8 @@ - 420 - 40 + 360 + 30 89 25 @@ -27,6 +27,117 @@ Connect + + + + 40 + 142 + 126 + 25 + + + + Number of values: + + + + + + 40 + 110 + 126 + 26 + + + + Start address: + + + + + + 170 + 110 + 113 + 25 + + + + + + + 170 + 140 + 113 + 25 + + + + + + + 43 + 430 + 41 + 25 + + + + Table: + + + + + + 345 + 430 + 80 + 25 + + + + + 0 + 0 + + + + Read + + + + + + 90 + 430 + 86 + 25 + + + + + + + 40 + 167 + 126 + 17 + + + + Result: + + + + + + 40 + 200 + 257 + 221 + + +