|
|
@ -11,7 +11,7 @@ modBusMaster::modBusMaster(QObject *parent) : QObject(parent) |
|
|
|
|
|
|
|
void modBusMaster::init() |
|
|
|
{ |
|
|
|
stop(); |
|
|
|
close(); |
|
|
|
modbusDevice = nullptr; |
|
|
|
modbusDevice = new QModbusRtuSerialMaster(this); |
|
|
|
connect(modbusDevice, &QModbusClient::errorOccurred, [this](QModbusDevice::Error) |
|
|
@ -23,14 +23,133 @@ void modBusMaster::init() |
|
|
|
throw serialPortException("Could not create Modbus master."); |
|
|
|
} |
|
|
|
|
|
|
|
void modBusMaster::close() |
|
|
|
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::stop() |
|
|
|
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() |
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|