QSerialPort bytesAvailable() and read() delayed, QextSerialPort works
-
Hey guys,
I communicate with a device using a simple protocol and was using QextSerialDevice. The protocol requires to send some data and then process the answer. The messages are quite small (a few bytes).
I send the message to the device and then try to receive the answer (no signal / slot stuff).It seems that QSerialPort::bytesAvailable() does not immediately report when bytes where received. Even after some bytes are received, bytesAvailable() still reports 0 and read() would not return any data. When more data have been received, bytesAvailable() suddenly reports all of them and read() would return (appaerently) all data. Naturally, this behaviour kills my use case.
I switch back to QextSerialPort for now but want to make people aware of this.
The system runs under Windows (32bit min-gw) and I am using Qt 5.3.1.
Is this a known / wanted behaviour? Does anyone know a fix?
Cheers,
Brembo -
Hey,
Just for clarification: I am facing with the similar problem on Linux with QSerialPort shipped with Qt 5.3.1. -
Hello,
Have you tried the simple project ("terminal") in Qt5?
In Qt 5.3.1 we have ready serial port, I tried with Android, Windows XP, 7, 8 correctly.PS
With Android I have done a workarround. -
I do not know why are you come up with the terminal example, because it is clearly using the event driven approach.
There is a message here from one of the developers of the QSerialPort mentioning the root cause of the problems:
https://www.mail-archive.com/interest@qt-project.org/msg08712.htmlBut there is not any word in the documentation about that the read, write, bytesAvailabe methods working differently than what a developer should expect from a QIODevice...
Even the example code in the documentation is incorrect: the waitforReadyRead cannot be called without argument.
@int numRead = 0, numReadTotal = 0;
char buffer[50];forever {
numRead = serial.read(buffer, 50);// Do whatever with the array numReadTotal += numRead; if (numRead == 0 && !serial.waitForReadyRead()) break;
}@
-
Already posted the same issue here: http://qt-project.org/forums/viewthread/44873/
I also switched back to QextSerialPort. -
Hello,
I use QSerialport but I prefer event driver because if you use waitForReadyRead() the gui is blocked.
Have you checked the project terminal?
http://qt-project.org/doc/qt-5/qtserialport-terminal-example.html
This is very important because when bytes are on buffer you receive a signal
connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));void MainWindow::readData()
{
QByteArray data = serial->readAll();
console->putData(data);
} -
my solution:
call QCoreApplication::processEvents(); after write() then bytesAvailable() will be updated -
[quote author="mr_wallyit" date="1410691263"]Hello,
Have you tried the simple project ("terminal") in Qt5?
In Qt 5.3.1 we have ready serial port, I tried with Android, Windows XP, 7, 8 correctly.PS
With Android I have done a workarround.[/quote]Hello mr_wallyit
You said that you were able to use the Serial port with android in Qt5, could you please share with me, how this was done? I would appreciate your response. Thank you in advance. -
[quote author="mr_wallyit" date="1410691263"]Hello,
Have you tried the simple project ("terminal") in Qt5?
In Qt 5.3.1 we have ready serial port, I tried with Android, Windows XP, 7, 8 correctly.PS
With Android I have done a workarround.[/quote]Hello mr_wallyit
You said that you were able to use the Serial port with android in Qt5, could you please share with me, how this was done? I would appreciate your response. Thank you in advance. -
Hello,
First, serial Port on Android works if the Kernel is builded with this module.Second,file System of Android is not standard,there are not standard folders for the
serial port, so I changed the driver with a few line of code.I changed the method serialPortLockFilePath in the fileqserialport_unix_p.cpp
@
QString serialPortLockFilePath(const QString &portName)
{qDebug() << __LINE__ << __FILE__; static const QStringList lockDirectoryPaths = QStringList()
//#ifdef Q_OS_ANDROID
#ifdef ANDROID<< QStringLiteral("/sdcard/data/lock") << QStringLiteral("/sdcard/data/locks") << QStringLiteral("/sdcard/data/spool/locks") << QStringLiteral("/sdcard/data/spool/uucp") << QStringLiteral("/sdcard/data/tmp") << QStringLiteral("/data/local/tmp"); qDebug() << __LINE__ << __FILE__;
#else
<< QStringLiteral("/var/lock") << QStringLiteral("/etc/locks") << QStringLiteral("/var/spool/locks") << QStringLiteral("/var/spool/uucp") << QStringLiteral("/tmp"); qDebug() << __LINE__ << __FILE__;
#endif
@
Third,
You need to create these directories:
<< QStringLiteral("/sdcard/data/lock") << QStringLiteral("/sdcard/data/locks") << QStringLiteral("/sdcard/data/spool/locks") << QStringLiteral("/sdcard/data/spool/uucp") << QStringLiteral("/sdcard/data/tmp")
-
Hello,
First, serial Port on Android works if the Kernel is builded with this module.Second,file System of Android is not standard,there are not standard folders for the
serial port, so I changed the driver with a few line of code.I changed the method serialPortLockFilePath in the fileqserialport_unix_p.cpp
@
QString serialPortLockFilePath(const QString &portName)
{qDebug() << __LINE__ << __FILE__; static const QStringList lockDirectoryPaths = QStringList()
//#ifdef Q_OS_ANDROID
#ifdef ANDROID<< QStringLiteral("/sdcard/data/lock") << QStringLiteral("/sdcard/data/locks") << QStringLiteral("/sdcard/data/spool/locks") << QStringLiteral("/sdcard/data/spool/uucp") << QStringLiteral("/sdcard/data/tmp") << QStringLiteral("/data/local/tmp"); qDebug() << __LINE__ << __FILE__;
#else
<< QStringLiteral("/var/lock") << QStringLiteral("/etc/locks") << QStringLiteral("/var/spool/locks") << QStringLiteral("/var/spool/uucp") << QStringLiteral("/tmp"); qDebug() << __LINE__ << __FILE__;
#endif
@
Third,
You need to create these directories:
<< QStringLiteral("/sdcard/data/lock") << QStringLiteral("/sdcard/data/locks") << QStringLiteral("/sdcard/data/spool/locks") << QStringLiteral("/sdcard/data/spool/uucp") << QStringLiteral("/sdcard/data/tmp")
-
Sorry I have deleted a duplicate message
-
Sorry I have deleted a duplicate message
-
Hello Mr_Wallyit
Thank you for your reply.
My target is android. Is it the same with Android as well?Thank you in advance.
-
Hello Mr_Wallyit
Thank you for your reply.
My target is android. Is it the same with Android as well?Thank you in advance.
-
Hello,
yes of course, I use Point of sale Industrial with Android, with workarround we can use serial port.
Best Regards
-
Hello,
yes of course, I use Point of sale Industrial with Android, with workarround we can use serial port.
Best Regards
-
Hi Mr_Wallyit,
Thanks for sharing the details.
I have an android device which has serial port attached to it. The manufacturer has a sample application with it which uses the serial port. The port name is "/dev/ttyS6".
As you mentioned I tried to create folder in my device. My device file explorer shows files structure as "/mnt/sdcard". So I created folders as below:
"/mnt/sdcard/data/lock"
"/mnt/sdcard/data/locks"
"/mnt/sdcard/data/spool/locks"
"/mnt/sdcard/data/spool/uucp"
"/mnt/sdcard/data/tmp"But, the folder "/mnt/data/local/tmp" is unable to create as my file explorer doesn't allow to create folder.
I kept my code as @QString serialPortLockFilePath(const QString &portName)
{
static const QStringList lockDirectoryPaths = QStringList()#ifdef Q_OS_ANDROID
<< QStringLiteral("/mnt/sdcard/data/lock")
<< QStringLiteral("/mnt/sdcard/data/locks")
<< QStringLiteral("/mnt/sdcard/data/spool/locks")
<< QStringLiteral("/mnt/sdcard/data/spool/uucp")
<< QStringLiteral("/mnt/sdcard/data/tmp");
#else
<< QStringLiteral("/var/lock")
<< QStringLiteral("/etc/locks")
<< QStringLiteral("/var/spool/locks")
<< QStringLiteral("/var/spool/uucp")
<< QStringLiteral("/tmp");
#endif@And I have a second device whose files structure as "/sdcard". So I created folders as below:
"/sdcard/data/lock"
"/sdcard/data/locks"
"/sdcard/data/spool/locks"
"/sdcard/data/spool/uucp"
"/sdcard/data/tmp"But, the folder "/data/local/tmp" is unable to create as my file explorer crashes on creating folder "/data/locaal" (need to retry with different file explorer application).
@QString serialPortLockFilePath(const QString &portName)
{
static const QStringList lockDirectoryPaths = QStringList()#ifdef Q_OS_ANDROID
<< QStringLiteral("/sdcard/data/lock")
<< QStringLiteral("/sdcard/data/locks")
<< QStringLiteral("/sdcard/data/spool/locks")
<< QStringLiteral("/sdcard/data/spool/uucp")
<< QStringLiteral("/sdcard/data/tmp");
#else
<< QStringLiteral("/var/lock")
<< QStringLiteral("/etc/locks")
<< QStringLiteral("/var/spool/locks")
<< QStringLiteral("/var/spool/uucp")
<< QStringLiteral("/tmp");
#endif@and created a sample application which tries to access the serial port. I set the port name as @setPortName("/dev/ttyS6");@
But when running the application I get the error "Permission denied".Could you help me to figure out where I am going wrong.
Thanks in advance.
-
Hi Mr_Wallyit,
Thanks for sharing the details.
I have an android device which has serial port attached to it. The manufacturer has a sample application with it which uses the serial port. The port name is "/dev/ttyS6".
As you mentioned I tried to create folder in my device. My device file explorer shows files structure as "/mnt/sdcard". So I created folders as below:
"/mnt/sdcard/data/lock"
"/mnt/sdcard/data/locks"
"/mnt/sdcard/data/spool/locks"
"/mnt/sdcard/data/spool/uucp"
"/mnt/sdcard/data/tmp"But, the folder "/mnt/data/local/tmp" is unable to create as my file explorer doesn't allow to create folder.
I kept my code as @QString serialPortLockFilePath(const QString &portName)
{
static const QStringList lockDirectoryPaths = QStringList()#ifdef Q_OS_ANDROID
<< QStringLiteral("/mnt/sdcard/data/lock")
<< QStringLiteral("/mnt/sdcard/data/locks")
<< QStringLiteral("/mnt/sdcard/data/spool/locks")
<< QStringLiteral("/mnt/sdcard/data/spool/uucp")
<< QStringLiteral("/mnt/sdcard/data/tmp");
#else
<< QStringLiteral("/var/lock")
<< QStringLiteral("/etc/locks")
<< QStringLiteral("/var/spool/locks")
<< QStringLiteral("/var/spool/uucp")
<< QStringLiteral("/tmp");
#endif@And I have a second device whose files structure as "/sdcard". So I created folders as below:
"/sdcard/data/lock"
"/sdcard/data/locks"
"/sdcard/data/spool/locks"
"/sdcard/data/spool/uucp"
"/sdcard/data/tmp"But, the folder "/data/local/tmp" is unable to create as my file explorer crashes on creating folder "/data/locaal" (need to retry with different file explorer application).
@QString serialPortLockFilePath(const QString &portName)
{
static const QStringList lockDirectoryPaths = QStringList()#ifdef Q_OS_ANDROID
<< QStringLiteral("/sdcard/data/lock")
<< QStringLiteral("/sdcard/data/locks")
<< QStringLiteral("/sdcard/data/spool/locks")
<< QStringLiteral("/sdcard/data/spool/uucp")
<< QStringLiteral("/sdcard/data/tmp");
#else
<< QStringLiteral("/var/lock")
<< QStringLiteral("/etc/locks")
<< QStringLiteral("/var/spool/locks")
<< QStringLiteral("/var/spool/uucp")
<< QStringLiteral("/tmp");
#endif@and created a sample application which tries to access the serial port. I set the port name as @setPortName("/dev/ttyS6");@
But when running the application I get the error "Permission denied".Could you help me to figure out where I am going wrong.
Thanks in advance.
-
Hello,
this is my source code, I think who is wrong “/mnt/sdcard/data/lock”.
@
bool s = true; QStringList pathList;
#ifdef ANDROID
pathList << "/sdcard/data";
pathList << "/sdcard/data/lock";
pathList << "/sdcard/data/locks";
pathList << "/sdcard/data/spool";
pathList << "/sdcard/data/spool/locks";
pathList << "/sdcard/data/spool/uucp";
pathList << "/sdcard/data/tmp";
pathList << "/sdcard/data/local";
pathList << "/sdcard/data/local/tmp";
#endifQDir d; foreach (const QString s, pathList) { d.setPath(s); if (!d.exists()){ if(d.mkpath(d.absolutePath())) qCCritical() << "error create directory " << d.absolutePath(); } }
@