How implement serial delay



  • I have a send function and now I need a delay of 2 ms after I send a byte. If I send quicker than these 2 ms the receiving end will miss the data.

    void MainWindow::send(QString c)
    {
        serial->write(c.toLatin1());
        QString cAsHex = QString("%1").arg(c, 0, 16);
        qDebug()  << cAsHex << " >>";
    }
    

    I was wondering what the most efficient way would be to do this. I don't know whether I can use some fancy serial function of which I don't know about yet or if I should pause the entire application using a QThread delay.

    It is not big deal if the program freezes temporarily.


  • Moderators

    @bask185 Just use QTimer


  • Qt Champions 2016

    And what ever you do, please dont use QThread delay. :)



  • @jsulm said in How implement serial delay:

    @bask185 Just use QTimer

    Thank you. I will try it out ;)

    @mrjj said in How implement serial delay:

    And what ever you do, please dont use QThread delay. :)

    You cannot say something like that if you don't provide the 'why' argument with it. This is just like saying: "never use global variables" or "always use 'private' and 'public'".

    If I say: "jump in the ditch", how likely will it be that you will actually do it? But if I say: "Jump in the ditch, because there is a person drowning in it" than it is more likely that you will actually jump in the ditch. I said in the OP that it would not be a big deal if my program would freeze temporarily during a data transfer so I am not even remotely getting why I should not use a QThread delay??? If my push buttons would be disabled, it would actually be better because no user can accidently send a 'false' byte.



  • This

    void MainWindow::send(QString c)
    {
      QTimer::singleShot(2, this, SLOT(timeOut()));
      timer = true;
    
      serial->write(c.toLatin1());
      QString cAsHex = QString("%1").arg(c, 0, 16);
      qDebug()  << cAsHex << " >>";
      while (timer == true) {;}
    }
    
    void MainWindow::timeOut()
    {
        timer = false;
    }
    

    is not working. The idea is that timeOut gets called 2ms after a byte has been send so the program can escape the while loop.

    Why is this not working??

    EDIT:
    does not matter I used a different approach with a timer object and ->start(2) and -> stop() functions. This works ;)


  • Qt Champions 2016

    @bask185

    Fair enough, please don't use QThread delay for any kind of pausing in a main thread as it also strangulate the
    event/signal processing and can lead to all sort of odd behaviors. Its simply a wrong solution to the requirements.

    Your buttons are not really disabled, they simply not getting the click event ( or some might) so using
    delay is just bad design in 99% of all cases in regards to the main thread.
    To disable, there is a function for just that.


  • Moderators

    @bask185 Well, this just cannot work as your while loop blocks the event loop which breaks signals/slots.
    Why did you put the loop there?

    void MainWindow::send(QString c)
    {
      QTimer::singleShot(2, this, SLOT(timeOut()));
      serial->write(c.toLatin1());
      QString cAsHex = QString("%1").arg(c, 0, 16);
      qDebug()  << cAsHex << " >>";
    }
    
    void MainWindow::timeOut()
    {
        // Here send the rest of the data
    }
    


  • I would suggest something like this:

    //Member variables:
    QTimer *timer;
    QList<QString> dataToSend;
    
    /*Timer event*/
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, timer, [=]{
         if(dataToSend.size() > 0){
             send(dataToSend.first());
             dataToSend.removeFirst();
        }
        if(dataToSend.isEmpty())
            timer->stop();
    });
    
    /*Start send*/
    ...
    dataToSend.append(newData);
    if(!timer->isRunning())
        timer->start(2);
    


  • I now use:

    void MainWindow::send(QString c)
    {
    
      timer->start(2);
    
      serial->write(c.toLatin1());
      QString cAsHex = QString("%1").arg(c, 0, 16);
      qDebug()  << cAsHex << " >>";
      while (Timer == true) {;}
    }
    
    void MainWindow::timeOut()
    {
        Timer = false;
        timer->stop();
    }
    

    and it works like a charm


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.