一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

相关Qt Class

  • QModbusRtuSerialSlave (服务器类)
  • QModbusServer
  • QModbusDevice
  • QModbusClient
  • QModbusRtuSerialMaster(客户端类)
  • QModbusRequest 
  • QModbusResponse
  • QModbusReply
  • QModbusDataUnit

通信流程

创建QModbusRtuSerialMaster对象m_modbusDevice,并设置串口通信参数:

1  m_modbusDevice.setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::EvenParity);
2  m_modbusDevice.setConnectionParameter(QModbusDevice::SerialBaudRateParameter, QSerialPort::Baud9600);
3  m_modbusDevice.setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
4  m_modbusDevice.setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);

串口连接:

1 bool connectDevice()
2 {
3     //implement
4 }

连接成功后,发送请求:

1 QModbusResponse sendModbusRawRequest(const QModbusRequest &request) const
2 {
3     //implement
4 }

断开连接:

1 void disconnectDevice()
2 {
3     //implement
4 }

示例代码

tempCtrl.h

 1 #ifndef TEMPCTRL_H
 2 #define TEMPCTRL_H
 3 
 4 #include 
 5 
 6 class TempCtrl
 7 {
 8 private:
 9     TempCtrl();
10 
11 public:
12     ~TempCtrl();
13     static TempCtrl* instance();
14 
15 public:    
16     void connectDevice();
17     void disconnectDevice();
18     
19 private:
20     QModbusResponse sendModbusRawRequest(const QModbusRequest &request) const;
21 
22 private:
23     bool m_channelConnected;
24     int m_channelAddr;
25     mutable QModbusRtuSerialMaster m_modbusDevice;
26 };
27 #endif // TEMPCTRL_H

tempCtrl.cpp 

  1 #include "TempCtrl.h"
  2 
  3 #include 
  4 #include 
  5 #include 
  6 
  7 #include 
  8 #include 
  9 #include 
 10 
 11 TempCtrl::TempCtrl()
 12     , m_channelConnected(false)
 13     , m_channelAddr(0)
 14     , m_modbusDevice()
 15 {
 16     m_modbusDevice.setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::EvenParity);
 17     m_modbusDevice.setConnectionParameter(QModbusDevice::SerialBaudRateParameter, QSerialPort::Baud9600);
 18     m_modbusDevice.setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
 19     m_modbusDevice.setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
 20 }
 21 
 22 TempCtrl::~TempCtrl()
 23 {
 24     disconnectDevice();
 25 }
 26 
 27 TempCtrl* TempCtrl::instance()
 28 {
 29     static TempCtrl* theInstance = new TempCtrl();
 30     return theInstance;
 31 }
 32 
 33 bool TempCtrl::connectDevice()
 34 {
 35     disconnectDevice(); 
 36     
 37     const auto serialPortInfos = QSerialPortInfo::availablePorts();
 38     if(!serialPortInfos.empty())
 39     {
 40         QModbusRequest echoTest(QModbusRequest::Diagnostics, quint16(0x0000), quint16(0x1234));
 41 
 42         bool comportFound(false);
 43         for (const QSerialPortInfo &serialPortInfo : serialPortInfos)
 44         {
 45             m_modbusDevice.setConnectionParameter(QModbusDevice::SerialPortNameParameter, serialPortInfo.portName());
 46 
 47             if(m_modbusDevice.connectDevice())
 48             {
 49                 auto curTimePt = std::chrono::steady_clock::now();
 50                 double duration = 0;
 51 
 52                 while(m_modbusDevice.state() != QModbusDevice::ConnectedState && duration < 2.0)
 53                 {
 54                     QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 20);
 55                     std::chrono::duration d = std::chrono::steady_clock::now()-curTimePt;
 56                     duration = d.count();
 57                 }
 58 
 59                 if(m_modbusDevice.state() == QModbusDevice::ConnectedState)
 60                 {
 61                     try
 62                     {
 63                         QModbusResponse reply = sendModbusRawRequest(echoTest); 
 64                         if(reply.isValid())
 65                         {
 66                             if(reply.data() == QByteArray::fromHex("00001234"))
 67                             {
 68                                 if(!comportFound)
 69                                 {
 70                                     comportFound = true;
 71                                 }
 72                              m_channelConnected = true;
 73                             }
 74                         }
 75                     }
 76                     catch(...)
 77                     {
 78                     }
 79                 }
 80 
 81                 if(comportFound)
 82                 {
 83                     break;
 84                 }
 85                 else
 86                 {
 87                     m_modbusDevice.disconnectDevice();
 88                 }
 89             }
 90         }
 91     }
 92 
 93     m_modbusDevice.setTimeout(500);
 94     m_modbusDevice.setNumberOfRetries(3);
 95     return m_channelConnected;
 96 }
 97 
 98 void TempCtrl::disconnectDevice()
 99 {
100     if(m_modbusDevice.state() != QModbusDevice::UnconnectedState)
101     {
102         m_modbusDevice.disconnectDevice();
103     }
104     m_channelConnected = false;
105 }
106 
107 QModbusResponse TempCtrl::sendModbusRawRequest(const QModbusRequest &request) const
108 {
109     QModbusReply* reply = m_modbusDevice.sendRawRequest(request, m_channelAddr);
110 
111     if(reply)
112     {
113         while(!reply->isFinished())
114         {
115             QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 20);
116         }
117 
118         reply->deleteLater();
119 
120         if(reply->error() == QModbusDevice::NoError)
121         {
122             auto response = reply->rawResult();
123             std::this_thread::sleep_for(std::chrono::milliseconds(5));
124             return response;
125         }
126         else if (reply->error() == QModbusDevice::ProtocolError)
127         {
128             QString error = "Protocol error: " + reply->errorString();
129             throw std::exception(error.toStdString().c_str());
130         }
131         else if (reply->error() == QModbusDevice::TimeoutError)
132         {
133             throw std::exception("Timeout error");
134         }
135         else
136         {
137             throw std::exception("Unknown error");
138         }
139     }
140     else
141     {
142         return QModbusResponse();
143     }
144 }

 

posted on 2021-02-04 14:51  一杯清酒邀明月  阅读(8429)  评论(1编辑  收藏  举报

/* 看板娘 */