Browse Source

Add GetCoil

test
nasicurious 3 years ago
parent
commit
d26d25f661
  1. 12
      Servo/include/ModbusMaster.h
  2. 3
      Servo/include/ModbusWrapper.h
  3. 96
      Servo/src/ModbusMaster.cpp
  4. 16
      Servo/src/ModbusWrapper.cpp
  5. 36
      Test/MainWindow.cpp
  6. 2
      Test/MainWindow.h
  7. 115
      Test/MainWindow.ui

12
Servo/include/ModbusMaster.h

@ -3,11 +3,14 @@
#include <QObject> #include <QObject>
#include <QModbusDevice> #include <QModbusDevice>
#include <QBitArray>
#include <QModbusDataUnit>
#include "ServoException.h" #include "ServoException.h"
#include "ModbusConfig.h" #include "ModbusConfig.h"
class QModbusClient; class QModbusClient;
class QModbusReply;
class ModbusMaster : public QObject class ModbusMaster : public QObject
{ {
@ -17,16 +20,25 @@ private:
bool _initialized = false; bool _initialized = false;
QModbusClient* _modbusDevice = nullptr; QModbusClient* _modbusDevice = nullptr;
int _clientAddress; int _clientAddress;
QModbusDataUnit _modbusReplyUnit;
public: public:
explicit ModbusMaster(QObject* parent = nullptr); explicit ModbusMaster(QObject* parent = nullptr);
void readRequest(QModbusDataUnit::RegisterType registerType,
int startAddress,
quint16 readSize);
void checkForError(QModbusReply* _reply);
void modbusReplyRecieved();
//uncrustify off //uncrustify off
public slots: public slots:
//uncrustify on //uncrustify on
void init(); void init();
void connectToDevice(ModbusConfig modbusConfig); void connectToDevice(ModbusConfig modbusConfig);
void connectionStateChanged(QModbusDevice::State state); void connectionStateChanged(QModbusDevice::State state);
QBitArray getCoil(int startAddress, quint16 readSize);
}; };
#endif //MODBUSMASTER_H #endif //MODBUSMASTER_H

3
Servo/include/ModbusWrapper.h

@ -3,6 +3,7 @@
#include <QObject> #include <QObject>
#include <QThread> #include <QThread>
#include <QBitArray>
#include "ModbusMaster.h" #include "ModbusMaster.h"
#include "ModbusConfig.h" #include "ModbusConfig.h"
@ -20,10 +21,12 @@ public:
~ModbusWrapper(); ~ModbusWrapper();
void connectToDevice(ModbusConfig modbusConfig); void connectToDevice(ModbusConfig modbusConfig);
void init(); void init();
QBitArray getCoil(int startAddress, quint16 readSize);
signals: signals:
void connectOrder(ModbusConfig modbusConfig); void connectOrder(ModbusConfig modbusConfig);
void initOrder(); void initOrder();
QBitArray getCoilOrder(int startAddress, quint16 readSize);
//uncrustify off //uncrustify off
public slots: public slots:

96
Servo/src/ModbusMaster.cpp

@ -1,6 +1,7 @@
#include "ModbusMaster.h" #include "ModbusMaster.h"
#include <QModbusRtuSerialMaster> #include <QModbusRtuSerialMaster>
#include <QEventLoop>
ModbusMaster::ModbusMaster(QObject* parent) : QObject(parent) ModbusMaster::ModbusMaster(QObject* parent) : QObject(parent)
{ {
@ -68,3 +69,98 @@ void ModbusMaster::connectionStateChanged(QModbusDevice::State state)
qDebug() << "internal connect"; 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<int>(num));
for(uint i = 0; i < num; i++)
{
if(unit.value(static_cast<int>(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<QModbusReply*>(sender());
if(!reply)
return;
checkForError(reply);
_modbusReplyUnit = reply->result();
reply->deleteLater();
}

16
Servo/src/ModbusWrapper.cpp

@ -33,15 +33,31 @@ void ModbusWrapper::init()
&modbusMaster, &modbusMaster,
&ModbusMaster::connectToDevice, &ModbusMaster::connectToDevice,
Qt::BlockingQueuedConnection); Qt::BlockingQueuedConnection);
connect(this,
&ModbusWrapper::getCoilOrder,
&modbusMaster,
&ModbusMaster::getCoil,
Qt::BlockingQueuedConnection);
emit initOrder(); emit initOrder();
qDebug() << "init done"; 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) void ModbusWrapper::connectToDevice(ModbusConfig modbusConfig)
{ {
emit connectOrder(modbusConfig); emit connectOrder(modbusConfig);
qDebug() << "connect done"; qDebug() << "connect done";
} }
/*************************************************************************************************/

36
Test/MainWindow.cpp

@ -6,6 +6,11 @@ MainWindow::MainWindow(QWidget* parent)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
{ {
ui->setupUi(this); 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(); 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<quint16>(numberOfEntries)));
break;
//case 1: printCoilsDataFromSlave(modbusWrapper->getInputCoil(startAddress,static_cast<quint16>(numberOfEntries)));
//break;
//case 2: printRegisterDataFromSlave(modbusWrapper->getInputRegister(startAddress,static_cast<quint16>(numberOfEntries)));
//break;
//case 3: printRegisterDataFromSlave(modbusWrapper->getHoldingRegister(startAddress,static_cast<quint16>(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);
}

2
Test/MainWindow.h

@ -23,11 +23,13 @@ private:
public: public:
MainWindow(QWidget* parent = nullptr); MainWindow(QWidget* parent = nullptr);
~MainWindow(); ~MainWindow();
void printCoilsDataFromClient(QBitArray uiCoils);
//uncrustify off //uncrustify off
private slots: private slots:
void on_connect_clicked(); void on_connect_clicked();
//uncrustify on //uncrustify on
void on_readButton_clicked();
}; };
#endif //MAINWINDOW_H #endif //MAINWINDOW_H

115
Test/MainWindow.ui

@ -17,8 +17,8 @@
<widget class="QPushButton" name="connect"> <widget class="QPushButton" name="connect">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>420</x> <x>360</x>
<y>40</y> <y>30</y>
<width>89</width> <width>89</width>
<height>25</height> <height>25</height>
</rect> </rect>
@ -27,6 +27,117 @@
<string>Connect</string> <string>Connect</string>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>40</x>
<y>142</y>
<width>126</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Number of values:</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>40</x>
<y>110</y>
<width>126</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Start address:</string>
</property>
</widget>
<widget class="QLineEdit" name="startAddress">
<property name="geometry">
<rect>
<x>170</x>
<y>110</y>
<width>113</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="readSize">
<property name="geometry">
<rect>
<x>170</x>
<y>140</y>
<width>113</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>43</x>
<y>430</y>
<width>41</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Table:</string>
</property>
</widget>
<widget class="QPushButton" name="readButton">
<property name="geometry">
<rect>
<x>345</x>
<y>430</y>
<width>80</width>
<height>25</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Read</string>
</property>
</widget>
<widget class="QComboBox" name="writeTable">
<property name="geometry">
<rect>
<x>90</x>
<y>430</y>
<width>86</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_9">
<property name="geometry">
<rect>
<x>40</x>
<y>167</y>
<width>126</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Result:</string>
</property>
</widget>
<widget class="QTextEdit" name="textEditRead">
<property name="geometry">
<rect>
<x>40</x>
<y>200</y>
<width>257</width>
<height>221</height>
</rect>
</property>
</widget>
</widget> </widget>
<widget class="QMenuBar" name="menubar"> <widget class="QMenuBar" name="menubar">
<property name="geometry"> <property name="geometry">

Loading…
Cancel
Save