QSerialPort communication
-
Hi,
I'm developing an application that controls a CameraLink camera using the virtual COM port.
I open a serial port usingserial->setPortName(comPort); serial->setBaudRate(QSerialPort::Baud9600); serial->setStopBits(QSerialPort::OneStop); serial->setParity(QSerialPort::NoParity); serial->open(QIODevice::ReadWrite);
Parameters are correct as I can establish a communication on the port with a COM-terminal using these settings.
Then I pass some commands of the following type to the device:QString comm=QString("r gwbr\r"); //red serial->write(comm.toUtf8(),comm.size()); serial->flush(); serial->waitForReadyRead(-1); QString resp=QString(serial->readAll()); resp=resp.left(resp.indexOf('\r')); int redGain=resp.toInt();
This also works and yields the expected responses.
Then I send a command multiple times that expects a 512 byte response for each execution. I do this using the following code:for (int i=0;i<64;i++) //64 blocks { comm=QString("r ffco\r"); serial->write(comm.toUtf8(),comm.size()); serial->flush(); while (serial->waitForReadyRead(200)) { resp=QString(serial->readAll()); } }
This is where the program gets stuck and freezes. However, if I add a
qDebug() << resp;
to the while loop it terminates. So I suppose there must be some issue with the timing that get solved accidentally by the execution time of writing to the qDebug output.
Any ideas how to fix the last code sample or general comments how to correctly implement this? -
This might be the culprit:
while (serial->waitForReadyRead(200))
This will put your thread to sleep until data has arrived or 200 ms has elapsed. QSerialPort seems to rely on the message loop to handle data so this might interfere with it (?). There is no guarantee that you will have 512 bytes of data back at once either.
There is a signal (QSerialPort::readyRead() ) you can use when received data arrives. Connect this to a suitable slot and buffer what has arrived each time the signal is fired (I assume you will not get all the data at once). Do this until you have 512 bytes then process it. Keep the event loop active if you have some other 'heavy' function somewhere (QApplication::processEvents() ).