Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Terminal Example for QSerialPort doesn't work correctly



  • Hello everyone!

    I still trying to use QSerialPort for reading data from some device. Now I think, that QSerialPort has really many bugs. But, maybe, developers don't know about it, so I am writing here.

    I am trying to get data from some device with Terminal Example for QSerialPort: if I send somy byte, device will send me back some set of bytes. Device works normally.

    In Terminal Example I connect to port with needed options (default) and then press some keys in console, but no any data.

    When I write key, there will be executed next method:

    void MainWindow::writeData(const QByteArray &data)
    {
        qDebug() << data;
        m_serial->write(data);
        qDebug() << "WRITTEN" << endl;
    }
    

    and I really get first time next correct messages:

    "1"
    WRITTEN 
    

    Then I must to get readyRead signal, when data will be ready:

    connect(m_serial, &QSerialPort::readyRead, this, &MainWindow::readData);
    
    void MainWindow::readData()
    {
        qDebug("Reading");
        const QByteArray data = m_serial->readAll();
        m_console->putData(data);
    }
    

    but always no data (no Reading message), i.e. no readyRead signals:

    "1"
    WRITTEN 
    
    "1"
    WRITTEN 
    
    "1"
    WRITTEN 
    
    "1"
    WRITTEN 
    
    "1"
    WRITTEN 
    
    "1"
    WRITTEN 
    

    Ok, example doesn't work, but I tried to fix it. I added to writeData() method waitForBytesWritten() function:

    void MainWindow::writeData(const QByteArray &data)
    {
        qDebug() << data;
        m_serial->write(data);
        qDebug() << "WRITTEN" << endl;
    
        if (m_serial->waitForBytesWritten(30000))
        {
            qDebug() << "WRITTEN REALLY" << endl;
        }
    }
    

    and I begin to get data from putdata() method, but only previous data with new message:

    void Console::putData(const QByteArray &data)
    {
        insertPlainText(data);
    
        for (int item : data)
        {
            QString str = QString("%1").arg(item, 0, 16);
            qDebug() << str;
        }
    
        QScrollBar *bar = verticalScrollBar();
        bar->setValue(bar->maximum());
    }
    
    "1"
    WRITTEN 
    
    WRITTEN REALLY 
    
    "2"
    WRITTEN 
    
    Reading
    "31"
    "ffffffffffffffe0"
    "ffffffffffffffc0"
    "ffffffffffffffbb"
    "ffffffffffffff87"
    WRITTEN REALLY 
    
    "2"
    WRITTEN 
    
    Reading
    "32"
    "ffffffffffffffe0"
    "ffffffffffffffc0"
    "ffffffffffffffbb"
    "ffffffffffffff87"
    WRITTEN REALLY
    

    so, for first message "1" I got nothing, because no previos data, and for next message "2" I got data for message "1" (after Reading message "31", although must be "1", by the way) before waitForBytesWritten().

    It works really strangely, incorrectly. Maybe, I understand something badly.

    I already don't know, how to get data correctly, like every message -> correct data.

    Hope for your help!



  • Hi @oBOXPOH

    I don't think that QSerialPort is buggy, I think that your using it wrong:

    AFAIK data comes asynchronously from QSerialPort, so you should consider using QSerialPort::waitForReadyRead :

    for example you should write something like that inside your readData() function:

    void MainWindow::readData()
    {
        qDebug("Reading");
        while (m_serial->waitForReadyRead()
       {
         ....
        const QByteArray data = m_serial->readAll();
         ...
       }
    ....
    }
    

    I hope that this can help you,

    Thank you and best regards!


  • Moderators

    @oBOXPOH
    It's already reported and fixed:

    https://bugreports.qt.io/browse/QTBUG-78086

    Qt versions 5.12.6 and 5.13.2 are working normally


  • Lifetime Qt Champion

    @mostefa and @oBOXPOH: Please don't use waitForReady... if you don't know what you are doing. In 99% of case you use it wrong.

    Using the correct signals is the way to go.

    Regards



  • @J-Hilk said in Terminal Example for QSerialPort doesn't work correctly:

    @oBOXPOH
    It's already reported and fixed:

    https://bugreports.qt.io/browse/QTBUG-78086

    Qt versions 5.12.6 and 5.13.2 are working normally

    Yes, thank you very much! Now Terminal Example works correctly on 5.13.2 Qt version. I had 5.13.1 or 5.12.9 versions before.


  • Lifetime Qt Champion

    @oBOXPOH So please mark this topic as SOLVED too. Thanks!



  • @aha_1980 said in Terminal Example for QSerialPort doesn't work correctly:

    @oBOXPOH So please mark this topic as SOLVED too. Thanks!

    By the way, maybe, I found another strange thing. Also in Terminal Example for QSerialPort.

        connect(m_serial, &QSerialPort::readyRead, this, &MainWindow::readData);
        connect(m_console, &Console::getData, this, &MainWindow::writeData);
    
    //! [6]
    void MainWindow::writeData(const QByteArray &data)
    {
        qDebug("ReadyWrite");
        m_serial->write(data);
        qDebug("EndOfReadyWrite");
    }
    //! [6]
    
    //! [7]
    void MainWindow::readData()
    {
        qDebug("ReadyRead");
        QThread::msleep(10000);
        const QByteArray data = m_serial->readAll();
        qDebug() << QString::number(data.count()) << endl;
        m_console->putData(data);
        qDebug("EndOfReadyRead");
    }
    //! [7]
    

    When I press a key ('1'), I enter into readData() method 2 times:

    ReadyWrite // Before write() method
    EndOfReadyWrite // After write() method
    ReadyRead // Before readAll() method
    "3" // After 10 seconds I get only 3 bytes
    
    EndOfReadyRead // And of readData() method
    ReadyRead // Again readyRead() signal
    "2" // After 10 seconds I get 2 last bytes
    
    EndOfReadyRead // End of readData() method again
    

    The question is how do I need to get all data with 1 call to readData? Just if I use even reading in another thread, I get also 2 calls to readyRead() signal.

    Thank you in advance!


  • Moderators

    1. If you remove the QThread::msleep(10000); call, you'll get the 2nd package much much faster.

    2. That is normal behavior, you get noticed each event loop cycle, if new data arrived at the Serial port. -> getting partial data is normal and expected.
      It is your task as a developer to collect and store the data and decide when the answer is complete.



  • @J-Hilk said in Terminal Example for QSerialPort doesn't work correctly:

    1. If you remove the QThread::msleep(10000); call, you'll get the 2nd package much much faster.

    2. That is normal behavior, you get noticed each event loop cycle, if new data arrived at the Serial port. -> getting partial data is normal and expected.
      It is your task as a developer to collect and store the data and decide when the answer is complete.

    Thank you very much for quich answer! QThread::msleep() I used only to check how readyRead() signal works.


Log in to reply