#include "ModbusMaster.h" #include #include #include #include "QtConcurrent/QtConcurrent" #include "SerialportException.h" enum { NumColumn = 0, CoilsColumn = 1, HoldingColumn = 2, ColumnCount = 3, RowCount = 10 }; ModBusMaster::ModBusMaster(QObject *parent) : QObject(parent) { qDebug() << "in ModBusMaster" <disconnectDevice(); delete modbusDevice; } void ModBusMaster::stop() { if (modbusDevice) modbusDevice->disconnectDevice(); emit modbusConnectionState(false); } void ModBusMaster::setSingleCoil(int startAddress,bool coilFlag) { if (!modbusDevice) return; _coilFlags.setBit(0,coilFlag); writeRequest(QModbusDataUnit::RegisterType::Coils, startAddress, 1); } void ModBusMaster::setMultipleCoil(int startAddress, quint16 writeSize, QBitArray coilFlags) { if (!modbusDevice) return; _coilFlags = coilFlags; writeRequest(QModbusDataUnit::RegisterType::Coils, startAddress, writeSize); } void ModBusMaster::setSingleRegister(int startAddress, quint16 registerValue) { if (!modbusDevice) return; _registerValues[0]=registerValue; writeRequest(QModbusDataUnit::RegisterType::HoldingRegisters, startAddress, 1); } void ModBusMaster::setMultipleRegister(int startAddress, quint16 writeSize , QVector registerValues) { if (!modbusDevice) return; _registerValues = registerValues; writeRequest(QModbusDataUnit::RegisterType::HoldingRegisters, startAddress, writeSize); } QBitArray ModBusMaster::getCoil(int startAddress, quint16 readSize) { objsimModbus.readCoil(startAddress,readSize); return clientCoil; } void ModBusMaster::modbusReplyRecieved() { } QBitArray ModBusMaster::getInputCoil(int startAddress, quint16 readSize) { QModbusDataUnit unit = readRequest(QModbusDataUnit::RegisterType::DiscreteInputs, startAddress, readSize); QBitArray coils; coils.resize(2); auto num = unit.valueCount(); coils.resize(static_cast(num)); for (uint i = 0; i < unit.valueCount(); i++) { coils.setBit((unit.value(i))); } return coils ; } QVector ModBusMaster::getInputRegister(int startAddress, quint16 readSize) { QModbusDataUnit unit = readRequest(QModbusDataUnit::RegisterType::InputRegisters, startAddress, readSize); QVector registerValues; registerValues.resize(2); auto num = unit.valueCount(); registerValues.resize(static_cast(num)); for (uint i = 0; i < unit.valueCount(); i++) { registerValues[i]=unit.value(i); } return registerValues ; } QVector ModBusMaster::getHoldingRegister(int startAddress, quint16 readSize) { // if (!modbusDevice) // return; QModbusDataUnit unit = readRequest(QModbusDataUnit::RegisterType::HoldingRegisters, startAddress, readSize); QVector registerValues; registerValues.resize(2); auto num = unit.valueCount(); registerValues.resize(static_cast(num)); for (uint i = 0; i < unit.valueCount(); i++) { registerValues[i]=unit.value(i); } return registerValues ; } QModbusDataUnit ModBusMaster::readRequest(QModbusDataUnit::RegisterType registerType, int startAddress, quint16 readSize) { qDebug() << " QThread::currentThreadId() readRequest1" <sendReadRequest(QModbusDataUnit(table, startAddress, readSize), _slaveAddress)) { QFuture future = QtConcurrent::run([this, reply]() { qDebug() << " QThread::currentThreadId() inside worker thread" <isFinished()) // { // qDebug() << "reply->isFinished() " << reply->isFinished(); // qDebug() << "Hello from thread " << QThread::currentThread(); // } if (!reply->isFinished()) { qDebug() << " QThread::currentThreadId() inside worker thread isFinished" <isFinished() " << reply->isFinished(); connect(reply, &QModbusReply::finished, this, &ModBusMaster::modbusReplyRecieved); qDebug() << "2reply->isFinished() " << reply->isFinished(); } }); qDebug() << " QThread::currentThreadId() readRequest3" <result(); return unit; } } else { throw serialPortException(modbusDevice->errorString()); } reply->deleteLater(); } bool ModBusMaster::checkForError(QModbusReply *_reply) { if (_reply->error() == QModbusDevice::NoError) { return false; } else if (_reply->error() == QModbusDevice::ProtocolError) { throw serialPortException(tr("Read response error: %1 (Mobus exception: 0x%2)"). arg(reply->errorString()). arg(reply->rawResult().exceptionCode(), -1, 16)); } else { throw serialPortException(tr("Read response error: %1 (code: 0x%2)"). arg(reply->errorString()). arg(reply->error(), -1, 16)); } } void ModBusMaster::modbusReplyRecievedSimulate(QBitArray coilDataFromClient) { clientCoil = coilDataFromClient; } void ModBusMaster::writeRequest(QModbusDataUnit::RegisterType registerType, int startAddress, quint16 writeSize) { qDebug() << " ---- setSingleCoil coilFlag writeRequest "; auto table =registerType; Q_ASSERT(startAddress >= 0 && startAddress < 10); QModbusDataUnit writeUnit = QModbusDataUnit(table, startAddress, writeSize); qDebug() << " ---- writeUnit.valueCount()" << writeUnit.valueCount(); for (int i = 0; i < writeUnit.valueCount(); i++) { if (table == QModbusDataUnit::Coils) writeUnit.setValue(i, _coilFlags[i + writeUnit.startAddress()]); else writeUnit.setValue(i, _registerValues[i + writeUnit.startAddress()]); } if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, _slaveAddress)) { QFuture future = QtConcurrent::run([this, reply]() { while(!reply->isFinished()) { qDebug() << "reply->isFinished() " << reply->isFinished(); } qDebug() << "reply->isFinished() after " << reply->isFinished(); if(!checkForError(reply)) { const QModbusDataUnit unit = reply->result(); } }); // future.waitForFinished(); // if (!reply->isFinished()) { // connect(reply, &QModbusReply::finished, this, [reply]() { // if (reply->error() == QModbusDevice::ProtocolError) { // throw serialPortException(tr("Write response error: %1 (Mobus exception: 0x%2)") // .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16)); // } else if (reply->error() != QModbusDevice::NoError) { // throw serialPortException(tr("Write response error: %1 (code: 0x%2)"). // arg(reply->errorString()).arg(reply->error(), -1, 16)); // } // reply->deleteLater(); // }); // } else { //reply->deleteLater(); //} qDebug() << " ---- sreply reply "<< reply->error(); } else { throw serialPortException(tr("Write error: ") + modbusDevice->errorString()); } }