Analog QSerialPort::waitForReadyRead()
-
I need to make a request and get a response from the card through the port. I do not want to wait forever for an answer, so I need to control the timeout. For this, the method
QSerialPort::waitForReadyRead()
is ideal, but on the Windows platform it has problems. Are there any analogues or alternative solutions? Tried using a timer, but the port was silent.QByteArray ComPort::requestResponse(const QByteArray &data) { mutex->lock(); qDebug() << "-------------------------"; if(!serial->isOpen()) open(); int attempts = 1; QElapsedTimer waitTimer; readBuf.clear(); while (attempts <= 3) { if (serial->isWritable()) { serial->write(data); waitTimer.restart(); while (waitTimer.elapsed() < 333){ ms_delay(5); readBuf += serial->readAll(); if (readBuf.size() == 4){ close(); mutex->unlock(); return readBuf; } } readBuf.clear(); qDebug() << "Timeout..."; close(); open(); attempts++; } else { qDebug() << "Port is not written"; close(); mutex->unlock(); return 0; } } close(); mutex->unlock(); return 0; }
-
Hi,
Are you sure the port is opening properly ?
What if you use Qt's asynchronous capabilities for the communication ?
-
-
@SGaist
I think that it is correctly opened, because if I changewhile (waitTimer.elapsed() < 333){ //reading }
for it,
while (serial->waitForReadyRead(300)) { //(wait 300ms). Here, randomly breaks down //reading }
everything works correctly.
The asynchronous method is not suitable for two reasons:- I have to receive a response to a specific request, so I need to work synchronously
- I must be sure that the board has responded and only then proceed to the next actions
-
@aha_1980
In these examples (Blocking Master Example, Blocking Slave Example), the method works in other threads (maybe I did not understand the remark).
In short, it should work like thisdevice1.requestResponse(requestPackage) //do action 1 device2.requestResponse(requestPackage) //do action 2
Permission to proceed to the following actions only when the board has responded to my request. At the same time, if there is a timeout, I need to resend the request, because maybe the board did not receive a request and wait for a reply is useless
-
@maratk1n said in Analog QSerialPort::waitForReadyRead():
I have to receive a response to a specific request, so I need to work synchronously
I must be sure that the board has responded and only then proceed to the next actionsI don't see why it would not work with asynchronous approach. You send a request and then "wait" until readyRead signal is fired. If you get this signal then you know that the board has responded and it should be the response for the request you sent before.
If you really want to use blocking calls (waitFor...) then you should move that part to a thread to not to block your main thread. -
Hi @maratk1n,
And you should really think if you need to keep a mutex for 300 milliseconds. That effectively makes multithreading impossible.
But back to your topic: Is your code running in a thread? If the answer is no, then I repeat: it will not work, because with your
ms_delay
andwaitForReadyRead
you're blocking Qt's event loop.I have written a lot of programs working with QtSerialPort on Windows, and never had problems, neither with non-blocking nor with blocking code. You just have to take care how you use it.