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