Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Chinese
  4. 串口如何稳定接收数据(转帖)
Forum Updated to NodeBB v4.3 + New Features

串口如何稳定接收数据(转帖)

Scheduled Pinned Locked Moved Chinese
30 Posts 4 Posters 24.4k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    ohno
    wrote on last edited by
    #1

    http://www.qtcn.org/bbs/read-htm-tid-57104.html大家好我在用qt做串口调试工具时遇到类似的问题:卡的元凶找到了ui->textEdit->append(str);这句话,每次要刷新一次显示。现在该如何处理?这个没法放在别的线程处理吧.
    本人的想法:
    1.其实跟这个帖子的很类似,不一样的地方是用insert方式,因为append是自带换行的,跟我的想法有出入。
    2.相信接触过串口调试助手的对AccessPort都不陌生,其实就是想做一个类似的串口接收工具,发现qt做起来很难,许多网友一直在怀疑我要做到工具的有效性(1ms帧与帧间隔,不停的发送数据),其实工具做出来肯定是有用的,就看个人需不需要。AccessPort的优越性就是,发送过来的数据不管多快都能显示出来,并且不影响界面的移动,界面其他按钮的操作,都非常的流畅。但是qt做的串口调试助手如果接收1ms,大约100字节左右发送过来的数据,界面肯定卡死(不能执行任何操作),我最近在网上一直找qt版的串口调试助手,没有一个能抗住这个测试,qt自带的demo也一样。
    初步怀疑:由于数据量比较大,qt文本显示控件是全部更新导致时间长,导致主ui延缓,导致界面卡死,不能移动,不能操作界面上的任何按钮。
    确诊:经过多次询问网友,最终确认为显示控件显示数据量大,刷新缓慢导致。
    确认之前本人已经尝试过的方法如下:
    1.换qt自带有关文本控件,问题不能解决。
    2.用缓存+延时的方法,时间久照样会卡,并且实时性很差,A串口发送工具已经发送数据完毕,自己编写的串口工具还是慢慢的显示数据。
    3.线程的方法,本人一直用的就是线程,一个线程接收串口过来的数据,然后再投递给显示控件,还是不能解决问题。
    4.有网友说用qapplication::processevent,在显示槽函数中加入一对该函数,也不行,时间长(1分钟左右)照样有问题
    5.想用重绘的方法,不止从何下手.尤其是重绘文本+滚动条,由于本人是初学者。对qt 有一定的了解,但是遇到这种问题真不知道如何解决。
    6.国外论坛查找相关解决方法,在google上好像也有老外问过类似的问题。具体链接忘记,但是也没有具体的解决方法。
    希望奇能异士能帮忙解决此问题,很多人都觉得很简单,不屑一看,其实我就是想说,问题感觉不是想象中的简单,可能我是初学者的原因。学习qt一年来,觉得初学的资料不少,但是到深入的就没有啦,资料太少啦。越来越觉得没有信心学好,请网友们勿劈砖。希望得到大家的帮助。

    1 Reply Last reply
    0
    • J Offline
      J Offline
      JohnYork
      wrote on last edited by
      #2

      会不会是没有把QTextEdit的acceptRichTex属性关掉,控件老是做大量的格式渲染导致延迟了?

      1 Reply Last reply
      0
      • O Offline
        O Offline
        ohno
        wrote on last edited by
        #3

        你好按照你说的讲允许接收富文本属性关闭还是不行。我也是怀疑是格式渲染导致的,但是不知道怎么解决这个问题。谢谢。

        1 Reply Last reply
        0
        • V Offline
          V Offline
          Vincent007
          wrote on last edited by
          #4
          1. You use debug build or release build?
          2. Did you perform profiling on ui->textEdit->append(str) ?
          3. write a program that only involve ui->textEdit->append(str) to perform profiling.
          1 Reply Last reply
          0
          • O Offline
            O Offline
            ohno
            wrote on last edited by
            #5

            hi Vincent007
            1.debug build
            2.Yes,The refresh speed is very quick, not a bit dull, but I don't like with append, because append broken the original data format, especially the received data is Chinese。The original format:
            你好!
            我很认真,但是很失望。一直再等待。
            If you use the append may become the following format:
            你好!
            我很认真,
            但是很失望。
            一直再等待。
            3.I once did a test, use a non UI thread interval 1ms to control sending data, display data using insert, long time after will refresh is not over, the main UI can't move。
            4.I think QT is text controls render caused by slow。

            Thank you for your reply!

            1 Reply Last reply
            0
            • V Offline
              V Offline
              Vincent007
              wrote on last edited by
              #6

              What is release build performance?
              Did you test release build?

              1 Reply Last reply
              0
              • J Offline
                J Offline
                JohnYork
                wrote on last edited by
                #7

                append过于频繁导致控件频繁重绘,UI的事件响应循环被阻塞,程序卡死。

                试试这样做:
                加长缓存深度,使append的间隔至少20ms,还可以用定时器按固定时间间隔将缓存中的数据append入控件。一定要记得在append时使用资源互斥锁保护你正在读的数据;如果有丢数现象发生,则需要考虑使用双缓冲区执行乒乓处理来避免。

                1 Reply Last reply
                0
                • O Offline
                  O Offline
                  ohno
                  wrote on last edited by
                  #8

                  hi Vincent007
                  1.I have done a test release version using append fast.no problem。
                  2. but I don’t like to use append, because append broken the original data format, especially the received data is Chinese。The original format:
                  你好!
                  我很认真,但是很失望。一直再等待。
                  If you use the append may become the following format:
                  你好!
                  我很认真,
                  但是很失望。
                  一直再等待。
                  Thank you for your reply

                  1 Reply Last reply
                  0
                  • O Offline
                    O Offline
                    ohno
                    wrote on last edited by
                    #9

                    JohnYork
                    你好,其实append速度是很快的,我测试过,没有问题的,但是它有一个问题就是打破数据的格式(数据自动换行),比如:
                    你好!
                    我很认真,但是很失望。一直再等待。这这2句话,我很认真,但是很失望两者如果不是在同一帧接收过来的,就会变成
                    我很认真
                    但是很失望。自动换行变成2句话。
                    。
                    我的目标是做成AccessPort串口调试工具,我说的这些问题AccessPort几乎不存在。
                    等半小时我把代码上传上来。让大家看看怎么解决。
                    谢谢JohnYork你的回答。

                    1 Reply Last reply
                    0
                    • O Offline
                      O Offline
                      ohno
                      wrote on last edited by
                      #10

                      JohnYork
                      你好
                      1.其实append速度是很快的,我测试过是没有问题的。但是它有一个问题就是自动换行。
                      比如:我很认真,但是很失望。一直再等待。
                      这句话如果不是在一帧中接收过来的会变成如下格式:
                      我很认真,
                      但是很失望。
                      一直再等待。
                      我是希望做成AccessPort这个串口调试工具一样的接收功能。很厉害的这个软件,尤其是在高速接收数据上,性能很优越。
                      过半小时把代码上传上来,让你们看看,谢谢你的回答。

                      1 Reply Last reply
                      0
                      • O Offline
                        O Offline
                        ohno
                        wrote on last edited by
                        #11

                        hi Vincent007,JohnYork

                        我已经把代码上传到如下链接,同时里面有一个测试视频,qt5.3.1 mingw编译的
                        http://pan.baidu.com/s/1kTh0ifd
                        。
                        谢谢你们的讨论。

                        1 Reply Last reply
                        0
                        • O Offline
                          O Offline
                          ohno
                          wrote on last edited by
                          #12

                          hi Vincent007,JohnYork
                          你们是否看到代码?有问题吗?,有问题请留言谢谢.

                          1 Reply Last reply
                          0
                          • V Offline
                            V Offline
                            Vincent007
                            wrote on last edited by
                            #13

                            試把
                            @
                            connect(
                            &m_Portconfigview,SIGNAL(signalConfigPort(const SPortsettings *)),&m_Serialportrecevie,SLOT(slotsConfigPort(const SPortsettings *)),Qt::QueuedConnection);
                            connect(
                            &m_Portconfigview,SIGNAL(signalConfigPort(const SPortsettings *)),this,SLOT(updatetstatus(const SPortsettings *)));
                            connect(
                            &m_Serialportrecevie,SIGNAL(signalThreadToStore( const QByteArray&)),&m_Serialportcachedata,SLOT(slotsSerialportcachedata(const QByteArray&)),Qt::BlockingQueuedConnection);
                            connect(
                            &m_Serialportcachedata,SIGNAL(signalToserialportwindow(const QByteArray&)),&m_pSerialPortWindow,SLOT(slotsserialportupdateview(const QByteArray&)),Qt::BlockingQueuedConnection);
                            @
                            改成
                            @
                            connect(
                            &m_Portconfigview,SIGNAL(signalConfigPort(const SPortsettings *)),&m_Serialportrecevie,SLOT(slotsConfigPort(const SPortsettings *)));
                            connect(
                            &m_Portconfigview,SIGNAL(signalConfigPort(const SPortsettings *)),this,SLOT(updatetstatus(const SPortsettings *)));
                            connect(
                            &m_Serialportrecevie,SIGNAL(signalThreadToStore( const QByteArray&)),&m_Serialportcachedata,SLOT(slotsSerialportcachedata(const QByteArray&)));
                            connect(
                            &m_Serialportcachedata,SIGNAL(signalToserialportwindow(const QByteArray&)),&m_pSerialPortWindow,SLOT(slotsserialportupdateview(const QByteArray&)));
                            @

                            1 Reply Last reply
                            0
                            • O Offline
                              O Offline
                              ohno
                              wrote on last edited by
                              #14

                              hi Vincent007
                              我已经按照你说的进行测试,还是会卡住界面。谢谢。

                              1 Reply Last reply
                              0
                              • V Offline
                                V Offline
                                Vincent007
                                wrote on last edited by
                                #15

                                Did you test release build?

                                1 Reply Last reply
                                0
                                • O Offline
                                  O Offline
                                  ohno
                                  wrote on last edited by
                                  #16

                                  hi Vincent007

                                  1.我是用的release build。谢谢。
                                  2.我看过java c# vc++写的类似串口调试助手都没有类似问题,qt版本网上所有的串口调试助手和qt官网自带的demo都有类似的问题。是不是qt控件本身的一个bug.

                                  1 Reply Last reply
                                  0
                                  • V Offline
                                    V Offline
                                    Vincent007
                                    wrote on last edited by
                                    #17

                                    measure time consumed by slotsSerialportcachedata and slotsserialportupdateview via QElapsedTimer
                                    另外你要確保你的PC 沒有問題.你有否在另一台PC試過你的程序?
                                    @
                                    QElapsedTimer timer;
                                    timer.start();
                                    slowOperation1();
                                    qDebug() << "The slow operation took" << timer.nsecsElapsed() << "nanoseconds";
                                    @

                                    1 Reply Last reply
                                    0
                                    • O Offline
                                      O Offline
                                      ohno
                                      wrote on last edited by
                                      #18

                                      HI Vincent007
                                      前阵子忙别的去,所以今天才回复你,不好意思按照你说的用以下代码进行测试
                                      timer.start();
                                      pSerialPortQPlainTextEdit.insertPlainText(DatatFormRead);
                                      pSerialPortQPlainTextEdit.moveCursor(QTextCursor::End, QTextCursor::KeepAnchor);
                                      qDebug() << "The slow operation took" << timer.nsecsElapsed() <<"nanoseconds";
                                      下面是测试结果:
                                      The slow operation took 1017500 nanoseconds
                                      The slow operation took 1018310 nanoseconds
                                      The slow operation took 1421502 nanoseconds
                                      The slow operation took 1186476 nanoseconds

                                      The slow operation took 10685984 nanoseconds
                                      The slow operation took 10668154 nanoseconds
                                      The slow operation took 10564419 nanoseconds
                                      The slow operation took 10569686 nanoseconds
                                      The slow operation took 10243486 nanoseconds
                                      The slow operation took 10473245 nanoseconds
                                      The slow operation took 10746766 nanoseconds
                                      The slow operation took 10772700 nanoseconds
                                      The slow operation took 10583059 nanoseconds
                                      The slow operation took 11221681 nanoseconds
                                      The slow operation took 10795798 nanoseconds
                                      The slow operation took 16827051 nanoseconds

                                      The slow operation took 222369451 nanoseconds
                                      The slow operation took 205003460 nanoseconds
                                      The slow operation took 222164411 nanoseconds
                                      The slow operation took 204823949 nanoseconds
                                      The slow operation took 209414655 nanoseconds
                                      The slow operation took 186572559 nanoseconds
                                      The slow operation took 209589304 nanoseconds
                                      The slow operation took 214433676 nanoseconds
                                      The slow operation took 219041401 nanoseconds
                                      说明qt的窗口刷新确实有问题,请指教谢谢。

                                      1 Reply Last reply
                                      0
                                      • V Offline
                                        V Offline
                                        Vincent007
                                        wrote on last edited by
                                        #19

                                        @
                                        #include "mainwindow.h"
                                        #include "ui_mainwindow.h"

                                        MainWindow::MainWindow(QWidget *parent) :
                                        QMainWindow(parent),
                                        ui(new Ui::MainWindow)
                                        {
                                        ui->setupUi(this);
                                        _timer.setInterval(10);

                                        for(int i = 0; i<1024;i++) {
                                            message += "1";
                                        }
                                        connect(&_timer,&QTimer::timeout,this,&MainWindow::updateText);
                                        _timer.start();
                                        

                                        }

                                        MainWindow::~MainWindow()
                                        {
                                        delete ui;
                                        }

                                        void MainWindow::updateText()
                                        {
                                        ui->textEdit->append(message);
                                        }
                                        @
                                        I did a simple application and test it. It works fine.
                                        You can try it and adjust parameters.

                                        1 Reply Last reply
                                        0
                                        • O Offline
                                          O Offline
                                          ohno
                                          wrote on last edited by
                                          #20

                                          HI Vincent007
                                          我以前测试过调用append是没有问题的,建议你改成ui->textEdit->insertPlainText(message);试试。
                                          因为我不能使用append,改成append会有这么一个问题
                                          一句完整的话分2次发送过来就变成2行,比如:
                                          “你好,谢谢你回答我的问题”。
                                          分两次之后,有可能变成
                                          “你好,”
                                          “谢谢你回答我的问题”

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved