diff --git a/Servo/include/ModbusMaster.h b/Servo/include/ModbusMaster.h index ebb6349..51fea7e 100644 --- a/Servo/include/ModbusMaster.h +++ b/Servo/include/ModbusMaster.h @@ -21,6 +21,8 @@ private: QModbusClient* _modbusDevice = nullptr; int _clientAddress; QModbusDataUnit _modbusReplyUnit; + QBitArray _coilsToWrite; + QVector _RegistersToWrite; public: explicit ModbusMaster(QObject* parent = nullptr); @@ -29,7 +31,9 @@ public: int startAddress, quint16 readSize); void checkForError(QModbusReply* _reply); - void modbusReplyRecieved(); + void writeRequest(QModbusDataUnit::RegisterType registerType, + int startAddress, + quint16 writeSize); //uncrustify off public slots: @@ -42,6 +46,7 @@ public slots: QBitArray getInputCoil(int startAddress, quint16 readSize); QVector getHoldingRegister(int startAddress, quint16 readSize); QVector getInputRegister(int startAddress, quint16 readSize); + void setSingleCoil(int startAddress, bool coilFlag); }; #endif //MODBUSMASTER_H diff --git a/Servo/include/ModbusWrapper.h b/Servo/include/ModbusWrapper.h index 791bf33..3cc1d25 100644 --- a/Servo/include/ModbusWrapper.h +++ b/Servo/include/ModbusWrapper.h @@ -21,11 +21,14 @@ public: ~ModbusWrapper(); void connectToDevice(ModbusConfig modbusConfig); void init(); + QBitArray getCoil(int startAddress, quint16 readSize); QBitArray getInputCoil(int startAddress, quint16 readSize); QVector getHoldingRegister(int startAddress, quint16 readSize); QVector getInputRegister(int startAddress, quint16 readSize); + void setSingleCoil(int startAddress, bool coilFlag); + signals: void connectOrder(ModbusConfig modbusConfig); void initOrder(); @@ -35,6 +38,8 @@ signals: quint16 readSize); QVector getInputRegisterOrder(int startAddress, quint16 readSize); + void setSingleCoilOrder(int startAddress, bool coilFlag); + //uncrustify off public slots: //uncrustify on diff --git a/Servo/src/ModbusMaster.cpp b/Servo/src/ModbusMaster.cpp index 3781d10..5717818 100644 --- a/Servo/src/ModbusMaster.cpp +++ b/Servo/src/ModbusMaster.cpp @@ -29,8 +29,6 @@ void ModbusMaster::init() { throw ServoException("Modbus Device Created Before Handle it"); } - - qDebug() << "internal init"; } /*************************************************************************************************/ @@ -66,8 +64,6 @@ void ModbusMaster::connectionStateChanged(QModbusDevice::State state) { throw ServoException("Connection wasnt prepared"); } - - qDebug() << "internal connect"; } /*************************************************************************************************/ @@ -174,6 +170,26 @@ QVector ModbusMaster::getInputRegister(int startAddress, quint16 readSi } } +/*************************************************************************************************/ +void ModbusMaster::setSingleCoil(int startAddress, bool coilFlag) +{ + try + { + _coilsToWrite.resize(1); + + if(coilFlag) + _coilsToWrite.setBit(0); + else + _coilsToWrite.clearBit(0); + + writeRequest(QModbusDataUnit::RegisterType::Coils, startAddress, 1); + } + catch(const ServoException& ex) + { + qDebug() << ex.what(); + } +} + /*************************************************************************************************/ void ModbusMaster::readRequest(QModbusDataUnit::RegisterType registerType, int startAddress, @@ -229,15 +245,41 @@ void ModbusMaster::checkForError(QModbusReply* _reply) } } -void ModbusMaster::modbusReplyRecieved() +/*************************************************************************************************/ +void ModbusMaster::writeRequest(QModbusDataUnit::RegisterType registerType, + int startAddress, + quint16 writeSize) { - auto reply = qobject_cast(sender()); + auto table = registerType; + QModbusDataUnit writeUnit = QModbusDataUnit(table, startAddress, writeSize); + for(int i = 0; i < writeUnit.valueCount(); i++) + { + if(table == QModbusDataUnit::Coils) + writeUnit.setValue(i, _coilsToWrite[i]); + else + writeUnit.setValue(i, _RegistersToWrite[i]); + } - if(!reply) - return; + if(auto* reply = _modbusDevice->sendWriteRequest(writeUnit, _clientAddress)) + { + if(!reply->isFinished()) + { + QEventLoop loop; + connect(reply, &QModbusReply::finished, &loop, + &QEventLoop::quit + ); + loop.exec(); - checkForError(reply); - _modbusReplyUnit = reply->result(); + checkForError(reply); + _modbusReplyUnit = reply->result(); - reply->deleteLater(); + reply->deleteLater(); + } + else + delete reply; //broadcast replies return immediately + } + else + { + throw ServoException(_modbusDevice->errorString()); + } } diff --git a/Servo/src/ModbusWrapper.cpp b/Servo/src/ModbusWrapper.cpp index 72e0930..93ca357 100644 --- a/Servo/src/ModbusWrapper.cpp +++ b/Servo/src/ModbusWrapper.cpp @@ -54,6 +54,12 @@ void ModbusWrapper::init() &ModbusMaster::getInputRegister, Qt::BlockingQueuedConnection); + connect(this, + &ModbusWrapper::setSingleCoilOrder, + &_modbusMaster, + &ModbusMaster::setSingleCoil, + Qt::BlockingQueuedConnection); + emit initOrder(); qDebug() << "init done"; @@ -62,44 +68,35 @@ void ModbusWrapper::init() /*************************************************************************************************/ QBitArray ModbusWrapper::getCoil(int startAddress, quint16 readSize) { - auto result = emit getCoilOrder(startAddress, readSize); - qDebug() << "getCoil done"; - - return result; + return emit getCoilOrder(startAddress, readSize); } /*************************************************************************************************/ QBitArray ModbusWrapper::getInputCoil(int startAddress, quint16 readSize) { - auto result = emit getInputCoilOrder(startAddress, readSize); - qDebug() << "getInputCoilOrder done"; - - return result; + return emit getInputCoilOrder(startAddress, readSize); } /*************************************************************************************************/ QVector ModbusWrapper::getHoldingRegister(int startAddress, quint16 readSize) { - auto result = emit getHoldingRegisterOrder(startAddress, readSize); - qDebug() << "getHoldingRegister done"; - - return result; + return emit getHoldingRegisterOrder(startAddress, readSize); } /*************************************************************************************************/ QVector ModbusWrapper::getInputRegister(int startAddress, quint16 readSize) { - auto result = emit getInputRegisterOrder(startAddress, readSize); - qDebug() << "getInputRegister done"; + return emit getInputRegisterOrder(startAddress, readSize); +} - return result; +/*************************************************************************************************/ +void ModbusWrapper::setSingleCoil(int startAddress, bool coilFlag) +{ + emit setSingleCoilOrder(startAddress, coilFlag); } /*************************************************************************************************/ void ModbusWrapper::connectToDevice(ModbusConfig modbusConfig) { emit connectOrder(modbusConfig); - qDebug() << "connect done"; } - -/*************************************************************************************************/ diff --git a/Test/MainWindow.cpp b/Test/MainWindow.cpp index 98d6972..e082fc6 100644 --- a/Test/MainWindow.cpp +++ b/Test/MainWindow.cpp @@ -94,3 +94,11 @@ void MainWindow::printRegisterDataFromClient(QVector uiHoldingRegisters } ui->textEditRead->setText(readedData); } + +void MainWindow::on_writeSingleCoil_clicked() +{ + int startAddress = ui->writeSingleCoilAddress->text().toInt(); + QBitArray uiCoils; + uiCoils.resize(1); + modbusWrapper.setSingleCoil(startAddress, ui->coilData->isChecked()); +} diff --git a/Test/MainWindow.h b/Test/MainWindow.h index 2eada0a..c8013ab 100644 --- a/Test/MainWindow.h +++ b/Test/MainWindow.h @@ -31,6 +31,7 @@ private slots: void on_connect_clicked(); //uncrustify on void on_readButton_clicked(); + void on_writeSingleCoil_clicked(); }; #endif //MAINWINDOW_H diff --git a/Test/MainWindow.ui b/Test/MainWindow.ui index 1fffe32..0b600f4 100644 --- a/Test/MainWindow.ui +++ b/Test/MainWindow.ui @@ -17,8 +17,8 @@ - 360 - 30 + 40 + 10 89 25 @@ -76,8 +76,8 @@ - 43 - 430 + 160 + 10 41 25 @@ -86,30 +86,11 @@ Table: - - - - 345 - 430 - 80 - 25 - - - - - 0 - 0 - - - - Read - - - 90 - 430 + 207 + 10 86 25 @@ -128,16 +109,120 @@ Result: - + - 40 - 200 - 257 - 221 + 10 + 70 + 311 + 381 + + + + Read Data From Device + + + + + 20 + 120 + 257 + 221 + + + + + + + 100 + 350 + 80 + 25 + + + + + 0 + 0 + + + + Read + + + + + + + 340 + 70 + 191 + 111 + + Write Single Coil + + + + + 10 + 20 + 61 + 23 + + + + Coil + + + + + + 70 + 40 + 113 + 25 + + + + + + + 10 + 40 + 71 + 26 + + + + address: + + + + + + 20 + 70 + 141 + 25 + + + + Write Single Coil + + + groupBox + connect + label_5 + label_4 + startAddress + readSize + label_6 + writeTable + label_9 + groupBox_2