#include "TempCtrl.h" #include #include #include #include #include #include #include #include TempCtrl::TempCtrl(): m_channelConnected(false), m_channelAddr(0) { m_modbusDevice.setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::EvenParity); m_modbusDevice.setConnectionParameter(QModbusDevice::SerialBaudRateParameter, QSerialPort::Baud9600); m_modbusDevice.setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8); m_modbusDevice.setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop); } TempCtrl::~TempCtrl() { disconnectDevice(); } TempCtrl* TempCtrl::instance() { static TempCtrl* theInstance = new TempCtrl(); return theInstance; } bool TempCtrl::connectDevice() { disconnectDevice(); const auto serialPortInfos = QSerialPortInfo::availablePorts(); if(!serialPortInfos.empty()) { QModbusRequest echoTest(QModbusRequest::Diagnostics, quint16(0x0000), quint16(0x1234)); bool comportFound(false); for (const QSerialPortInfo &serialPortInfo : serialPortInfos) { m_modbusDevice.setConnectionParameter(QModbusDevice::SerialPortNameParameter, QVariant::fromValue(serialPortInfo.portName())); if(m_modbusDevice.connectDevice()) { auto curTimePt = std::chrono::steady_clock::now(); double duration = 0; while(m_modbusDevice.state() != QModbusDevice::ConnectedState && duration < 2.0) { QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 20); std::chrono::duration d = std::chrono::steady_clock::now()-curTimePt; duration = d.count(); } if(m_modbusDevice.state() == QModbusDevice::ConnectedState) { try { QModbusResponse reply = sendModbusRawRequest(echoTest); if(reply.isValid()) { if(reply.data() == QByteArray::fromHex("00001234")) { if(!comportFound) { comportFound = true; } m_channelConnected = true; } } } catch(...) { } } if(comportFound) { break; } else { m_modbusDevice.disconnectDevice(); } } } } m_modbusDevice.setTimeout(500); m_modbusDevice.setNumberOfRetries(3); return m_channelConnected; } void TempCtrl::disconnectDevice() { if(m_modbusDevice.state() != QModbusDevice::UnconnectedState) { m_modbusDevice.disconnectDevice(); } m_channelConnected = false; } QModbusResponse TempCtrl::sendModbusRawRequest(const QModbusRequest &request) const { QModbusReply* reply = m_modbusDevice.sendRawRequest(request, m_channelAddr); if(reply) { while(!reply->isFinished()) { QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 20); } reply->deleteLater(); if(reply->error() == QModbusDevice::NoError) { auto response = reply->rawResult(); std::this_thread::sleep_for(std::chrono::milliseconds(5)); return response; } else if (reply->error() == QModbusDevice::ProtocolError) { QString error = "Protocol error: " + reply->errorString(); throw std::exception(error.toStdString().c_str()); } else if (reply->error() == QModbusDevice::TimeoutError) { throw std::exception("Timeout error"); } else { throw std::exception("Unknown error"); } } else { return QModbusResponse(); } }