Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. multi precise timer delay functions compare

multi precise timer delay functions compare

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 5 Posters 840 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    QtTester
    wrote on 29 Apr 2021, 07:04 last edited by
    #1

    Hi guys:
    I have tried these code for a delay function, finally found the last one is the most precise delay.
    However, in a thread , the delay sometimes may not be the result i found.
    for example , simpleWait(50) will delay for 50 msec. but sometimes it will delay 100 msec.
    why? any help will be appreciated.

    void MyAction::simpleWait(int msec)
    {
        if(msec <= 0)
            return;
    
      // func1: tick has 10ms
        /*QTime dieTime = QTime::currentTime().addMSecs(msec);
     
        while (QTime::currentTime() < dieTime)
            QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);*/
     
        // func2: more 2~3sec than wanted
        /*QDeadlineTimer timer(msec,Qt::PreciseTimer);
        while(!timer.hasExpired())
            QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);*/
     
        // func3: longer
        /*QElapsedTimer timer;
     
        timer.start();
        while(!timer.hasExpired(msec))
            QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);*/
    
       // the precise one works for me:
        QTimer timer;
    
        timer.setTimerType(Qt::PreciseTimer);
        timer.start(msec);
        while(timer.remainingTime() > 0)
            QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
    }
    

    I use this code to measure tick:

    qint64 start = QDateTime::currentMSecsSinceEpoch();
    simpleWait(50);
    qDebug()<<"move:" <<(QDateTime::currentMSecsSinceEpoch() - start );
    // most delay = 50, sometimes = 100 or more
    
    J 1 Reply Last reply 29 Apr 2021, 08:14
    0
    • Q QtTester
      29 Apr 2021, 07:04

      Hi guys:
      I have tried these code for a delay function, finally found the last one is the most precise delay.
      However, in a thread , the delay sometimes may not be the result i found.
      for example , simpleWait(50) will delay for 50 msec. but sometimes it will delay 100 msec.
      why? any help will be appreciated.

      void MyAction::simpleWait(int msec)
      {
          if(msec <= 0)
              return;
      
        // func1: tick has 10ms
          /*QTime dieTime = QTime::currentTime().addMSecs(msec);
       
          while (QTime::currentTime() < dieTime)
              QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);*/
       
          // func2: more 2~3sec than wanted
          /*QDeadlineTimer timer(msec,Qt::PreciseTimer);
          while(!timer.hasExpired())
              QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);*/
       
          // func3: longer
          /*QElapsedTimer timer;
       
          timer.start();
          while(!timer.hasExpired(msec))
              QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);*/
      
         // the precise one works for me:
          QTimer timer;
      
          timer.setTimerType(Qt::PreciseTimer);
          timer.start(msec);
          while(timer.remainingTime() > 0)
              QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
      }
      

      I use this code to measure tick:

      qint64 start = QDateTime::currentMSecsSinceEpoch();
      simpleWait(50);
      qDebug()<<"move:" <<(QDateTime::currentMSecsSinceEpoch() - start );
      // most delay = 50, sometimes = 100 or more
      
      J Offline
      J Offline
      JKSH
      Moderators
      wrote on 29 Apr 2021, 08:14 last edited by
      #2

      @QtTester said in multi precise timer delay functions compare:

      why?

      What is your operating system?

      Windows is a non-deterministic, non-real-time OS so it doesn't guarantee timings. The OS can decide to allocate CPU time to other programs, for example.

      If it is important for you to always get exactly 50ms, then you need a real-time operating system such as https://www.linux.com/news/inside-real-time-linux/

          while(timer.remainingTime() > 0)
              QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
      

      This code is a bit like a spinlock (https://en.wikipedia.org/wiki/Spinlock ) which is quite inefficient and burns your CPU.

      May I ask why you need a "delay" function? Asynchronous, event-driven programming is usually better.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      Q 1 Reply Last reply 29 Apr 2021, 08:29
      3
      • J JKSH
        29 Apr 2021, 08:14

        @QtTester said in multi precise timer delay functions compare:

        why?

        What is your operating system?

        Windows is a non-deterministic, non-real-time OS so it doesn't guarantee timings. The OS can decide to allocate CPU time to other programs, for example.

        If it is important for you to always get exactly 50ms, then you need a real-time operating system such as https://www.linux.com/news/inside-real-time-linux/

            while(timer.remainingTime() > 0)
                QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
        

        This code is a bit like a spinlock (https://en.wikipedia.org/wiki/Spinlock ) which is quite inefficient and burns your CPU.

        May I ask why you need a "delay" function? Asynchronous, event-driven programming is usually better.

        Q Offline
        Q Offline
        QtTester
        wrote on 29 Apr 2021, 08:29 last edited by
        #3

        @JKSH thanks for reply.
        My Os is Windows 10. qt is 15.4.1.
        delay is needed to check external hardware's position, for example the servo motor runs to some position.

        int32_t MyAction::moveXY(uint32_t motorId1,uint32_t motorId2, int32_t pos1, int32_t pos2,int spdLevel,uint32_t timeOut)
        {
            int32_t ret = ERR_NONE;
            uint32_t tOut = 0;
        
            ret = m_mcBase->absMove(motorId1, pos1, spdLevel);
            if(ret == ERR_NONE)
                ret = m_mcBase->absMove(motorId2, pos2, spdLevel);
            if(ret != ERR_NONE)
                return ret;
        
          // check motor position 
            while(true){
                if(m_mcBase->checkPositionDone(motorId1) && m_mcBase->checkPositionDone(motorId2))
                    break;
        
                simpleWait(1);
                if(tOut++ > timeOut){
                    return ERR_TIME_OUT;
                }
            }
            return ret;
        }
        

        Finally , I found if QTimer is a global member, like QTimer *m_threadTimer, the function works fine.
        Do not know why when it is as a local variable it will not work sometimes.

        J K 2 Replies Last reply 29 Apr 2021, 08:36
        0
        • Q QtTester
          29 Apr 2021, 08:29

          @JKSH thanks for reply.
          My Os is Windows 10. qt is 15.4.1.
          delay is needed to check external hardware's position, for example the servo motor runs to some position.

          int32_t MyAction::moveXY(uint32_t motorId1,uint32_t motorId2, int32_t pos1, int32_t pos2,int spdLevel,uint32_t timeOut)
          {
              int32_t ret = ERR_NONE;
              uint32_t tOut = 0;
          
              ret = m_mcBase->absMove(motorId1, pos1, spdLevel);
              if(ret == ERR_NONE)
                  ret = m_mcBase->absMove(motorId2, pos2, spdLevel);
              if(ret != ERR_NONE)
                  return ret;
          
            // check motor position 
              while(true){
                  if(m_mcBase->checkPositionDone(motorId1) && m_mcBase->checkPositionDone(motorId2))
                      break;
          
                  simpleWait(1);
                  if(tOut++ > timeOut){
                      return ERR_TIME_OUT;
                  }
              }
              return ret;
          }
          

          Finally , I found if QTimer is a global member, like QTimer *m_threadTimer, the function works fine.
          Do not know why when it is as a local variable it will not work sometimes.

          J Offline
          J Offline
          JKSH
          Moderators
          wrote on 29 Apr 2021, 08:36 last edited by
          #4

          @QtTester said in multi precise timer delay functions compare:

          Finally , I found if QTimer is a global member, like QTimer *m_threadTimer, the function works fine.
          Do not know why when it is as a local variable it will not work sometimes.

          Well, it is expensive to create and destroy a QObject several hundred times per second.

          delay is needed to check external hardware's position, for example the servo motor runs to some position.

          Could you not connect the QTimer::timeout() signal to run a slot at fixed intervals to check the position?

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          Q 1 Reply Last reply 29 Apr 2021, 08:42
          0
          • J JKSH
            29 Apr 2021, 08:36

            @QtTester said in multi precise timer delay functions compare:

            Finally , I found if QTimer is a global member, like QTimer *m_threadTimer, the function works fine.
            Do not know why when it is as a local variable it will not work sometimes.

            Well, it is expensive to create and destroy a QObject several hundred times per second.

            delay is needed to check external hardware's position, for example the servo motor runs to some position.

            Could you not connect the QTimer::timeout() signal to run a slot at fixed intervals to check the position?

            Q Offline
            Q Offline
            QtTester
            wrote on 29 Apr 2021, 08:42 last edited by
            #5

            @JKSH
            We donot know when the position is done ,and need to return as soon as possible, 1 msec delay is the best way.
            time is money in factory, And if you donot use the CPU , it still does nothing right there :-)

            J 1 Reply Last reply 29 Apr 2021, 11:26
            0
            • Q QtTester
              29 Apr 2021, 08:42

              @JKSH
              We donot know when the position is done ,and need to return as soon as possible, 1 msec delay is the best way.
              time is money in factory, And if you donot use the CPU , it still does nothing right there :-)

              J Offline
              J Offline
              jsulm
              Lifetime Qt Champion
              wrote on 29 Apr 2021, 11:26 last edited by kshegunov
              #6

              @QtTester said in multi precise timer delay functions compare:

              1 msec delay is the best way

              You can can't have 1msec timeout with QTimer...

              [Edit: Typo fixed ~kshegunov]

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • Q QtTester
                29 Apr 2021, 08:29

                @JKSH thanks for reply.
                My Os is Windows 10. qt is 15.4.1.
                delay is needed to check external hardware's position, for example the servo motor runs to some position.

                int32_t MyAction::moveXY(uint32_t motorId1,uint32_t motorId2, int32_t pos1, int32_t pos2,int spdLevel,uint32_t timeOut)
                {
                    int32_t ret = ERR_NONE;
                    uint32_t tOut = 0;
                
                    ret = m_mcBase->absMove(motorId1, pos1, spdLevel);
                    if(ret == ERR_NONE)
                        ret = m_mcBase->absMove(motorId2, pos2, spdLevel);
                    if(ret != ERR_NONE)
                        return ret;
                
                  // check motor position 
                    while(true){
                        if(m_mcBase->checkPositionDone(motorId1) && m_mcBase->checkPositionDone(motorId2))
                            break;
                
                        simpleWait(1);
                        if(tOut++ > timeOut){
                            return ERR_TIME_OUT;
                        }
                    }
                    return ret;
                }
                

                Finally , I found if QTimer is a global member, like QTimer *m_threadTimer, the function works fine.
                Do not know why when it is as a local variable it will not work sometimes.

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 29 Apr 2021, 20:49 last edited by
                #7

                @QtTester said in multi precise timer delay functions compare:

                delay is needed to check external hardware's position, for example the servo motor runs to some position.

                That's why drivers (and interrupts) were invented. Do you have a driver with a corresponding client library for said machine?

                Read and abide by the Qt Code of Conduct

                Q 1 Reply Last reply 30 Apr 2021, 03:36
                2
                • K kshegunov
                  29 Apr 2021, 20:49

                  @QtTester said in multi precise timer delay functions compare:

                  delay is needed to check external hardware's position, for example the servo motor runs to some position.

                  That's why drivers (and interrupts) were invented. Do you have a driver with a corresponding client library for said machine?

                  Q Offline
                  Q Offline
                  QtTester
                  wrote on 30 Apr 2021, 03:36 last edited by QtTester
                  #8

                  @kshegunov said in multi precise timer delay functions compare:

                  That's why drivers (and interrupts) were invented. Do you have a driver with a corresponding client library for said machine?

                  driver still does the same thing to check flag and signal app.

                  @jsulm said in multi precise timer delay functions compare:

                  You can can't have 1msec timeout with QTimer...

                  seems works for me.

                  J 1 Reply Last reply 30 Apr 2021, 05:42
                  0
                  • Q QtTester
                    30 Apr 2021, 03:36

                    @kshegunov said in multi precise timer delay functions compare:

                    That's why drivers (and interrupts) were invented. Do you have a driver with a corresponding client library for said machine?

                    driver still does the same thing to check flag and signal app.

                    @jsulm said in multi precise timer delay functions compare:

                    You can can't have 1msec timeout with QTimer...

                    seems works for me.

                    J Offline
                    J Offline
                    jeremy_k
                    wrote on 30 Apr 2021, 05:42 last edited by
                    #9

                    If high precision busy waiting is the goal, QDeadlineTimer is a better choice than QTimer.

                    Asking a question about code? http://eel.is/iso-c++/testcase/

                    1 Reply Last reply
                    3

                    9/9

                    30 Apr 2021, 05:42

                    • Login

                    • Login or register to search.
                    9 out of 9
                    • First post
                      9/9
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved