zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    【代码笔记】iOS-点击搜索跳转到另外一个页面
    【代码笔记】iOS-仿安卓,本页出现多个选择项
    【代码笔记】iOS-点击任何处,显示出红色的UIView
    【代码笔记】iOS-点击任何处,出现城市
    【代码笔记】iOS-点击加号增加书架,点击减号减少书架
    【代码笔记】iOS-点击出现选择框
    【代码笔记】iOS-底下滚动,上面标题栏也会跟着变动
    【代码笔记】iOS-等待动画
    【代码笔记】iOS-登陆单例
    【代码笔记】iOS-获得现在的时间
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14372585.html
Copyright © 2011-2022 走看看