Compare commits

...

5 Commits

  1. 1
      Servo/Servo.pro
  2. 7
      Servo/include/ModbusMaster.h
  3. 6
      Servo/include/ModbusWrapper.h
  4. 18
      Servo/include/ServoController.h
  5. 605
      Servo/src/ModbusMaster.cpp
  6. 340
      Servo/src/ModbusWrapper.cpp
  7. 109
      Servo/src/ServoController.cpp
  8. 391
      Test/MainWindow.cpp
  9. 36
      Test/MainWindow.ui
  10. 22
      Test/main.cpp

1
Servo/Servo.pro

@ -25,7 +25,6 @@ SOURCES += \
HEADERS += \ HEADERS += \
$$files(*.h, true) \ $$files(*.h, true) \
include/ExpConfig.h
INCLUDEPATH += $$PWD/include INCLUDEPATH += $$PWD/include

7
Servo/include/ModbusMaster.h

@ -20,6 +20,7 @@ class ModbusMaster : public QObject
private: private:
bool _initialized = false; bool _initialized = false;
bool _connected = false;
QModbusClient* _modbusDevice = nullptr; QModbusClient* _modbusDevice = nullptr;
int _clientAddress; int _clientAddress;
QModbusDataUnit _modbusReplyUnit; QModbusDataUnit _modbusReplyUnit;
@ -36,7 +37,8 @@ public:
void writeRequest(QModbusDataUnit::RegisterType registerType, void writeRequest(QModbusDataUnit::RegisterType registerType,
int startAddress, int startAddress,
quint16 writeSize); quint16 writeSize);
void close();
//uncrustify off //uncrustify off
public slots: public slots:
@ -44,6 +46,7 @@ public slots:
void init(ExpConfig& expConfig); void init(ExpConfig& expConfig);
void connectToDevice(ModbusConfig modbusConfig, ExpConfig& expConfig); void connectToDevice(ModbusConfig modbusConfig, ExpConfig& expConfig);
void connectionStateChanged(QModbusDevice::State state); void connectionStateChanged(QModbusDevice::State state);
bool getConnectionState();
QBitArray getCoil(int startAddress, quint16 readSize, ExpConfig& expConfig); QBitArray getCoil(int startAddress, quint16 readSize, ExpConfig& expConfig);
QBitArray getInputCoil(int startAddress, quint16 readSize, ExpConfig& expConfig); QBitArray getInputCoil(int startAddress, quint16 readSize, ExpConfig& expConfig);
@ -60,6 +63,8 @@ public slots:
quint16 writeSize, quint16 writeSize,
QVector<quint16> registerValues, QVector<quint16> registerValues,
ExpConfig& expConfig); ExpConfig& expConfig);
void close();
}; };
#endif //MODBUSMASTER_H #endif //MODBUSMASTER_H

6
Servo/include/ModbusWrapper.h

@ -21,7 +21,7 @@ public:
~ModbusWrapper(); ~ModbusWrapper();
void connectToDevice(ModbusConfig modbusConfig); void connectToDevice(ModbusConfig modbusConfig);
void init(); void init();
void close();
QBitArray getCoil(int startAddress, quint16 readSize); QBitArray getCoil(int startAddress, quint16 readSize);
QBitArray getInputCoil(int startAddress, quint16 readSize); QBitArray getInputCoil(int startAddress, quint16 readSize);
QVector<quint16> getHoldingRegister(int startAddress, quint16 readSize); QVector<quint16> getHoldingRegister(int startAddress, quint16 readSize);
@ -31,10 +31,12 @@ public:
void setMultipleCoil(int startAddress, quint16 writeSize, QBitArray coilFlags); void setMultipleCoil(int startAddress, quint16 writeSize, QBitArray coilFlags);
void setSingleRegister(int startAddress, quint16 registerValue); void setSingleRegister(int startAddress, quint16 registerValue);
void setMultipleRegister(int startAddress, quint16 writeSize, QVector<quint16> registerValues); void setMultipleRegister(int startAddress, quint16 writeSize, QVector<quint16> registerValues);
bool getStatus();
signals: signals:
void connectOrder(ModbusConfig modbusConfig, ExpConfig& expConfig); void connectOrder(ModbusConfig modbusConfig, ExpConfig& expConfig);
void initOrder(ExpConfig& expConfig); void initOrder(ExpConfig& expConfig);
void closeOrder();
bool getConnectionStateOrder();
QBitArray getCoilOrder(int startAddress, quint16 readSize, ExpConfig& expConfig); QBitArray getCoilOrder(int startAddress, quint16 readSize, ExpConfig& expConfig);
QBitArray getInputCoilOrder(int startAddress, quint16 readSize, ExpConfig& expConfig); QBitArray getInputCoilOrder(int startAddress, quint16 readSize, ExpConfig& expConfig);

18
Servo/include/ServoController.h

@ -11,14 +11,14 @@ private:
const int SRV_START_ANGLE_INT_PART_REG = 2000; const int SRV_START_ANGLE_INT_PART_REG = 2000;
const int SRV_STOP_ANGLE_INT_PART_REG = 2001; const int SRV_STOP_ANGLE_INT_PART_REG = 2001;
const int SRV_AZIMUTH_SPEED_REG = 2002; const int SRV_AZIMUTH_SPEED_REG = 2002;
const int SRV_APPLY_SETTING_REG = 2004; const int SRV_APPLY_SETTING_REG = 2004;
const int SRV_START_STOP_REG = 2005; const int SRV_START_STOP_REG = 2005;
const int SRV_ZERO_OFFSET_ANGLE = 2007; const int SRV_ZERO_OFFSET_ANGLE = 2007;
const int SRV_START_ANGLE_FRAC_PART_REG = 2010; const int SRV_START_ANGLE_FRAC_PART_REG = 2010;
const int SRV_STOP_ANGLE_FRAC_PART_REG = 2011; const int SRV_STOP_ANGLE_FRAC_PART_REG = 2011;
const int SRV_CALIBRATE_REG = 2013; const int SRV_CALIBRATE_REG = 2013;
const int SRV_ENABLE_DRIVE_REG = 2017; const int SRV_ENABLE_DRIVE_REG = 2017;
const int SRV_AZIMUTH_REG = 2030; const int SRV_AZIMUTH_REG = 2030;
const double SRV_ANGLE_FACTOR = 100.0; const double SRV_ANGLE_FACTOR = 100.0;
const double SRV_SPEED_FACTOR = 1000.0; const double SRV_SPEED_FACTOR = 1000.0;
@ -48,6 +48,8 @@ public:
double getAngleOffset(); double getAngleOffset();
void setAngleOffset(double offset); void setAngleOffset(double offset);
double getAzimuth(); double getAzimuth();
bool getStatus();
}; };
#endif //SERVOCONTROLLER_H #endif //SERVOCONTROLLER_H

605
Servo/src/ModbusMaster.cpp

@ -2,368 +2,397 @@
#include <QModbusRtuSerialMaster> #include <QModbusRtuSerialMaster>
#include <QEventLoop> #include <QEventLoop>
#include <QThread>
ModbusMaster::ModbusMaster(QObject* parent) : QObject(parent) ModbusMaster::ModbusMaster(QObject* parent) : QObject(parent)
{ {
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusMaster::init(ExpConfig& expConfig) void ModbusMaster::init(ExpConfig& expConfig)
{ {
try { try {
if(!_initialized) if(!_initialized)
{ {
_modbusDevice = nullptr; _modbusDevice = nullptr;
_modbusDevice = new QModbusRtuSerialMaster(this); _modbusDevice = new QModbusRtuSerialMaster(this);
connect(_modbusDevice, &QModbusClient::errorOccurred, [this](QModbusDevice::Error) connect(_modbusDevice, &QModbusClient::errorOccurred, [this](QModbusDevice::Error)
{ {
throw ServoException(_modbusDevice->errorString()); _initialized = false;
}); connectionStateChanged(QModbusDevice::UnconnectedState);
});
connect(_modbusDevice,
&QModbusClient::stateChanged, connect(_modbusDevice,
this, &QModbusClient::stateChanged,
&ModbusMaster::connectionStateChanged); this,
&ModbusMaster::connectionStateChanged);
_initialized = true;
} _initialized = true;
else }
{ else
throw ServoException( {
"Modbus Device Object Created Before First Delete it Then Make New One"); throw ServoException(
} "Modbus Device Object Created Before First Delete it Then Make New One");
} }
catch(const ServoException& ex) }
{ catch(const ServoException& ex)
expConfig.valid = true; {
expConfig.message = ex.getMessage(); expConfig.valid = true;
} expConfig.message = ex.getMessage();
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusMaster::connectionStateChanged(QModbusDevice::State state) void ModbusMaster::connectionStateChanged(QModbusDevice::State state)
{ {
if(state == QModbusDevice::UnconnectedState)
{ if(state == QModbusDevice::UnconnectedState)
throw ServoException("Connection wasnt prepared"); {
} _connected = false;
}
else if (state == QModbusDevice::ConnectedState)
{
_connected = true;
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusMaster::connectToDevice(ModbusConfig modbusConfig, ExpConfig& expConfig) void ModbusMaster::connectToDevice(ModbusConfig modbusConfig, ExpConfig& expConfig)
{ {
try { try {
if(_modbusDevice->state() != QModbusDevice::ConnectedState) if(_modbusDevice->state() != QModbusDevice::ConnectedState)
{ {
_clientAddress = modbusConfig.clientAddress; _clientAddress = modbusConfig.clientAddress;
_modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, _modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
modbusConfig.serialPort); modbusConfig.serialPort);
_modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, _modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
modbusConfig.parity); modbusConfig.parity);
_modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, _modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
modbusConfig.baud); modbusConfig.baud);
_modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, _modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
modbusConfig.dataBits); modbusConfig.dataBits);
_modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, _modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
modbusConfig.stopBits); modbusConfig.stopBits);
_modbusDevice->setTimeout(modbusConfig.responseTime); _modbusDevice->setTimeout(modbusConfig.responseTime);
if(!_modbusDevice->connectDevice()) if(!_modbusDevice->connectDevice())
{ {
throw ServoException(_modbusDevice->errorString()); throw ServoException(_modbusDevice->errorString());
} }
} }
} }
catch(const ServoException& ex) catch(const ServoException& ex)
{ {
expConfig.valid = true; expConfig.valid = true;
expConfig.message = ex.getMessage(); expConfig.message = ex.getMessage();
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
QBitArray ModbusMaster::getCoil(int startAddress, quint16 readSize, ExpConfig& expConfig) QBitArray ModbusMaster::getCoil(int startAddress, quint16 readSize, ExpConfig& expConfig)
{ {
try try
{ {
readRequest(QModbusDataUnit::RegisterType::Coils, startAddress, readSize); readRequest(QModbusDataUnit::RegisterType::Coils, startAddress, readSize);
auto unit = _modbusReplyUnit; auto unit = _modbusReplyUnit;
QBitArray coils; QBitArray coils;
auto num = unit.valueCount(); auto num = unit.valueCount();
coils.resize(static_cast<int>(num)); coils.resize(static_cast<int>(num));
for(uint i = 0; i < num; i++) for(uint i = 0; i < num; i++)
{ {
if(unit.value(static_cast<int>(i)) == 1) if(unit.value(static_cast<int>(i)) == 1)
coils.setBit(static_cast<int>(i)); coils.setBit(static_cast<int>(i));
else else
coils.clearBit(static_cast<int>(i)); coils.clearBit(static_cast<int>(i));
} }
return coils; return coils;
} }
catch(const ServoException& ex) catch(const ServoException& ex)
{ {
expConfig.valid = true; expConfig.valid = true;
expConfig.message = ex.getMessage(); expConfig.message = ex.getMessage();
} return QBitArray();
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
QBitArray ModbusMaster::getInputCoil(int startAddress, quint16 readSize, ExpConfig& expConfig) QBitArray ModbusMaster::getInputCoil(int startAddress, quint16 readSize, ExpConfig& expConfig)
{ {
try try
{ {
readRequest(QModbusDataUnit::RegisterType::DiscreteInputs, startAddress, readSize); readRequest(QModbusDataUnit::RegisterType::DiscreteInputs, startAddress, readSize);
auto unit = _modbusReplyUnit; auto unit = _modbusReplyUnit;
QBitArray coils; QBitArray coils;
auto num = unit.valueCount(); auto num = unit.valueCount();
coils.resize(static_cast<int>(num)); coils.resize(static_cast<int>(num));
for(uint i = 0; i < num; i++) for(uint i = 0; i < num; i++)
{ {
if(unit.value(static_cast<int>(i)) == 1) if(unit.value(static_cast<int>(i)) == 1)
coils.setBit(static_cast<int>(i)); coils.setBit(static_cast<int>(i));
else else
coils.clearBit(static_cast<int>(i)); coils.clearBit(static_cast<int>(i));
} }
return coils; return coils;
} }
catch(const ServoException& ex) catch(const ServoException& ex)
{ {
expConfig.valid = true; expConfig.valid = true;
expConfig.message = ex.getMessage(); expConfig.message = ex.getMessage();
} return QBitArray();
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
QVector<quint16> ModbusMaster::getHoldingRegister(int startAddress, QVector<quint16> ModbusMaster::getHoldingRegister(int startAddress,
quint16 readSize, quint16 readSize,
ExpConfig& expConfig) ExpConfig& expConfig)
{ {
try try
{ {
readRequest(QModbusDataUnit::RegisterType::HoldingRegisters, startAddress, readSize); readRequest(QModbusDataUnit::RegisterType::HoldingRegisters, startAddress, readSize);
auto unit = _modbusReplyUnit; auto unit = _modbusReplyUnit;
QVector<quint16> registerValues; QVector<quint16> registerValues;
auto num = unit.valueCount(); auto num = unit.valueCount();
registerValues.resize(static_cast<int>(num)); registerValues.resize(static_cast<int>(num));
for(uint i = 0; i < unit.valueCount(); i++) for(uint i = 0; i < unit.valueCount(); i++)
{ {
registerValues[static_cast<int>(i)] = unit.value(static_cast<int>(i)); registerValues[static_cast<int>(i)] = unit.value(static_cast<int>(i));
} }
return registerValues; return registerValues;
} }
catch(const ServoException& ex) catch(const ServoException& ex)
{ {
expConfig.valid = true; expConfig.valid = true;
expConfig.message = ex.getMessage(); expConfig.message = ex.getMessage();
} return QVector<quint16>();
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
QVector<quint16> ModbusMaster::getInputRegister(int startAddress, QVector<quint16> ModbusMaster::getInputRegister(int startAddress,
quint16 readSize, quint16 readSize,
ExpConfig& expConfig) ExpConfig& expConfig)
{ {
try try
{ {
readRequest(QModbusDataUnit::RegisterType::InputRegisters, startAddress, readSize); readRequest(QModbusDataUnit::RegisterType::InputRegisters, startAddress, readSize);
auto unit = _modbusReplyUnit; auto unit = _modbusReplyUnit;
QVector<quint16> registerValues; QVector<quint16> registerValues;
auto num = unit.valueCount(); auto num = unit.valueCount();
registerValues.resize(static_cast<int>(num)); registerValues.resize(static_cast<int>(num));
for(uint i = 0; i < unit.valueCount(); i++) for(uint i = 0; i < unit.valueCount(); i++)
{ {
registerValues[static_cast<int>(i)] = unit.value(static_cast<int>(i)); registerValues[static_cast<int>(i)] = unit.value(static_cast<int>(i));
} }
return registerValues; return registerValues;
} }
catch(const ServoException& ex) catch(const ServoException& ex)
{ {
expConfig.valid = true; expConfig.valid = true;
expConfig.message = ex.getMessage(); expConfig.message = ex.getMessage();
} return QVector<quint16>();
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusMaster::setSingleCoil(int startAddress, bool coilFlag, ExpConfig& expConfig) void ModbusMaster::setSingleCoil(int startAddress, bool coilFlag, ExpConfig& expConfig)
{ {
try try
{ {
_coilsToWrite.resize(1); _coilsToWrite.resize(1);
if(coilFlag) if(coilFlag)
_coilsToWrite.setBit(0); _coilsToWrite.setBit(0);
else else
_coilsToWrite.clearBit(0); _coilsToWrite.clearBit(0);
writeRequest(QModbusDataUnit::RegisterType::Coils, startAddress, 1); writeRequest(QModbusDataUnit::RegisterType::Coils, startAddress, 1);
} }
catch(const ServoException& ex) catch(const ServoException& ex)
{ {
expConfig.valid = true; expConfig.valid = true;
expConfig.message = ex.getMessage(); expConfig.message = ex.getMessage();
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusMaster::setMultipleCoil(int startAddress, void ModbusMaster::setMultipleCoil(int startAddress,
quint16 writeSize, quint16 writeSize,
QBitArray coilFlags, QBitArray coilFlags,
ExpConfig& expConfig) ExpConfig& expConfig)
{ {
try try
{ {
_coilsToWrite = coilFlags; _coilsToWrite = coilFlags;
writeRequest(QModbusDataUnit::RegisterType::Coils, startAddress, writeSize); writeRequest(QModbusDataUnit::RegisterType::Coils, startAddress, writeSize);
} }
catch(const ServoException& ex) catch(const ServoException& ex)
{ {
expConfig.valid = true; expConfig.valid = true;
expConfig.message = ex.getMessage(); expConfig.message = ex.getMessage();
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusMaster::setSingleRegister(int startAddress, quint16 registerValue, ExpConfig& expConfig) void ModbusMaster::setSingleRegister(int startAddress, quint16 registerValue, ExpConfig& expConfig)
{ {
try try
{ {
_RegistersToWrite.resize(1); _RegistersToWrite.resize(1);
_RegistersToWrite[0] = registerValue; _RegistersToWrite[0] = registerValue;
writeRequest(QModbusDataUnit::RegisterType::HoldingRegisters, startAddress, 1); writeRequest(QModbusDataUnit::RegisterType::HoldingRegisters, startAddress, 1);
} }
catch(const ServoException& ex) catch(const ServoException& ex)
{ {
expConfig.valid = true; expConfig.valid = true;
expConfig.message = ex.getMessage(); expConfig.message = ex.getMessage();
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusMaster::setMultipleRegister(int startAddress, void ModbusMaster::setMultipleRegister(int startAddress,
quint16 writeSize, quint16 writeSize,
QVector<quint16> registerValues, ExpConfig& expConfig) QVector<quint16> registerValues, ExpConfig& expConfig)
{ {
try try
{ {
_RegistersToWrite = registerValues; _RegistersToWrite = registerValues;
writeRequest(QModbusDataUnit::RegisterType::HoldingRegisters, startAddress, writeSize); writeRequest(QModbusDataUnit::RegisterType::HoldingRegisters, startAddress, writeSize);
} }
catch(const ServoException& ex) catch(const ServoException& ex)
{ {
expConfig.valid = true; expConfig.valid = true;
expConfig.message = ex.getMessage(); expConfig.message = ex.getMessage();
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusMaster::readRequest(QModbusDataUnit::RegisterType registerType, void ModbusMaster::readRequest(QModbusDataUnit::RegisterType registerType,
int startAddress, int startAddress,
quint16 readSize) quint16 readSize)
{ {
auto table = registerType; auto table = registerType;
auto reply = _modbusDevice->sendReadRequest(QModbusDataUnit(table, startAddress, readSize), auto reply = _modbusDevice->sendReadRequest(QModbusDataUnit(table, startAddress, readSize),
_clientAddress); _clientAddress);
if(reply) if(reply)
{ {
if(!reply->isFinished()) if(!reply->isFinished())
{ {
QEventLoop loop; QEventLoop loop;
connect(reply, connect(reply,
&QModbusReply::finished, &QModbusReply::finished,
&loop, &loop,
&QEventLoop::quit &QEventLoop::quit
); );
loop.exec(); loop.exec();
checkForError(reply); checkForError(reply);
_modbusReplyUnit = reply->result(); _modbusReplyUnit = reply->result();
reply->deleteLater(); reply->deleteLater();
} }
else else
delete reply; //broadcast replies return immediately delete reply; //broadcast replies return immediately
} }
else else
{ {
throw ServoException(_modbusDevice->errorString()); throw ServoException(_modbusDevice->errorString());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusMaster::checkForError(QModbusReply* _reply) void ModbusMaster::checkForError(QModbusReply* _reply)
{ {
if(_reply->error() == QModbusDevice::NoError) if(_reply->error() == QModbusDevice::NoError)
return; {
_connected = true;
if(_reply->error() == QModbusDevice::ProtocolError) return;
{ }
throw ServoException(QString("Read response error: %1 (Mobus exception: %2)") if(_reply->error() == QModbusDevice::ProtocolError)
.arg(_reply->errorString()) {
.arg(_reply->rawResult().exceptionCode())); _connected = false;
} throw ServoException(QString("Read response error: %1 (Modbus exception: %2)")
else .arg(_reply->errorString())
{ .arg(_reply->rawResult().exceptionCode()));
throw ServoException(QString("Read response error: %1 (code: %2)") }
.arg(_reply->errorString()) else
.arg(_reply->error())); {
} _connected = false;
throw ServoException(QString("Read response error: %1 (code: %2)")
.arg(_reply->errorString())
.arg(_reply->error()));
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusMaster::writeRequest(QModbusDataUnit::RegisterType registerType, void ModbusMaster::writeRequest(QModbusDataUnit::RegisterType registerType,
int startAddress, int startAddress,
quint16 writeSize) quint16 writeSize)
{
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(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();
reply->deleteLater();
}
else
delete reply; //broadcast replies return immediately
}
else
{
throw ServoException(_modbusDevice->errorString());
}
}
/*************************************************************************************************/
bool ModbusMaster::getConnectionState()
{ {
auto table = registerType; return _connected;
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(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();
reply->deleteLater();
}
else
delete reply; //broadcast replies return immediately
}
else
{
throw ServoException(_modbusDevice->errorString());
}
} }
/*************************************************************************************************/
void ModbusMaster::close() void ModbusMaster::close()
{ {
if(_modbusDevice) _initialized = false;
_modbusDevice->disconnectDevice(); if(_modbusDevice)
delete _modbusDevice; {
if (_modbusDevice->state() == QModbusDevice::ConnectedState || _modbusDevice->state() == QModbusDevice::ConnectingState)
{
_modbusDevice->disconnectDevice();
}
delete _modbusDevice;
_modbusDevice = nullptr;
}
} }

340
Servo/src/ModbusWrapper.cpp

@ -8,187 +8,265 @@ ModbusWrapper::ModbusWrapper(QObject* parent) : QObject(parent)
/*************************************************************************************************/ /*************************************************************************************************/
ModbusWrapper::~ModbusWrapper() ModbusWrapper::~ModbusWrapper()
{ {
_workerThread.quit(); _workerThread.quit();
_workerThread.wait(); _workerThread.wait();
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusWrapper::init() void ModbusWrapper::init()
{ {
_modbusMaster.moveToThread(&_workerThread); _modbusMaster.moveToThread(&_workerThread);
_workerThread.setObjectName("workerThread"); _workerThread.setObjectName("workerThread");
_workerThread.start(); _workerThread.start();
QEventLoop loop; QEventLoop loop;
connect(&_workerThread, &QThread::started, &loop, &QEventLoop::quit); connect(&_workerThread, &QThread::started, &loop, &QEventLoop::quit);
loop.exec(); loop.exec();
connect(this, connect(this,
&ModbusWrapper::initOrder, &ModbusWrapper::getConnectionStateOrder,
&_modbusMaster, &_modbusMaster,
&ModbusMaster::init, &ModbusMaster::getConnectionState,
Qt::BlockingQueuedConnection); Qt::BlockingQueuedConnection);
connect(this, connect(this,
&ModbusWrapper::connectOrder, &ModbusWrapper::initOrder,
&_modbusMaster, &_modbusMaster,
&ModbusMaster::connectToDevice, &ModbusMaster::init,
Qt::BlockingQueuedConnection); Qt::BlockingQueuedConnection);
connect(this, connect(this,
&ModbusWrapper::getCoilOrder, &ModbusWrapper::connectOrder,
&_modbusMaster, &_modbusMaster,
&ModbusMaster::getCoil, &ModbusMaster::connectToDevice,
Qt::BlockingQueuedConnection); Qt::BlockingQueuedConnection);
connect(this, connect(this,
&ModbusWrapper::getInputCoilOrder, &ModbusWrapper::getCoilOrder,
&_modbusMaster, &_modbusMaster,
&ModbusMaster::getInputCoil, &ModbusMaster::getCoil,
Qt::BlockingQueuedConnection); Qt::BlockingQueuedConnection);
connect(this, connect(this,
&ModbusWrapper::getHoldingRegisterOrder, &ModbusWrapper::getInputCoilOrder,
&_modbusMaster, &_modbusMaster,
&ModbusMaster::getHoldingRegister, &ModbusMaster::getInputCoil,
Qt::BlockingQueuedConnection); Qt::BlockingQueuedConnection);
connect(this, connect(this,
&ModbusWrapper::getInputRegisterOrder, &ModbusWrapper::getHoldingRegisterOrder,
&_modbusMaster, &_modbusMaster,
&ModbusMaster::getInputRegister, &ModbusMaster::getHoldingRegister,
Qt::BlockingQueuedConnection); Qt::BlockingQueuedConnection);
connect(this,
connect(this, &ModbusWrapper::getInputRegisterOrder,
&ModbusWrapper::setSingleCoilOrder, &_modbusMaster,
&_modbusMaster, &ModbusMaster::getInputRegister,
&ModbusMaster::setSingleCoil, Qt::BlockingQueuedConnection);
Qt::BlockingQueuedConnection);
connect(this, connect(this,
&ModbusWrapper::setMultipleCoilOrder, &ModbusWrapper::setSingleCoilOrder,
&_modbusMaster, &_modbusMaster,
&ModbusMaster::setMultipleCoil, &ModbusMaster::setSingleCoil,
Qt::BlockingQueuedConnection); Qt::BlockingQueuedConnection);
connect(this, connect(this,
&ModbusWrapper::setSingleRegisterOrder, &ModbusWrapper::setMultipleCoilOrder,
&_modbusMaster, &_modbusMaster,
&ModbusMaster::setSingleRegister, &ModbusMaster::setMultipleCoil,
Qt::BlockingQueuedConnection); Qt::BlockingQueuedConnection);
connect(this, connect(this,
&ModbusWrapper::setMultipleRegisterOrder, &ModbusWrapper::setSingleRegisterOrder,
&_modbusMaster, &_modbusMaster,
&ModbusMaster::setMultipleRegister, &ModbusMaster::setSingleRegister,
Qt::BlockingQueuedConnection); Qt::BlockingQueuedConnection);
connect(this,
ExpConfig exp; &ModbusWrapper::setMultipleRegisterOrder,
emit initOrder(exp); &_modbusMaster,
if(exp.valid) &ModbusMaster::setMultipleRegister,
{ Qt::BlockingQueuedConnection);
throw ServoException(exp.message); connect(this,
} &ModbusWrapper::closeOrder,
&_modbusMaster,
&ModbusMaster::close,
Qt::BlockingQueuedConnection);
ExpConfig exp;
emit initOrder(exp);
if(exp.valid)
{
throw ServoException(exp.message);
}
}
/*************************************************************************************************/
void ModbusWrapper::close()
{
if (_workerThread.isRunning())
{
emit closeOrder();
_workerThread.quit();
_workerThread.wait();
disconnect(this,
&ModbusWrapper::getConnectionStateOrder,
&_modbusMaster,
&ModbusMaster::getConnectionState);
disconnect(this,
&ModbusWrapper::initOrder,
&_modbusMaster,
&ModbusMaster::init);
disconnect(this,
&ModbusWrapper::connectOrder,
&_modbusMaster,
&ModbusMaster::connectToDevice);
disconnect(this,
&ModbusWrapper::getCoilOrder,
&_modbusMaster,
&ModbusMaster::getCoil);
disconnect(this,
&ModbusWrapper::getInputCoilOrder,
&_modbusMaster,
&ModbusMaster::getInputCoil);
disconnect(this,
&ModbusWrapper::getHoldingRegisterOrder,
&_modbusMaster,
&ModbusMaster::getHoldingRegister);
disconnect(this,
&ModbusWrapper::getInputRegisterOrder,
&_modbusMaster,
&ModbusMaster::getInputRegister);
disconnect(this,
&ModbusWrapper::setSingleCoilOrder,
&_modbusMaster,
&ModbusMaster::setSingleCoil);
disconnect(this,
&ModbusWrapper::setMultipleCoilOrder,
&_modbusMaster,
&ModbusMaster::setMultipleCoil);
disconnect(this,
&ModbusWrapper::setSingleRegisterOrder,
&_modbusMaster,
&ModbusMaster::setSingleRegister);
disconnect(this,
&ModbusWrapper::setMultipleRegisterOrder,
&_modbusMaster,
&ModbusMaster::setMultipleRegister);
disconnect(this,
&ModbusWrapper::closeOrder,
&_modbusMaster,
&ModbusMaster::close);
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
QBitArray ModbusWrapper::getCoil(int startAddress, quint16 readSize) QBitArray ModbusWrapper::getCoil(int startAddress, quint16 readSize)
{ {
ExpConfig exp; ExpConfig exp;
auto ret = emit getCoilOrder(startAddress, readSize, exp); auto ret = emit getCoilOrder(startAddress, readSize, exp);
if(exp.valid) if(exp.valid)
{ {
throw ServoException(exp.message); throw ServoException(exp.message);
} }
return ret; return ret;
} }
/*************************************************************************************************/ /*************************************************************************************************/
QBitArray ModbusWrapper::getInputCoil(int startAddress, quint16 readSize) QBitArray ModbusWrapper::getInputCoil(int startAddress, quint16 readSize)
{ {
ExpConfig exp; ExpConfig exp;
auto ret = emit getInputCoilOrder(startAddress, readSize, exp); auto ret = emit getInputCoilOrder(startAddress, readSize, exp);
if(exp.valid) if(exp.valid)
{ {
throw ServoException(exp.message); throw ServoException(exp.message);
} }
return ret; return ret;
} }
/*************************************************************************************************/ /*************************************************************************************************/
QVector<quint16> ModbusWrapper::getHoldingRegister(int startAddress, quint16 readSize) QVector<quint16> ModbusWrapper::getHoldingRegister(int startAddress, quint16 readSize)
{ {
ExpConfig exp; ExpConfig exp;
auto ret = emit getHoldingRegisterOrder(startAddress, readSize, exp); auto ret = emit getHoldingRegisterOrder(startAddress, readSize, exp);
if(exp.valid) if(exp.valid)
{ {
throw ServoException(exp.message); throw ServoException(exp.message);
} }
return ret; return ret;
} }
/*************************************************************************************************/ /*************************************************************************************************/
QVector<quint16> ModbusWrapper::getInputRegister(int startAddress, quint16 readSize) QVector<quint16> ModbusWrapper::getInputRegister(int startAddress, quint16 readSize)
{ {
ExpConfig exp; ExpConfig exp;
auto ret = emit getInputRegisterOrder(startAddress, readSize, exp); auto ret = emit getInputRegisterOrder(startAddress, readSize, exp);
if(exp.valid) if(exp.valid)
{ {
throw ServoException(exp.message); throw ServoException(exp.message);
} }
return ret; return ret;
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusWrapper::setSingleCoil(int startAddress, bool coilFlag) void ModbusWrapper::setSingleCoil(int startAddress, bool coilFlag)
{ {
ExpConfig exp; ExpConfig exp;
emit setSingleCoilOrder(startAddress, coilFlag, exp); emit setSingleCoilOrder(startAddress, coilFlag, exp);
if(exp.valid) if(exp.valid)
{ {
throw ServoException(exp.message); throw ServoException(exp.message);
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusWrapper::setMultipleCoil(int startAddress, quint16 writeSize, QBitArray coilFlags) void ModbusWrapper::setMultipleCoil(int startAddress, quint16 writeSize, QBitArray coilFlags)
{ {
ExpConfig exp; ExpConfig exp;
emit setMultipleCoilOrder(startAddress, writeSize, coilFlags, exp); emit setMultipleCoilOrder(startAddress, writeSize, coilFlags, exp);
if(exp.valid) if(exp.valid)
{ {
throw ServoException(exp.message); throw ServoException(exp.message);
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusWrapper::setSingleRegister(int startAddress, quint16 registerValue) void ModbusWrapper::setSingleRegister(int startAddress, quint16 registerValue)
{ {
ExpConfig exp; ExpConfig exp;
emit setSingleRegisterOrder(startAddress, registerValue, exp); emit setSingleRegisterOrder(startAddress, registerValue, exp);
if(exp.valid) if(exp.valid)
{ {
throw ServoException(exp.message); throw ServoException(exp.message);
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusWrapper::setMultipleRegister(int startAddress, void ModbusWrapper::setMultipleRegister(int startAddress,
quint16 writeSize, quint16 writeSize,
QVector<quint16> registerValues) QVector<quint16> registerValues)
{
ExpConfig exp;
emit setMultipleRegisterOrder(startAddress, writeSize, registerValues, exp);
if(exp.valid)
{
throw ServoException(exp.message);
}
}
/*************************************************************************************************/
bool ModbusWrapper::getStatus()
{ {
ExpConfig exp; return emit getConnectionStateOrder();
emit setMultipleRegisterOrder(startAddress, writeSize, registerValues, exp);
if(exp.valid)
{
throw ServoException(exp.message);
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ModbusWrapper::connectToDevice(ModbusConfig modbusConfig) void ModbusWrapper::connectToDevice(ModbusConfig modbusConfig)
{ {
ExpConfig exp; ExpConfig exp;
emit connectOrder(modbusConfig, exp); emit connectOrder(modbusConfig, exp);
if(exp.valid) if(exp.valid)
{ {
throw ServoException(exp.message); throw ServoException(exp.message);
} }
} }

109
Servo/src/ServoController.cpp

@ -2,156 +2,163 @@
ModbusConfig ServoController::initiateConfig(QString serialPort) ModbusConfig ServoController::initiateConfig(QString serialPort)
{ {
ModbusConfig _config; ModbusConfig _config;
_config.baud = QSerialPort::Baud19200; _config.baud = QSerialPort::Baud19200;
_config.parity = QSerialPort::EvenParity; _config.parity = QSerialPort::EvenParity;
_config.dataBits = QSerialPort::Data8; _config.dataBits = QSerialPort::Data8;
_config.stopBits = QSerialPort::OneStop; _config.stopBits = QSerialPort::OneStop;
_config.responseTime = 2000; _config.responseTime = 2000;
_config.serialPort = serialPort; _config.serialPort = serialPort;
_config.clientAddress = 1; _config.clientAddress = 1;
return _config; return _config;
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::apply() void ServoController::apply()
{ {
_modbusWrapper.setSingleRegister(SRV_APPLY_SETTING_REG, SRV_APPLY_SETTING_VAL); _modbusWrapper.setSingleRegister(SRV_APPLY_SETTING_REG, SRV_APPLY_SETTING_VAL);
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::enableDrive() void ServoController::enableDrive()
{ {
_modbusWrapper.setSingleRegister(SRV_ENABLE_DRIVE_REG, 3); _modbusWrapper.setSingleRegister(SRV_ENABLE_DRIVE_REG, 3);
apply(); apply();
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::setStartStop(bool start) void ServoController::setStartStop(bool start)
{ {
_modbusWrapper.setSingleRegister(SRV_START_STOP_REG, start ? 3 : 0); _modbusWrapper.setSingleRegister(SRV_START_STOP_REG, start ? 3 : 0);
apply(); apply();
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::setStartAngle(double angle) void ServoController::setStartAngle(double angle)
{ {
_modbusWrapper.setSingleRegister(SRV_START_ANGLE_INT_PART_REG, static_cast<quint16>(angle)); _modbusWrapper.setSingleRegister(SRV_START_ANGLE_INT_PART_REG, static_cast<quint16>(angle));
_modbusWrapper.setSingleRegister(SRV_START_ANGLE_FRAC_PART_REG, _modbusWrapper.setSingleRegister(SRV_START_ANGLE_FRAC_PART_REG,
static_cast<quint16>((angle - (static_cast<int>(angle))) * static_cast<quint16>((angle - (static_cast<int>(angle))) *
100)); 100));
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::setStopAngle(double angle) void ServoController::setStopAngle(double angle)
{ {
_modbusWrapper.setSingleRegister(SRV_STOP_ANGLE_INT_PART_REG, static_cast<quint16>(angle)); _modbusWrapper.setSingleRegister(SRV_STOP_ANGLE_INT_PART_REG, static_cast<quint16>(angle));
_modbusWrapper.setSingleRegister(SRV_STOP_ANGLE_FRAC_PART_REG, _modbusWrapper.setSingleRegister(SRV_STOP_ANGLE_FRAC_PART_REG,
static_cast<quint16>((angle - (static_cast<int>(angle))) * static_cast<quint16>((angle - (static_cast<int>(angle))) *
100)); 100));
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::setSpeed(double speed) void ServoController::setSpeed(double speed)
{ {
_modbusWrapper.setSingleRegister(SRV_AZIMUTH_SPEED_REG, _modbusWrapper.setSingleRegister(SRV_AZIMUTH_SPEED_REG,
static_cast<quint16>(speed * SRV_SPEED_FACTOR)); static_cast<quint16>(speed * SRV_SPEED_FACTOR));
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::changeMode(double startAngle, double stopAngle, double speed) void ServoController::changeMode(double startAngle, double stopAngle, double speed)
{ {
setStartAngle(startAngle); setStartAngle(startAngle);
setStopAngle(stopAngle); setStopAngle(stopAngle);
setSpeed(speed); setSpeed(speed);
setStartStop(true); setStartStop(true);
enableDrive(); enableDrive();
apply(); apply();
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::init(QString serialPort) void ServoController::init(QString serialPort)
{ {
_modbusWrapper.init(); _modbusWrapper.close();
_modbusWrapper.connectToDevice(initiateConfig(serialPort)); _modbusWrapper.init();
_modbusWrapper.connectToDevice(initiateConfig(serialPort));
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::startMoving() void ServoController::startMoving()
{ {
setStartStop(true); setStartStop(true);
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::stopMoving() void ServoController::stopMoving()
{ {
setStartStop(false); setStartStop(false);
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::resetAzimuth() void ServoController::resetAzimuth()
{ {
_modbusWrapper.setSingleRegister(SRV_CALIBRATE_REG, SRV_CALIBRATION_VAL); _modbusWrapper.setSingleRegister(SRV_CALIBRATE_REG, SRV_CALIBRATION_VAL);
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::fix(double angle) void ServoController::fix(double angle)
{ {
changeMode(angle, angle, 5 / 6.0); changeMode(angle, angle, 5 / 6.0);
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::sector(double startAngle, double stopAngle, double speed) void ServoController::sector(double startAngle, double stopAngle, double speed)
{ {
changeMode(startAngle, stopAngle, speed); changeMode(startAngle, stopAngle, speed);
} }
/*************************************************************************************************/ /*************************************************************************************************/
double ServoController::getSpeed() double ServoController::getSpeed()
{ {
auto speedVector = _modbusWrapper.getHoldingRegister(SRV_AZIMUTH_SPEED_REG, 1); auto speedVector = _modbusWrapper.getHoldingRegister(SRV_AZIMUTH_SPEED_REG, 1);
return (speedVector[0] / SRV_SPEED_FACTOR); return (speedVector[0] / SRV_SPEED_FACTOR);
} }
/*************************************************************************************************/ /*************************************************************************************************/
double ServoController::getStopAngle() double ServoController::getStopAngle()
{ {
auto speedVector1 = _modbusWrapper.getHoldingRegister(SRV_STOP_ANGLE_INT_PART_REG, 1); auto speedVector1 = _modbusWrapper.getHoldingRegister(SRV_STOP_ANGLE_INT_PART_REG, 1);
auto speedVector2 = _modbusWrapper.getHoldingRegister(SRV_STOP_ANGLE_FRAC_PART_REG, 1); auto speedVector2 = _modbusWrapper.getHoldingRegister(SRV_STOP_ANGLE_FRAC_PART_REG, 1);
return (speedVector1[0] + speedVector2[0] / SRV_ANGLE_FACTOR); return (speedVector1[0] + speedVector2[0] / SRV_ANGLE_FACTOR);
} }
/*************************************************************************************************/ /*************************************************************************************************/
double ServoController::getStartAngle() double ServoController::getStartAngle()
{ {
auto speedVector1 = _modbusWrapper.getHoldingRegister(SRV_START_ANGLE_INT_PART_REG, 1); auto speedVector1 = _modbusWrapper.getHoldingRegister(SRV_START_ANGLE_INT_PART_REG, 1);
auto speedVector2 = _modbusWrapper.getHoldingRegister(SRV_START_ANGLE_FRAC_PART_REG, 1); auto speedVector2 = _modbusWrapper.getHoldingRegister(SRV_START_ANGLE_FRAC_PART_REG, 1);
return (speedVector1[0] + speedVector2[0] / SRV_ANGLE_FACTOR); return (speedVector1[0] + speedVector2[0] / SRV_ANGLE_FACTOR);
} }
/*************************************************************************************************/ /*************************************************************************************************/
double ServoController::getAngleOffset() double ServoController::getAngleOffset()
{ {
auto angleOffsetVector = _modbusWrapper.getHoldingRegister(SRV_ZERO_OFFSET_ANGLE, 1); auto angleOffsetVector = _modbusWrapper.getHoldingRegister(SRV_ZERO_OFFSET_ANGLE, 1);
return (angleOffsetVector[0] / SRV_ANGLE_FACTOR); return (angleOffsetVector[0] / SRV_ANGLE_FACTOR);
} }
/*************************************************************************************************/ /*************************************************************************************************/
void ServoController::setAngleOffset(double offset) void ServoController::setAngleOffset(double offset)
{ {
_modbusWrapper.setSingleRegister(SRV_ZERO_OFFSET_ANGLE, _modbusWrapper.setSingleRegister(SRV_ZERO_OFFSET_ANGLE,
static_cast<quint16>(offset * SRV_ANGLE_FACTOR)); static_cast<quint16>(offset * SRV_ANGLE_FACTOR));
} }
/*************************************************************************************************/ /*************************************************************************************************/
double ServoController::getAzimuth() double ServoController::getAzimuth()
{ {
auto azimuthVector = _modbusWrapper.getHoldingRegister(SRV_AZIMUTH_REG, 1); auto azimuthVector = _modbusWrapper.getHoldingRegister(SRV_AZIMUTH_REG, 1);
return (azimuthVector[0] / SRV_ANGLE_FACTOR); return (azimuthVector[0] / SRV_ANGLE_FACTOR);
}
/*************************************************************************************************/
bool ServoController::getStatus()
{
return _modbusWrapper.getStatus();
} }

391
Test/MainWindow.cpp

@ -1,287 +1,292 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "ui_MainWindow.h" #include "ui_MainWindow.h"
#include "QtConcurrent/QtConcurrent"
MainWindow::MainWindow(QWidget* parent) MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent) : QMainWindow(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("Coils"), 0);
ui->writeTable->addItem(tr("Discrete Inputs"), 1); ui->writeTable->addItem(tr("Discrete Inputs"), 1);
ui->writeTable->addItem(tr("Input Registers"), 2); ui->writeTable->addItem(tr("Input Registers"), 2);
ui->writeTable->addItem(tr("Holding Registers"), 3); ui->writeTable->addItem(tr("Holding Registers"), 3);
} }
/*************************************************************************************************/ /*************************************************************************************************/
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
delete ui; delete ui;
timer->stop();
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_connect_clicked() void MainWindow::on_connect_clicked()
{ {
try try
{ {
configDevice.serialPort = "/dev/pts/2"; configDevice.serialPort = "/dev/pts/2";
configDevice.clientAddress = 1; configDevice.clientAddress = 1;
configDevice.responseTime = 1000; configDevice.responseTime = 1000;
qDebug() << "before init"; qDebug() << "before init";
modbusWrapper.init(); modbusWrapper.init();
qDebug() << "after init"; qDebug() << "after init";
qDebug() << "before connect"; qDebug() << "before connect";
modbusWrapper.connectToDevice(configDevice); modbusWrapper.connectToDevice(configDevice);
qDebug() << "after connect"; qDebug() << "after connect";
ui->errorMonitoring->setText("No Error"); ui->errorMonitoring->setText("No Error");
} }
catch(ServoException ex) catch(ServoException ex)
{ {
ui->errorMonitoring->setText(ex.getMessage()); ui->errorMonitoring->setText(ex.getMessage());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_readButton_clicked() void MainWindow::on_readButton_clicked()
{ {
int startAddress = ui->startAddress->text().toInt(); int startAddress = ui->startAddress->text().toInt();
int numberOfEntries = ui->readSize->text().toInt(); int numberOfEntries = ui->readSize->text().toInt();
try try
{ {
switch(ui->writeTable->currentData().toInt()) switch(ui->writeTable->currentData().toInt())
{ {
case 0: case 0:
printCoilsDataFromClient(modbusWrapper.getCoil(startAddress, printCoilsDataFromClient(modbusWrapper.getCoil(startAddress,
static_cast<quint16>(numberOfEntries))); static_cast<quint16>(numberOfEntries)));
break; break;
case 1: case 1:
printCoilsDataFromClient(modbusWrapper.getInputCoil(startAddress, printCoilsDataFromClient(modbusWrapper.getInputCoil(startAddress,
static_cast<quint16>( static_cast<quint16>(
numberOfEntries))); numberOfEntries)));
break; break;
case 2: case 2:
printRegisterDataFromClient(modbusWrapper.getInputRegister(startAddress, printRegisterDataFromClient(modbusWrapper.getInputRegister(startAddress,
static_cast<quint16>( static_cast<quint16>(
numberOfEntries))); numberOfEntries)));
break; break;
case 3: case 3:
printRegisterDataFromClient(modbusWrapper.getHoldingRegister(startAddress, printRegisterDataFromClient(modbusWrapper.getHoldingRegister(startAddress,
static_cast<quint16>( static_cast<quint16>(
numberOfEntries))); numberOfEntries)));
break; break;
} }
ui->errorMonitoring->setText("No Error"); ui->errorMonitoring->setText("No Error");
} }
catch(const ServoException& exp) catch(const ServoException& exp)
{ {
ui->errorMonitoring->setText(exp.getMessage()); ui->errorMonitoring->setText(exp.getMessage());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::printCoilsDataFromClient(QBitArray uiCoils) void MainWindow::printCoilsDataFromClient(QBitArray uiCoils)
{ {
QString readedData; QString readedData;
for(int i = 0; i < uiCoils.count(); i++) for(int i = 0; i < uiCoils.count(); i++)
{ {
const QString entry = tr("Number: %1, Value: %2").arg(i) const QString entry = tr("Number: %1, Value: %2").arg(i)
.arg(QString::number(uiCoils[i])); .arg(QString::number(uiCoils[i]));
readedData += (entry + "\n"); readedData += (entry + "\n");
} }
ui->textEditRead->setText(readedData); ui->textEditRead->setText(readedData);
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::printRegisterDataFromClient(QVector<quint16> uiHoldingRegisters) void MainWindow::printRegisterDataFromClient(QVector<quint16> uiHoldingRegisters)
{ {
QString readedData; QString readedData;
for(int i = 0; i < uiHoldingRegisters.count(); i++) for(int i = 0; i < uiHoldingRegisters.count(); i++)
{ {
const QString entry = tr("Number: %1, Value: %2").arg(i) const QString entry = tr("Number: %1, Value: %2").arg(i)
.arg(QString::number(uiHoldingRegisters[i])); .arg(QString::number(uiHoldingRegisters[i]));
readedData += (entry + "\n"); readedData += (entry + "\n");
} }
ui->textEditRead->setText(readedData); ui->textEditRead->setText(readedData);
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_writeSingleCoil_clicked() void MainWindow::on_writeSingleCoil_clicked()
{ {
try { try {
int startAddress = ui->writeSingleCoilAddress->text().toInt(); int startAddress = ui->writeSingleCoilAddress->text().toInt();
modbusWrapper.setSingleCoil(startAddress, ui->coilData->isChecked()); modbusWrapper.setSingleCoil(startAddress, ui->coilData->isChecked());
ui->errorMonitoring->setText("No Error"); ui->errorMonitoring->setText("No Error");
} }
catch(const ServoException& exp) catch(const ServoException& exp)
{ {
ui->errorMonitoring->setText(exp.getMessage()); ui->errorMonitoring->setText(exp.getMessage());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_writeMultiCoil_clicked() void MainWindow::on_writeMultiCoil_clicked()
{ {
try { try {
int startAddress = ui->writeMultiCoilStartAddress->text().toInt(); int startAddress = ui->writeMultiCoilStartAddress->text().toInt();
int writeQty = ui->writeMultiCoilQty->text().toInt(); int writeQty = ui->writeMultiCoilQty->text().toInt();
QString valueToWrite = ui->writeMultiCoilValue->text(); QString valueToWrite = ui->writeMultiCoilValue->text();
QBitArray uiCoils; QBitArray uiCoils;
uiCoils.resize(writeQty); uiCoils.resize(writeQty);
for(int i = 0; i < valueToWrite.size(); i++) for(int i = 0; i < valueToWrite.size(); i++)
{ {
if(valueToWrite.at(i) == '0') if(valueToWrite.at(i) == '0')
uiCoils[i] = false; uiCoils[i] = false;
else else
uiCoils[i] = true; uiCoils[i] = true;
} }
modbusWrapper.setMultipleCoil(startAddress, static_cast<quint16>(writeQty), uiCoils); modbusWrapper.setMultipleCoil(startAddress, static_cast<quint16>(writeQty), uiCoils);
ui->errorMonitoring->setText("No Error"); ui->errorMonitoring->setText("No Error");
} }
catch(const ServoException& exp) catch(const ServoException& exp)
{ {
ui->errorMonitoring->setText(exp.getMessage()); ui->errorMonitoring->setText(exp.getMessage());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_writeSingleRegister_clicked() void MainWindow::on_writeSingleRegister_clicked()
{ {
try { try {
int startAddress = ui->writeSingleRegisterAddress->text().toInt(); int startAddress = ui->writeSingleRegisterAddress->text().toInt();
quint16 value = static_cast<quint16>(ui->writeSingleRegisterValue->text().toInt()); quint16 value = static_cast<quint16>(ui->writeSingleRegisterValue->text().toInt());
modbusWrapper.setSingleRegister(startAddress, value); modbusWrapper.setSingleRegister(startAddress, value);
ui->errorMonitoring->setText("No Error"); ui->errorMonitoring->setText("No Error");
} }
catch(const ServoException& exp) catch(const ServoException& exp)
{ {
ui->errorMonitoring->setText(exp.getMessage()); ui->errorMonitoring->setText(exp.getMessage());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_writeMultiRegister_clicked() void MainWindow::on_writeMultiRegister_clicked()
{ {
try { try {
int startAddress = ui->writeMultiRegisterStartAddress->text().toInt(); int startAddress = ui->writeMultiRegisterStartAddress->text().toInt();
int writeQty = ui->writeMultiRegisterQty->text().toInt(); int writeQty = ui->writeMultiRegisterQty->text().toInt();
QString valueToWrite = ui->writeMultiRegisterValue->text(); QString valueToWrite = ui->writeMultiRegisterValue->text();
QVector<quint16> uiHoldingRegisters; QVector<quint16> uiHoldingRegisters;
uiHoldingRegisters.resize(writeQty); uiHoldingRegisters.resize(writeQty);
QRegExp rx("(\\ |\\,|\\.|\\:|\\t)"); //RegEx for ' ' or ',' or '.' or ':' or '\t' QRegExp rx("(\\ |\\,|\\.|\\:|\\t)"); //RegEx for ' ' or ',' or '.' or ':' or '\t'
QStringList stringListValue = valueToWrite.split(rx); QStringList stringListValue = valueToWrite.split(rx);
for(int i = 0; i < stringListValue.size(); i++) for(int i = 0; i < stringListValue.size(); i++)
{ {
uiHoldingRegisters[i] = static_cast<quint16>(stringListValue[i].toInt()); uiHoldingRegisters[i] = static_cast<quint16>(stringListValue[i].toInt());
} }
modbusWrapper.setMultipleRegister(startAddress, modbusWrapper.setMultipleRegister(startAddress,
static_cast<quint16>(writeQty), static_cast<quint16>(writeQty),
uiHoldingRegisters); uiHoldingRegisters);
ui->errorMonitoring->setText("No Error"); ui->errorMonitoring->setText("No Error");
} }
catch(const ServoException& exp) catch(const ServoException& exp)
{ {
ui->errorMonitoring->setText(exp.getMessage()); ui->errorMonitoring->setText(exp.getMessage());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_init_clicked() void MainWindow::on_init_clicked()
{ {
try { try {
_servoControler.init(ui->serialPortServo->text()); ui->showServoError->setText("");
timer = new QTimer(); _servoControler.init(ui->serialPortServo->text());
timer->setInterval(1000); QtConcurrent::run(this,&MainWindow::handleGetRequestFromServo);
timer->start(); }
connect(timer, &QTimer::timeout, this, &MainWindow::handleGetRequestFromServo); catch(ServoException exp)
} {
catch(ServoException exp) ui->showServoError->setText(exp.getMessage());
{ }
ui->showServoError->setText(exp.getMessage());
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::handleGetRequestFromServo() void MainWindow::handleGetRequestFromServo()
{ {
try { while(1)
ui->showSpeed->setText(QString::number(_servoControler.getSpeed())); {
ui->showStartAngle->setText(QString::number(_servoControler.getStartAngle())); try {
ui->showStopAngle->setText(QString::number(_servoControler.getStopAngle())); ui->showSpeed->setText(QString::number(_servoControler.getSpeed()));
ui->showAngleOffset->setText(QString::number(_servoControler.getAngleOffset())); ui->showStartAngle->setText(QString::number(_servoControler.getStartAngle()));
ui->showAzimuth->setText(QString::number(_servoControler.getAzimuth())); ui->showStopAngle->setText(QString::number(_servoControler.getStopAngle()));
} ui->showAngleOffset->setText(QString::number(_servoControler.getAngleOffset()));
catch(ServoException exp) ui->showAzimuth->setText(QString::number(_servoControler.getAzimuth()));
{ ui->showServoError->setText("");
ui->showServoError->setText(exp.getMessage()); QThread::sleep(2);
} }
catch(ServoException exp)
{
ui->showServoError->setText(exp.getMessage());
}
auto currentstatus=_servoControler.getStatus();
ui->connectionState->setText(QVariant(currentstatus).toString());
}
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_startMoving_clicked() void MainWindow::on_startMoving_clicked()
{ {
try { try {
_servoControler.startMoving(); _servoControler.startMoving();
} }
catch(ServoException exp) catch(ServoException exp)
{ {
ui->showServoError->setText(exp.getMessage()); ui->showServoError->setText(exp.getMessage());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_stopMoving_clicked() void MainWindow::on_stopMoving_clicked()
{ {
try { try {
_servoControler.stopMoving(); _servoControler.stopMoving();
} }
catch(ServoException exp) catch(ServoException exp)
{ {
ui->showServoError->setText(exp.getMessage()); ui->showServoError->setText(exp.getMessage());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_ResetAzimuth_clicked() void MainWindow::on_ResetAzimuth_clicked()
{ {
try { try {
_servoControler.resetAzimuth(); _servoControler.resetAzimuth();
} }
catch(ServoException exp) catch(ServoException exp)
{ {
ui->showServoError->setText(exp.getMessage()); ui->showServoError->setText(exp.getMessage());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_sectorSpeed_clicked() void MainWindow::on_sectorSpeed_clicked()
{ {
try { try {
_servoControler.sector(ui->startAngle->text().toDouble(), _servoControler.sector(ui->startAngle->text().toDouble(),
ui->stopAngle->text().toDouble(), ui->stopAngle->text().toDouble(),
ui->speed->text().toDouble()); ui->speed->text().toDouble());
} }
catch(ServoException exp) catch(ServoException exp)
{ {
ui->showServoError->setText(exp.getMessage()); ui->showServoError->setText(exp.getMessage());
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
void MainWindow::on_fix_clicked() void MainWindow::on_fix_clicked()
{ {
try { try {
_servoControler.fix(ui->startAngle->text().toDouble()); _servoControler.fix(ui->startAngle->text().toDouble());
} }
catch(ServoException exp) catch(ServoException exp)
{ {
ui->showServoError->setText(exp.getMessage()); ui->showServoError->setText(exp.getMessage());
} }
} }

36
Test/MainWindow.ui

@ -621,6 +621,40 @@ background-color: rgb(186, 178, 158);</string>
</rect> </rect>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="label_18">
<property name="geometry">
<rect>
<x>180</x>
<y>0</y>
<width>181</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Connection State to Client:</string>
</property>
</widget>
<widget class="QLabel" name="connectionState">
<property name="geometry">
<rect>
<x>370</x>
<y>0</y>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(52, 101, 164);
color: rgb(238, 238, 236);
</string>
</property>
<property name="text">
<string/>
</property>
<property name="margin">
<number>0</number>
</property>
</widget>
</widget> </widget>
<widget class="QGroupBox" name="groupBox_12"> <widget class="QGroupBox" name="groupBox_12">
<property name="geometry"> <property name="geometry">
@ -923,7 +957,7 @@ color: rgb(238, 238, 236);
background-color: rgb(186, 178, 158);</string> background-color: rgb(186, 178, 158);</string>
</property> </property>
<property name="text"> <property name="text">
<string>Error Monitoring</string> <string/>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>

22
Test/main.cpp

@ -15,18 +15,18 @@ public:
} }
//reimplemented from QApplication so we can throw exceptions in slots //reimplemented from QApplication so we can throw exceptions in slots
virtual bool notify(QObject* receiver, QEvent* event) { // virtual bool notify(QObject* receiver, QEvent* event) {
try { // try {
return QApplication::notify(receiver, event); // return QApplication::notify(receiver, event);
} // }
catch(std::exception& e) // catch(std::exception& e)
{ // {
qDebug() << "e exception " << e.what(); // qDebug() << "e exception " << e.what();
; // ;
} // }
return false; // return false;
} // }
}; };
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {

Loading…
Cancel
Save