146 lines
4.2 KiB
C++
146 lines
4.2 KiB
C++
|
#include "TempCtrl.h"
|
||
|
|
||
|
#include <QSerialPort>
|
||
|
#include <QSerialPortInfo>
|
||
|
#include <QModbusRequest>
|
||
|
|
||
|
#include <QEventLoop>
|
||
|
#include <QCoreApplication>
|
||
|
#include <QVariant>
|
||
|
|
||
|
#include <chrono>
|
||
|
#include <thread>
|
||
|
|
||
|
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();
|
||
|
}
|
||
|
}
|