Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Issue with the serial data received and processing time



  • Hello Everyone,

    There are two functions in my qt program which gets triggered when data is received at serial port.
    My problem is that fun1 gets processed immediately but fun 2 sometime takes time to process and data get accumulated on the serial port, which creates problem when i get the next serial data.

    Fuc 1 should be executed instantly so cannot be delayed but fun2 can be executed independently. So i thinking to execute fun2 in a QThread

    But my problem is that:

    1. If suppose Qthread is executing the function and other requrest arises what will happen.
    2. If i put a wait for the thread what will be the result would my program will wait for earlier thread to execute creating a lag in the program.
      Ex:
    void MainWindow::funB()
    {
        thread->wait(); // If the thread is not running, this will immediately return.
         worker->requestWork();
    }
    
    1. If the program lags due to wait is there any mechanism to place the request in queue so it execute after the request is completed.
    2. Is there any better option to do the above implementation apart from thread.

    Note: I cannot create multiple thread for each function call as the do not want to break the sequence in which the function gets executed.

    Thanks in advance



  • @Kira said in Issue with the serial data received and processing time:

    which creates problem when i get the next serial data

    It shouldn't. I suspect you are doing something wrong when reading the serial data. can you post the code inside the 2 functions that read the data?



  • @VRonin : Being a bit more clear.
    So i am communicating with a device which sends me data after certain interval of time.
    Currently i am not using not using any acknowledgement mechanism.
    The time at which data is sent by the device is fixed. I have written the functions in serial read slot so when i receives the data i process the function in same slot ,so the slot take time to execute and the n machine data already gets buffered on the port.



  • @VRonin said in Issue with the serial data received and processing time:

    can you post the code inside the 2 functions that read the data?



  • @VRonin :

    Function declaration:

    funA(){
           qDebug(logInfo())<<"Bit 'a' received by the controller";
           bitCounter ++;
    }
    funB()
    {
          sprintf_s(saveimage, "C:\\Users\\sample"
                                        "\\Image_%d.jpeg", image); // Selecting location and name for image
            if(imwrite(saveimage, image)){
                qDebug(logInfo())<<"Image Saved;
    }
    

    Function call:

     // Slot when serail readready signal gets generated
    void MainWindow::readData()
    {
          if(receivedData.contains("a"))
     {
           funA();
           funB(); //Function to save image creates a delay sometimes
    }
    }
    


  • @Kira In the code above is not what we are after, we want to know how you read from the serial



  • @VRonin :
    OK so this signal to slot connection is used to read the serial data:
    connect(serialPort, &QSerialPort::readyRead,this,&MainWindow::readData);
    //It gets triggered when serail data is generated.
    You can also refer to the serial port examples in qt example set i have followed steps mentioned in the example.



  • MainWindow::readData() you posted above never interacts with serialPort 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
    }
    }


  • Moderators

    @Kira

    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
            }
        }
    


  • @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.



  • @mrdebug : Cannot buffer the data because camera capture has to be done at time of receiving the signal.
    If i read the buffered data the camera capture times may mismatch.


  • Qt Champions 2019

    @mrdebug I don't see any need for a thread in this case. Multithreading just overcomplicates things here without any benefit.



  • 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


  • Moderators

    @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.



  • @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.



  • Thanks guys for your answers and time. Moving with logic suggest @J-Hilk instead of QThread for solving the problem.

    QT forum have always been ever active, best and interactive forum of all time.
    Thanks :)


Log in to reply