|
|
@ -1,6 +1,7 @@ |
|
|
|
#include "ModbusMaster.h" |
|
|
|
|
|
|
|
#include <QModbusRtuSerialMaster> |
|
|
|
#include <QEventLoop> |
|
|
|
|
|
|
|
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<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(); |
|
|
|
} |
|
|
|