Issue with the serial data received and processing time
-
MainWindow::readData()
you posted above never interacts withserialPort
so I'm a bit confused on how that works...@VRonin : It interacts when using this:
connect(serialPort, &QSerialPort::readyRead,this,&MainWindow::readData);
Above get called when data is generated at serial port.
For more clarity
void MainWindow::readData()
{
QByteArray readData = serialPort->readAll();
if(receivedData.contains("a"))
{
funA();
funB(); //Function to save image creates a delay sometimes
}
} -
@VRonin : It interacts when using this:
connect(serialPort, &QSerialPort::readyRead,this,&MainWindow::readData);
Above get called when data is generated at serial port.
For more clarity
void MainWindow::readData()
{
QByteArray readData = serialPort->readAll();
if(receivedData.contains("a"))
{
funA();
funB(); //Function to save image creates a delay sometimes
}
}that is a very raw implementation of to handle the readyRead data.
For example you have no idea if all data is already send to the port. ReadyRead is emitted whenever new data has arrived not when all data has arrived. You'll have to manage that yourself.However to answer your original question.
in your case I would probably use Qt:Concurrent, no need to fully implement QThread for simply saving an image.
However I usually Thread my SerialPort.//PseudoCode: QFuture future; QFutureWatcher watcher; watcher.setFuture(future); connect(&watcher, &QFutureWatcher::finished, this, &myClass::processQueue); .... .... if(future.isFinished()){ future = QtConcurrent::run(imwrite, saveimage, image); }else{ saveQueue.append(MyStruct(saveimage,image)); }
-
I suggest you to use thread.
In the run() you can try this:QByteArray QBABufferInTemp; while (DoStart) { SerialPort.waitForReadyRead(50); QBABufferInTemp.append(SerialPort.readAll()); if (QBABufferInTemp.size()> 0) { if (HasTheBufferGotTheTerminator(QBABufferInTemp)) { // extract data from the buffer // emit } }
-
that is a very raw implementation of to handle the readyRead data.
For example you have no idea if all data is already send to the port. ReadyRead is emitted whenever new data has arrived not when all data has arrived. You'll have to manage that yourself.However to answer your original question.
in your case I would probably use Qt:Concurrent, no need to fully implement QThread for simply saving an image.
However I usually Thread my SerialPort.//PseudoCode: QFuture future; QFutureWatcher watcher; watcher.setFuture(future); connect(&watcher, &QFutureWatcher::finished, this, &myClass::processQueue); .... .... if(future.isFinished()){ future = QtConcurrent::run(imwrite, saveimage, image); }else{ saveQueue.append(MyStruct(saveimage,image)); }
-
I suggest you to use thread.
In the run() you can try this:QByteArray QBABufferInTemp; while (DoStart) { SerialPort.waitForReadyRead(50); QBABufferInTemp.append(SerialPort.readAll()); if (QBABufferInTemp.size()> 0) { if (HasTheBufferGotTheTerminator(QBABufferInTemp)) { // extract data from the buffer // emit } }
-
I suggest you to use thread.
In the run() you can try this:QByteArray QBABufferInTemp; while (DoStart) { SerialPort.waitForReadyRead(50); QBABufferInTemp.append(SerialPort.readAll()); if (QBABufferInTemp.size()> 0) { if (HasTheBufferGotTheTerminator(QBABufferInTemp)) { // extract data from the buffer // emit } }
-
QByteArray readData = serialPort->readAll(); if(receivedData.contains("a"))
readData
is unused?Your program, I guess, assumes that when you call
serialPort->readAll();
the buffer contains 1 and only one "chunck" of data. Such design is extremely unstable. a slow down in your connection speed can destroy your logic.You have to identify different chunks of data. independently of how they reach you
-
@J.Hilk : Thanks for the reply as per the above Psuedocode what i understand is
it will use queue to store the data and process it concurrently.Please clarify if wrong.
@Kira said in Issue with the serial data received and processing time:
@J.Hilk : Thanks for the reply as per the above Psuedocode what i understand is
it will use queue to store the data and process it concurrently.Please clarify if wrong.
no, thats about it.
And thats the ways this stuff is handled usually.Usually one stores the data from
readAll()
and as soon as you can identify as a coherent data-chunk you pass it along to your process function. -
QByteArray readData = serialPort->readAll(); if(receivedData.contains("a"))
readData
is unused?Your program, I guess, assumes that when you call
serialPort->readAll();
the buffer contains 1 and only one "chunck" of data. Such design is extremely unstable. a slow down in your connection speed can destroy your logic.You have to identify different chunks of data. independently of how they reach you
@VRonin :
Your assumption is correct regarding serailPort->readAll();
Actually the device with which i am communicating is working in controlled environment where behavior and type of signal generated is known in advance. It is expected to generate a the required data at that time. Every signal bit represents the command to capture image at a particular location of the controller. So if suppose two bit get generated at the port it is undesirable because if i process them individually my time and position may mismatch. I may not get the location exactly where the image has to be taken. That why i was in need of better and correct logic to handle such a scenario.
Currently it is handled by sending acknowledgement to the port but still in need of better logic for it.