Results 1 to 6 of 6

Thread: QSerialPort - speed and performance

  1. #1
    Join Date
    Apr 2015
    Posts
    27
    Thanks
    5
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Post QSerialPort - speed and performance

    Hello guys.
    First time here, should not be the last, since I should work with Qt for a few times

    I developed an app to obtain data from a serial port.
    The current baudrate is 115200, and I wanted to improve it even more.

    The thing is, that even at this rate it is really slow.
    The buffer keeps storing data and increasing all the time, by using the function QSerialPort::readAll

    I don't know if I am handling the data correctly, but here's a hint of my code:

    This is the slot for the readyRead() signal from QSerialPort
    void ADCStream::readData()
    {
    ADCData += ADCPort->readAll();

    int dataBegin;
    int dataEnd;

    dataBegin = ADCData.indexOf('A',0);
    dataEnd = ADCData.indexOf('Z',dataBegin);
    if((dataBegin != -1) && (dataEnd != -1))
    {
    QByteArray tempData = ADCData.mid(dataBegin+1,2);
    quint16 number=0;

    number = (tempData.at(0) & 0x00FF)<<8;
    number |= tempData.at(1) & 0x00FF;

    emit dataReady(number);
    ADCData.remove(0,dataEnd+1);//get next data
    }
    }
    this is the constructor of the main dialog
    ui->setupUi(this);
    myStream = new ADCStream();//customized class, with a QSerialPort instance
    streamThread = new QThread(this);
    myStream->moveToThread(streamThread);

    streamThread->setPriority();
    streamThread->start();
    myStream->open();

    log = new QFile("Log",this);
    if(!log->open(QIODevice::Append))
    {
    QMessageBox::warning(this,"Log File","Couldn't open file");
    }

    connect(myStream,SIGNAL(dataReady(quint16)),this,S LOT(showData(quint16)),Qt::QueuedConnection);
    connect(myStream->ADCPort,SIGNAL(readyRead()),myStream,SLOT(readDat a()));
    The slot showData simply displays the data in a QTextBrowser with this:
    ui->textLogger->insertPlainText(QString(" %1\n").arg(whatever));

    Can you tell me how can I improve this data handling from the serialPort?
    I'm reading from a sensor, and when I change the sensor, it takes a REALLY long time to update in the GUI

    Thanks in advance

  2. #2
    Join Date
    Apr 2015
    Posts
    27
    Thanks
    5
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QSerialPort - speed and performance

    I found (kind of) a solution.

    If I put a timer generating an update and sendig a signal every milisecond(! the minimum of QTimer) I can actually read from the serial port every milisecond. Which is what I wanted.
    Still, If I want to improve the sampling rate I cannot do that...

    Any ideas?

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QSerialPort - speed and performance

    Since you are using a thread, make sure each object belongs to the thread you think it belongs.
    e.g. especially make sure that myStream->ADCPort is a child of myStream and is thus owned by the thread.

    In general my recommendation would be to make it work without a thread first.

    Cheers,
    _

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QSerialPort - speed and performance

    You don't want to sample faster: you already read all data when it becomes available. You do want to process all the available received data each time more data is received.

    Your code currently processes a single 16 bit value each time more data is received, leaving any other data for later. For example, if you receive data in 16 byte blocks (a not uncommon UART buffer size), you will process four bytes (AxxZ) and leave 12 bytes in the buffer. The next 16 byte block arrives and you process the second value from the first block and carry forward 24 bytes, and so on. Processing one sample per packet effectively reduces your sample processing rate.

    The readyRead() handler should iterate over the entire buffer processing samples until less than a full sample remains.

    You should not need threads to keep up with a serial port and remain responsive.

    BTW: Your code also has a problem if either byte following the 'A' is 0x5A ('Z').

  5. The following user says thank you to ChrisW67 for this useful post:

    Wer_Bn (18th August 2015)

  6. #5
    Join Date
    Apr 2015
    Posts
    27
    Thanks
    5
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QSerialPort - speed and performance

    Thank you very much for the idea. And the warning !
    I just though that readyRead would constantly generate an interrupt, as long as it had data waiting to be read.

    If something goes wrong, I'll shout
    Last edited by Wer_Bn; 30th April 2015 at 14:21.

  7. #6
    Join Date
    Apr 2015
    Posts
    27
    Thanks
    5
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QSerialPort - speed and performance

    What about this?

    Is it nice? Do you see any flaws?
    In terms of performance seems fine. And the buffer is not constantly increasing.
    I use no threads or timers now

    void ADCStream::readData()
    {
    int dataBegin;
    int dataEnd;

    ADCData += ADCPort->readAll();

    while(ADCData.size()>=4)
    {
    dataBegin = ADCData.indexOf('A',0);
    dataEnd = dataBegin + 3;

    if((dataBegin != -1) && (dataEnd != -1) && (ADCData.size() >= dataEnd+1) && (ADCData.at(dataEnd) == 'Z'))
    {
    QByteArray tempData = ADCData.mid(dataBegin+1,2);
    quint16 number=0;

    samplesReceived++;

    number = (tempData.at(0) & 0x00FF)<<8;
    number |= tempData.at(1) & 0x00FF;

    hardMedia += (double)((double)number*((double)1/SAMPLES_END));

    if(samplesReceived == SAMPLES_END)
    {
    emit dataReady((quint16)hardMedia);
    samplesReceived = 0;
    hardMedia = 0;
    }
    ADCData.remove(0,dataEnd+1);//get next data
    }
    }
    }

Similar Threads

  1. QSerialPort read delay
    By M4chin3 in forum Qt Programming
    Replies: 14
    Last Post: 24th January 2014, 18:06
  2. Qserialport issue in QT4
    By coss_cat in forum Qt Programming
    Replies: 3
    Last Post: 11th December 2013, 18:11
  3. QSerialport in multithread
    By snow_starzz in forum Newbie
    Replies: 3
    Last Post: 3rd December 2013, 10:18
  4. Qt5 cmake and QSerialPort
    By Chris.Burner in forum Newbie
    Replies: 1
    Last Post: 21st April 2013, 16:13
  5. How to speed up the Qt GUI apps launch speed?
    By wshn13 in forum Qt Programming
    Replies: 3
    Last Post: 14th March 2012, 08:37

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.