emsApplication/applications/examples/qmodbus_demo01/tempctrl.cpp

146 lines
4.2 KiB
C++
Raw Normal View History

2025-03-04 11:27:16 +08:00
#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();
}
}