• QSerialPort的线程常用操作(包含心跳,读写延时方法等)


     1 #ifndef DATACOMMSERIAL_H
     2 #define DATACOMMSERIAL_H
     3 
     4 #include <QThread>
     5 #include <QSerialPort>
     6 
     7 struct tagSerialPortInfo
     8 {
     9     QString                     portName;
    10     qint32                      baudRate;
    11     QSerialPort::Directions     directions;
    12     QSerialPort::DataBits       dataBits;
    13     QSerialPort::FlowControl    flowControl;
    14     QSerialPort::Parity         parity;
    15     QSerialPort::StopBits       stopBits;
    16 
    17     tagSerialPortInfo()
    18     {
    19         directions = QSerialPort::AllDirections;
    20         dataBits = QSerialPort::Data8;
    21         flowControl = QSerialPort::NoFlowControl;
    22         parity = QSerialPort::NoParity;
    23         stopBits = QSerialPort::OneStop;
    24     }
    25 
    26     tagSerialPortInfo(QString name, qint32 rate):
    27         tagSerialPortInfo()
    28     {
    29         portName = name;
    30         baudRate = rate;
    31     }
    32 };
    33 
    34 enum SerialWorkMode
    35 {
    36     serial_send_time_to_live,
    37     serial_send_request_only,
    38     serial_send_request_recv_response,
    39     serial_send_request_check_response,
    40     serial_recv_response_only,
    41 };
    42 
    43 class IResponseValidate
    44 {
    45 public:
    46     virtual bool validate(const QByteArray& response) = 0;
    47 };
    48 
    49 class DataCommSerial : public QThread
    50 {
    51     Q_OBJECT
    52 public:
    53     explicit DataCommSerial(QObject *parent = 0);
    54 
    55     // 初始化串口信息
    56     void init(const tagSerialPortInfo& info);
    57 
    58     // 发送ttl信号
    59     void send_time_to_live(int interval_time_ms, int timeout_ms);
    60 
    61     // 仅发送数据
    62     void sendRequest_only(const QList<QByteArray>& datas, int timeout_ms);
    63 
    64     // 发送且接收应答
    65     void sendRequest_and_recvResponse(const QList<QByteArray>& datas, int timeout_ms);
    66 
    67     // 发送且检查应答
    68     void sendRequest_and_checkResponse(const QList<QByteArray>& datas, int timeout_ms, IResponseValidate* pValidate);
    69 
    70     // 仅接受数据
    71     void recvResponse_only();
    72 
    73     void run();
    74 
    75 signals:
    76     // 应答数据信号
    77     void sigRecvResponse(const QByteArray& data);
    78 
    79     // 校验应答数据信号
    80     void sigCheckResponse(bool valid, const QByteArray& data);
    81 
    82     // 异常提示信号
    83     void sigCatchException(const QString& info);
    84 
    85 public slots:
    86 
    87 private:
    88     QList<QByteArray>       m_request_datas;
    89     int                     m_ttl_interval_ms;
    90     int                     m_wait_timeout;
    91     tagSerialPortInfo       m_serialport_info;
    92     SerialWorkMode          m_serial_work_mode;
    93     IResponseValidate*      m_pResponseValidate;
    94 };
    95 
    96 #endif // DATACOMMSERIAL_H
      1 #include "datacommserial.h"
      2 #include <QDebug>
      3 #include <QDateTime>
      4 
      5 DataCommSerial::DataCommSerial(QObject *parent) : QThread(parent)
      6 {
      7     m_pResponseValidate = 0;
      8     m_ttl_interval_ms = 1000;
      9     m_wait_timeout = 5000;
     10 }
     11 
     12 void DataCommSerial::init(const tagSerialPortInfo& info)
     13 {
     14     m_serialport_info = info;
     15 }
     16 
     17 void DataCommSerial::send_time_to_live(int interval_time_ms, int timeout_ms)
     18 {
     19     m_serial_work_mode = serial_send_time_to_live;
     20     m_ttl_interval_ms = interval_time_ms;
     21     m_wait_timeout = timeout_ms;
     22 }
     23 
     24 void DataCommSerial::sendRequest_only(const QList<QByteArray>& datas, int timeout_ms)
     25 {
     26     m_serial_work_mode = serial_send_request_only;
     27     m_request_datas = datas;
     28     m_wait_timeout = timeout_ms;
     29 }
     30 
     31 void DataCommSerial::sendRequest_and_recvResponse(const QList<QByteArray>& datas, int timeout_ms)
     32 {
     33     m_serial_work_mode = serial_send_request_recv_response;
     34     m_request_datas = datas;
     35     m_wait_timeout = timeout_ms;
     36 }
     37 
     38 void DataCommSerial::sendRequest_and_checkResponse(const QList<QByteArray>& datas, int timeout_ms, IResponseValidate* pValidate)
     39 {
     40     m_serial_work_mode = serial_send_request_check_response;
     41     m_request_datas = datas;
     42     m_wait_timeout = timeout_ms;
     43     m_pResponseValidate = pValidate;
     44 }
     45 
     46 void DataCommSerial::recvResponse_only()
     47 {
     48     m_serial_work_mode = serial_recv_response_only;
     49 }
     50 
     51 void DataCommSerial::run()
     52 {
     53     QSerialPort serialport;
     54     tagSerialPortInfo& cfg = m_serialport_info;
     55     serialport.setPortName(cfg.portName);
     56     if(!serialport.setBaudRate(cfg.baudRate, cfg.directions)) return;
     57     if(!serialport.setDataBits(cfg.dataBits)) return;
     58     if(!serialport.setFlowControl(cfg.flowControl)) return;
     59     if(!serialport.setParity(cfg.parity)) return;
     60     if(!serialport.setStopBits(cfg.stopBits)) return;
     61     if(!serialport.open(QIODevice::ReadWrite))
     62     {
     63         emit sigCatchException("serialport open failture" + serialport.errorString());
     64         qDebug() << "serialport open failture" << serialport.errorString();
     65         return;
     66     }
     67 
     68     if(serial_send_time_to_live==m_serial_work_mode)
     69     {
     70         while (true)
     71         {
     72             QString ttl = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
     73             serialport.write(ttl.toLocal8Bit());
     74             if(!serialport.waitForBytesWritten(m_wait_timeout))
     75             {
     76                 emit sigCatchException("waitForBytesWritten timeout");
     77                 qDebug() << "waitForBytesWritten timeout" << ttl;
     78             }
     79 
     80             msleep(m_ttl_interval_ms);
     81         }
     82     }
     83     else if(serial_send_request_only==m_serial_work_mode)
     84     {
     85         foreach(QByteArray request_data, m_request_datas)
     86         {
     87             serialport.write(request_data);
     88             if(!serialport.waitForBytesWritten(m_wait_timeout))
     89             {
     90                 emit sigCatchException("waitForBytesWritten timeout");
     91                 qDebug() << "waitForBytesWritten timeout";
     92                 return;
     93             }
     94         }
     95     }
     96     else if(serial_send_request_recv_response==m_serial_work_mode)
     97     {
     98         foreach(QByteArray request_data, m_request_datas)
     99         {
    100             serialport.write(request_data);
    101             if(serialport.waitForBytesWritten(m_wait_timeout))
    102             {
    103                 if(serialport.waitForReadyRead(m_wait_timeout))
    104                 {
    105                     QByteArray response_data = serialport.readAll();
    106                     while(serialport.waitForReadyRead(50))
    107                     {
    108                         response_data += serialport.readAll();
    109                     }
    110                     qDebug() << response_data;
    111                     emit sigRecvResponse(response_data);
    112                 }
    113                 else
    114                 {
    115                     emit sigCatchException("waitForReadyRead timeout");
    116                     qDebug() << "waitForReadyRead timeout";
    117                     return;
    118                 }
    119             }
    120             else
    121             {
    122                 emit sigCatchException("waitForBytesWritten timeout");
    123                 qDebug() << "waitForBytesWritten timeout";
    124                 return;
    125             }
    126         }
    127     }
    128     else if(serial_send_request_check_response==m_serial_work_mode)
    129     {
    130         foreach(QByteArray request_data, m_request_datas)
    131         {
    132             serialport.write(request_data);
    133             if(serialport.waitForBytesWritten(m_wait_timeout))
    134             {
    135                 if(serialport.waitForReadyRead(m_wait_timeout))
    136                 {
    137                     QByteArray response_data = serialport.readAll();
    138                     while(serialport.waitForReadyRead(50))
    139                     {
    140                         response_data += serialport.readAll();
    141                     }
    142 
    143                     if(m_pResponseValidate)
    144                     {
    145                         bool bValid = m_pResponseValidate->validate(response_data);
    146                         qDebug() << bValid << response_data.toHex();
    147                         emit sigCheckResponse(bValid, response_data);
    148                     }
    149                     else
    150                     {
    151                         emit sigCatchException("m_pResponseValidate invalid");
    152                         qDebug() << "m_pResponseValidate invalid" << m_pResponseValidate;
    153                         return;
    154                     }
    155                 }
    156                 else
    157                 {
    158                     emit sigCatchException("waitForReadyRead timeout");
    159                     qDebug() << "waitForReadyRead timeout";
    160                     return;
    161                 }
    162             }
    163             else
    164             {
    165                 emit sigCatchException("waitForBytesWritten timeout");
    166                 qDebug() << "waitForBytesWritten timeout";
    167                 return;
    168             }
    169         }
    170     }
    171     else if(serial_recv_response_only==m_serial_work_mode)
    172     {
    173         while (true)
    174         {
    175             QByteArray response_data = serialport.readAll();
    176 
    177             while (serialport.waitForReadyRead(500))
    178             {
    179                 response_data += serialport.readAll();
    180             }
    181 
    182             if(!response_data.isEmpty())
    183             {
    184                 emit sigRecvResponse(response_data);
    185                 qDebug() << response_data;
    186             }
    187         }
    188     }
    189 }

    测试方法

    #ifndef DATACOMMMANAGER_H
    #define DATACOMMMANAGER_H
    
    #include <QObject>
    
    #include "datacommserial.h"
    
    class IResponseValidate_F1 : public IResponseValidate
    {
    public:
        virtual bool validate(const QByteArray& response)
        {
            bool bValid = false;
            return bValid;
        }
    };
    
    class DataCommTest : public QObject
    {
        Q_OBJECT
    public:
        explicit DataCommTest(QObject *parent = 0);
    
        void test();
    
        void test_serial0();
    
        void test_serial1();
    
        void test_serial2();
    
        void test_serial3();
    
        void test_serial4();
    
    signals:
    
    public slots:
    };
    
    #endif // DATACOMMMANAGER_H
    #include "datacommmanager.h"
    #include <QDateTime>
    
    DataCommTest::DataCommTest(QObject *parent) : QObject(parent)
    {
    
    }
    
    void DataCommTest::test_serial0()
    {
        DataCommSerial* pComm = new DataCommSerial();
        if(pComm)
        {
            pComm->init(tagSerialPortInfo("com1", 9600));
    
            pComm->send_time_to_live(500, 3000);
    
            pComm->start();
        }
    }
    
    void DataCommTest::test_serial1()
    {
        DataCommSerial* pComm = new DataCommSerial();
        if(pComm)
        {
            pComm->init(tagSerialPortInfo("com1", 9600));
            QList<QByteArray> datas;
            for(int i=0;i<10;i++)
            {
                datas << QDateTime::currentDateTime().toString("yyyyMMddHHmmss--").toLocal8Bit();
            }
            pComm->sendRequest_only(datas, 3000);
            pComm->start();
        }
    }
    
    void DataCommTest::test_serial2()
    {
        DataCommSerial* pComm = new DataCommSerial();
        if(pComm)
        {
            pComm->init(tagSerialPortInfo("com1", 9600));
            QList<QByteArray> datas;
            for(int i=0;i<10;i++)
            {
                datas << QDateTime::currentDateTime().toString("yyyyMMddHHmmss--").toLocal8Bit();
            }
            pComm->sendRequest_and_recvResponse(datas, 3000);
            pComm->start();
        }
    }
    
    void DataCommTest::test_serial3()
    {
        DataCommSerial* pComm = new DataCommSerial();
        if(pComm)
        {
            pComm->init(tagSerialPortInfo("com1", 9600));
            QList<QByteArray> datas;
            for(int i=0;i<10;i++)
            {
                datas << QDateTime::currentDateTime().toString("yyyyMMddHHmmss--").toLocal8Bit();
            }
    
            IResponseValidate* pF1 = new IResponseValidate_F1();
            pComm->sendRequest_and_checkResponse(datas, 3000, pF1);
            pComm->start();
        }
    }
    
    void DataCommTest::test_serial4()
    {
        DataCommSerial* pComm = new DataCommSerial();
        if(pComm)
        {
            pComm->init(tagSerialPortInfo("com1", 9600));
    
            pComm->recvResponse_only();
            pComm->start();
        }
    }
    
    void DataCommTest::test()
    {
        test_serial0();
    //    test_serial1();
    //    test_serial2();
    //    test_serial3();
    //    test_serial4();
    }
  • 相关阅读:
    c# 数组自定义排序
    我的第一个npm包:wechat-menu-editor 基于Vue的微信自定义菜单编辑器
    vue-element-admin左侧目录的三级展示
    vue的input框输入不了
    常用IDE(开发工具)
    DOM – 大杂烩
    Glob 语法
    Tailwind CSS – 学习笔记
    Google Ads – 大杂烩
    Webpack 学习笔记
  • 原文地址:https://www.cnblogs.com/jobgeo/p/6903424.html
Copyright © 2020-2023  润新知