#include "modbusmaster.h" #include #include #include "serialportexception.h" modBusMaster::modBusMaster(QObject *parent) : QObject(parent) { } void modBusMaster::init() { close(); modbusDevice = nullptr; modbusDevice = new QModbusRtuSerialMaster(this); connect(modbusDevice, &QModbusClient::errorOccurred, [this](QModbusDevice::Error) { throw serialPortException(modbusDevice->errorString()); }); if (!modbusDevice) throw serialPortException("Could not create Modbus master."); } void modBusMaster::open(QString _serialPort , int _serverId) { serialPort=_serialPort; serverId=_serverId; if (!modbusDevice) return; if (modbusDevice->state() != QModbusDevice::ConnectedState) { modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, serialPort); #if QT_CONFIG(modbus_serialport) modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, modbusSettings.parity); modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, modbusSettings.baud); modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, modbusSettings.dataBits); modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, modbusSettings.stopBits); #endif modbusDevice->setTimeout(modbusSettings.responseTime); modbusDevice->setNumberOfRetries(modbusSettings.numberOfRetries); } if (!modbusDevice->connectDevice()) { throw serialPortException(modbusDevice->errorString()); } } void modBusMaster::close() { if (modbusDevice) modbusDevice->disconnectDevice(); delete modbusDevice; } void modBusMaster::stop() { } void modBusMaster::getCoil(int startAddress, quint16 readSize) { if (!modbusDevice) return; readRequest(QModbusDataUnit::RegisterType::Coils, startAddress, readSize); } void modBusMaster::getInputCoil(int startAddress, quint16 readSize) { if (!modbusDevice) return; readRequest(QModbusDataUnit::RegisterType::DiscreteInputs, startAddress, readSize); } void modBusMaster::getInputRegister(int startAddress, quint16 readSize) { if (!modbusDevice) return; readRequest(QModbusDataUnit::RegisterType::InputRegisters, startAddress, readSize); } void modBusMaster::getHoldingRegister(int startAddress, quint16 readSize) { if (!modbusDevice) return; readRequest(QModbusDataUnit::RegisterType::HoldingRegisters, startAddress, readSize); } void modBusMaster::readRequest(QModbusDataUnit::RegisterType registerType, int startAddress, quint16 readSize) { auto table =registerType; Q_ASSERT(startAddress >= 0 && startAddress < 10); reply=modbusDevice->sendReadRequest(QModbusDataUnit(table, startAddress, readSize), serverId) ; if (reply) { if (!reply->isFinished()) connect(reply, &QModbusReply::finished, this, &modBusMaster::readReady); else delete reply; // broadcast replies return immediately } else { throw serialPortException(modbusDevice->errorString()); } } void modBusMaster::writeRequest(QModbusDataUnit::RegisterType registerType, int startAddress, quint16 readSize) { auto table =registerType; Q_ASSERT(startAddress >= 0 && startAddress < 10); QModbusDataUnit writeUnit = QModbusDataUnit(table, startAddress, readSize); for (int i = 0; i < writeUnit.valueCount(); i++) { if (table == QModbusDataUnit::Coils) writeUnit.setValue(i, m_coils[i + writeUnit.startAddress()]); else writeUnit.setValue(i, m_holdingRegisters[i + writeUnit.startAddress()]); } if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, serverId)) { if (!reply->isFinished()) { connect(reply, &QModbusReply::finished, this, [this, reply]() { if (reply->error() == QModbusDevice::ProtocolError) { throw serialPortException("Write response error: %1 (Mobus exception: 0x%2)"); } else if (reply->error() != QModbusDevice::NoError) { throw serialPortException("Write response error: %1 (code: 0x%2)"); } reply->deleteLater(); }); } else { // broadcast replies return immediately reply->deleteLater(); } } else { throw serialPortException(tr("Write error: ") + modbusDevice->errorString()); } } void modBusMaster::readReady() { }