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

multi precise timer delay functions compare



  • 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
    

  • Moderators

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



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


  • Moderators

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



  • @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 :-)


  • Lifetime Qt Champion

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


  • Moderators

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



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



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


Log in to reply