QT 高效串口读取、显示与存储软件开发之二:串口高效读取(线程讨论)hdntCom库(1)

QT 高效串口读取、显示与存储软件开发之二:串口高效读取(线程讨论)

串口数据操作

搜了大量的资料,也看了QT的文档,串口读取有以下几种方案,包括:connect直接连接、线程中直接读取(Run)、利用movetothread、在线程中开启串口(打开串口)。所有的串口操作均封装在动态连接库中,名为:hdntCom,对外输入输出接口如下:

 class SerialSetInfo{
public:
    QString ComName;
    QString BaudRate;
    QString DataBit;
    QString StopBit;
    QString Parity;
    QString Protocol;
};

class HDNTCOMSHARED_EXPORT hdntCom:public QThread
{
   Q_OBJECT
public:
   hdntCom(QObject *parent);
   ~hdntCom();

   int Init(SerialSetInfo *SerialSetParm);  //Init the serial port
   int Open();  //open
   int Close();

   int Write(QByteArray *Dat);
   QByteArray Read();

   bool isOpen();
   QByteArray ComData;
   uint8_t *uComData;
   uint16_t ComDataLength;

   QSerialPort * m_serial = nullptr;

   bool mThreadRun=true;

   bool OpenFlag=false;


   void setCallback(std::function<void(void)> func);
private slots:
   void ReceiveComData(void);

signals:
   void SendReceiveData(QByteArray Dat);
   void Sg_ComReady(void);

private:



   std::function<void(void)> m_func;
   uint8_t BufferNum=2;
   bool SolveFlag=true;
   QByteArray Buffer1,Buffer2;


protected:
   void run();
};

connect直接连接

利用connect命令,直接将readready与一个槽函数相连,代码如下:

connect(m_serial,SIGNAL(readyRead()),this,SLOT(ReceiveComData()));//有数据就读

该种方法,ReceiveComData函数运行在主线程中,一旦GUI负载过重,则串口卡顿明显。

线程中直接读取

将hdntCom继承于QThread,重构run函数

void hdntCom::run(){
    while(mThreadRun)
    {
         if(m_serial->isOpen()){
            if(m_serial->waitForReadyRead(-1))  //等待有数据到达,-1表示永不超时
            {
                this->usleep(1000);  //延时一会,等待数据全部到达
                ComData.clear();
                Buffer1=m_serial->readAll();
                ComData=Buffer1;
                ComDataLength=ComData.length();
                emit Sg_ComReady();
                m_func();
            }
        }else{
           this->terminate();
            mThreadRun=false;
        }
    }
}

利用movetothread

新建一个类命名为工作线程,如下

#include <QObject>
#include <QtCore/qglobal.h>
#include <functional>

class WorkThread:public QObject
{
    Q_OBJECT
public:
    WorkThread(QObject *parent);
    void setCallback(std::function<void(void)> func);

public slots:
    void Slot_RecieveDat();

signals:


private:
    std::function<void(void)> m_func;
};

使用方式如下

m_ComThread=new WorkThread(this);
Th_ComWork=new QThread;
m_ComThread->moveToThread(Th_ComWork);
Th_ComWork->start();
connect(m_serial, SIGNAL(readyRead()), m_ComThread, SLOT(Slot_RecieveDat()));

该方法,可把数据读取放到子线程中,但是经实测该方法串口总非正常卡死。
在这里插入图片描述
可以看出,多线程已经出来了,但是还是很卡,不知道什么原因。信号传的是读到的数组。

在线程中开启串口


这种方法在网上看到有人提,单个人认为纯属瞎扯。

本软件,最终会通过github开源社区共享,有意共同开发者,可留言。
目前版本软件下载地址:https://github.com/liuning19861103/HDNT-Center

持续更新中。。。。

有时间争取每天都写写,希望大家支持。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值