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!
-
@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
-
@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.
-
@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!
-
-
If you remove the QThread::msleep(10000); call, you'll get the 2nd package much much faster.
-
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:
-
If you remove the QThread::msleep(10000); call, you'll get the 2nd package much much faster.
-
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.
-