Qt Modbus通信(RTU模式)


相關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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM