QSerialPort
from version 5.13.1 of the Qt library does not physically output data under Windows 7 and 10.
In order to demonstrate the described problem I have prepared the following setup:
I have tested the connection between a PC with a physical serial port (COM1) and a real serial device, but for demonstration purposes I have created a simple loopback by connecting together pins 2 and 3 of the DSub connector of the PC, i.e. Tx and Rx.
The problem occurs in my own GUI applications, as well as in the official examples shipped with Qt. However, for the sake of the demonstration I wrote a very basic console app:
SerialBug.pro
QT -= gui
QT += serialport
CONFIG += console
SOURCES += \
main.cpp
main.cpp
#include <QCoreApplication>
#include <QSerialPort>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSerialPort port("COM1");
port.setBaudRate(QSerialPort::Baud4800);
port.setDataBits(QSerialPort::Data8);
port.setStopBits(QSerialPort::OneStop);
port.setParity(QSerialPort::NoParity);
port.setFlowControl(QSerialPort::NoFlowControl);
QObject::connect(&port, &QSerialPort::readyRead,
[&port](){
qDebug() << port.readAll();
});
QObject::connect(&port, &QSerialPort::bytesWritten,
[](qint64 bytes){
qDebug() << bytes;
});
QObject::connect(&port, &QSerialPort::errorOccurred,
[](QSerialPort::SerialPortError error){
qDebug() << error;
});
if (port.open(QSerialPort::ReadWrite)) {
qDebug() << port.write("Test");
}
return a.exec();
}
Compiling and running the example code with MSVC2017 and Qt 5.13.0 in release mode, the following output is produced:
QSerialPort::NoError
4
4
"Test"
The exact same code compiled in release mode with MSVC2017, but this time with Qt 5.13.1, produces the following output:
QSerialPort::NoError
4
port.write
returns 4
, meaning 4 bytes are send to the serial port, but that is not actually done. bytesWritten
is not emitted and the data is not read back.
Note: A serial monitor program is showing the written data, but the data does not reach the pins.
Is it possible to fix the code in any way in order to make it work with Qt5.13.1?
download and unpack the QtSerialPort sources. run QtCreator and open the root "qtserialport/qtserialport.pro" project file. get to "Projects->(Your Kit)->Build->Build Steps" add a new make "Build Step" and write to the "Make arguments" the install target.
We can do it with below code block. void MainWindow::readData() { bool _ok; //This code is to read all data on serial port QByteArray data = serial->readAll(); if (ui->chkGetHexadecimalValue->isChecked() == true) qDebug() << data.
Searching Qt bug tracker there seem to be multiple bugs about QSerialPort not working on Qt 5.13.1 on Windows. All of them are duplicated with QTBUG-78086 which also contains a link to Gerrit review of the fix.
From the bug description:
The signal readyRead is never emitted, even if data is sent to the serial port from a connected device. The member bytesAvailable returns 0 even if data has been sent to the serial port from a connected device.
Basically, they have tried to emit _q_notify
in qwinoverlappedionotifier.cpp
only if there's no notification pending. Unfortunatelly
That commit completely breaks the I/O on Windows.
For now you have the options to downgrade to 5.13.0, wait for Qt 5.13.2 or
Fix the Qt 5.13.1 qserialport
yourself:
QTDIR\5.13.1\Src\qtserialport\qtserialport.pro
with QtCreatorProjects
-> Manage kits
-> Desktop Qt 5.13.1 MSVC2017 64bit
src/serialport/serialport-lib/sources/qwinoverlappedionotifier.cpp
QAtomicInt pendingNotifications;
change
if (!waiting && pendingNotifications-- == 0)
emit q->_q_notify();
to
if (!waiting)
emit q->_q_notify();
change
int n = pendingNotifications.fetchAndStoreAcquire(0);
while (--n >= 0) {
if (WaitForSingleObject(hSemaphore, 0) == WAIT_OBJECT_0)
dispatchNextIoResult();
}
to
if (WaitForSingleObject(hSemaphore, 0) == WAIT_OBJECT_0)
dispatchNextIoResult();
In QtCreator go to build
-> clean all
, then run qmake
, then rebuild all
Qt5SerialPort.dll
and Qt5SerialPortd.dll
from build\bin
to QTDIR\5.13.1\msvc2017_64\bin
Your code should work now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With