天天看點

多線程的序列槽通信-11 下位機STM32發送的資料格式與序列槽參數2 上位機程式3 QT程式設計QT走過的坑–多線程

多線程的序列槽通信

  • 1 下位機STM32發送的資料格式與序列槽參數
    • 1.1下位機上傳的資料格式:
    • 1.2序列槽參數
  • 2 上位機程式
    • 2.1Future:
    • ~~2.2序列槽參數同上~~
  • 3 QT程式設計
  • QT走過的坑--多線程

參考文獻:

vodka

QSerialPort多線程方法

Qt下實作多線程的序列槽通信

QT序列槽程式設計–多線程

QT 防止界面卡死(多線程式列槽使用)

序列槽接受資料不完整的解決方法

1 下位機STM32發送的資料格式與序列槽參數

1.1下位機上傳的資料格式:

  • unsigned int data [81]
  • uint=2byte ,data=162byte
  • 324
  • 其中 data[0]為時間戳-自加計數生成
  • data[1:81]為10ms内采集的8通道的資料,即data[1:8]…data[74:81]為分時采集的8通道資料。data[1:8]為第1ms,data[9:16]為第2ms采集的資料。
  • 下位機每10ms發送一次162byte資料,即1s發送16200 Byte =129600bit/s=15KB/s
  • 1byte=8bits

1.2序列槽參數

  • 波特率Baud Rate:230400 bps( bit Per Second)
  • 1ms 接受 230.4byte
  • 其他預設參數:8資料位,1停止位,無奇偶校驗位NoParity

2 上位機程式

上位機程式負責:接受資料,自定義的資料格式化Format,儲存。

将格式化後的資料繪制成波形圖

2.1Future:

  • 擷取keyboard按鍵,并在Format時增加該按鍵的内容(–主要用來采集手勢動作時自動打标簽)
  • 實時的神經網絡進行訓練,識别

2.2序列槽參數同上

3 QT程式設計

參考:vodka,QSerialPort多線程方法

前言:使用序列槽有多種方式:第一種,開閉序列槽和接收資料都在主界面線程中進行,資料量小還可以,資料量一大直接卡死;第二種,開閉序列槽和接收資料都在子線程中進行,主界面不會卡死,資料也能正常接收,但是線程中序列槽類不安全;第三種,開閉序列槽在主線程中進行,接受資料和解析資料在子線程中進行。

————————————————

版權聲明:本文為CSDN部落客「kissgoodbye2012」的原創文章,遵循 CC 4.0 BY-SA 版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/kissgoodbye2012/article/details/96348923

  • 多線程-序列槽操作類
  • MulitPlot類-多通道資料繪圖
  • 主程式UI/widget

QT走過的坑–多線程

  • 1 使用繼承QThread重寫run函數
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include<QThread>
#include<QSerialPort>
#include<QSerialPortInfo>
#include<QObject>
#include<QDebug>
class MyThread:public QThread
{
    Q_OBJECT
public:
    MyThread(QString portname);
    void run() override;
signals:
    void senddata(const QByteArray &);
public slots:
    void read_serial_data();//讀取序列槽資料
    void close_mthread_serial();//關閉
private:
     QSerialPort *m_serialport;
     QString port;
};

#endif // MYTHREAD_H
           
#include "mythread.h"

MyThread::MyThread(QString portname)

{
   m_serialport=new QSerialPort();
   port=portname;
}

void MyThread::run(){
   m_serialport->setPortName(port);
   m_serialport->open(QIODevice::ReadOnly);
   m_serialport->setBaudRate(230400);
   m_serialport->setDataBits(QSerialPort::Data8);
   m_serialport->setParity(QSerialPort::NoParity);
   m_serialport->setStopBits(QSerialPort::OneStop);
   m_serialport->setFlowControl(QSerialPort::NoFlowControl);
   m_serialport->setReadBufferSize(1024);
   connect(m_serialport,SIGNAL(readyRead()),this,SLOT(read_serial_data()));
}

void MyThread::read_serial_data()//讀取序列槽資料
{
   QByteArray buf;
   if(m_serialport->bytesAvailable()>=0){
       qDebug()<<m_serialport->bytesAvailable() << endl;
       buf=m_serialport->readAll();
       qDebug()<<buf;
       // 轉為16進制*4位數 ///162byte  81 ushort
       //data=buf;
       emit senddata(buf);
   }
}

void MyThread:: close_mthread_serial(){

   qDebug() <<"close ok"<<endl;
   m_serialport->close();//關閉子線程
}
           
  • 2 繼承QObject然後使用MoveToThread

    QObject序列槽類

日經問題

  • Q: Qt信号和槽問題,const QString &中的&是什麼意思?最近學習Qt,textChanged(const QString &)這個函數中,QString &是什麼意思,為什麼隻有一個&?
  • A:& 是引用,相當于指針,不過比較直覺,你可以修改這個傳遞進來的變量。

    但是他用const修飾了,你無法修改,傳遞引用比直接複制傳遞節省記憶體,但是其實Qt内置了記憶體管理,是以無所謂

  • Q: 線程之間怎麼傳遞資料
  • A: Qt線程間共享資料主要有兩種方式:
    • 1)使用共享記憶體。即使用一個兩個線程都能夠共享的變量(如全局變量),這樣兩個線程都能夠通路和修改該變量,進而達到共享資料的目的。
    • 2)使用singal/slot機制,把資料從一個線程傳遞到另外一個線程。
  • Q:線程的4中狀态是什麼?怎麼建立線程?
  • A: QT:開啟,暫停,恢複,退出,
  • JAVA:
  • 建立狀态(New):當線程對象對建立後,即進入了建立狀态,如:Thread t = new MyThread();

    就緒狀态(Runnable):當調用線程對象的start()方法(t.start();),線程即進入就緒狀态。處于就緒狀态的線程,隻是說明此線程已經做好了準備,随時等待CPU排程執行,并不是說執行了t.start()此線程立即就會執行;

  • 運作狀态(Running):當CPU開始排程處于就緒狀态的線程時,此時線程才得以真正執行,即進入到運作狀态。注:就 緒狀态是進入到運作狀态的唯一入口,也就是說,線程要想進入運作狀态執行,首先必須處于就緒狀态中;
  • 阻塞狀态(Blocked):處于運作狀态中的線程由于某種原因,暫時放棄對CPU的使用權,停止執行,此時進入阻塞狀态,直到其進入到就緒狀态,才 有機會再次被CPU調用以進入到運作狀态。根據阻塞産生的原因不同,阻塞狀态又可以分為三種:
    • 1.等待阻塞:運作狀态中的線程執行wait()方法,使本線程進入到等待阻塞狀态;
    • 2.同步阻塞 – 線程在擷取synchronized同步鎖失敗(因為鎖被其它線程所占用),它會進入同步阻塞狀态;
    • 3.其他阻塞 – 通過調用線程的sleep()或join()或發出了I/O請求時,線程會進入到阻塞狀态。當sleep()狀态逾時、join()等待線程終止或者逾時、或者I/O處理完畢時,線程重新轉入就緒狀态。
  • 死亡狀态(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命周期。
  • A:

繼續閱讀