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