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

QT timer accuracy mobile



  • Hi,

    I've been developing a mobile app (qml and js) and I have a timer that is not very accurate.

    The timer range can go from every two second to 0.2 of a second...
    But just a bit above one second it starts to already rush a little bit... (enough to not accomplish the goals).

    This timer is supposed to trigger a sound event.

    I've read some topics also suggesting ElapsedTime, but it would be to heavy on the battery.

    What option do I have for High Accuracy timer on mobile?

    Thank you,
    Best regards

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.13
    import QtQuick.Layouts 1.3
    import QtMultimedia 5.12
    //import QtQuick.LocalStorage 2.0//will be used in future
    
    ApplicationWindow {
    
        visible: true
        title: MyApp
        width: 400
        height: 700
        color: "#232020"
    
    
        Dial {
            id: dial
            x: 108
            y: 318
            value: 60
            inputMode: Dial.Circular
            to: 300
            from: 35
            stepSize: 1.2
    
    
        }
    
        Button {
            id: bttStart
            x: 150
            y: 569
    
            palette {
                       button: "#5b5353"
                    }
    
            text: "<font color='#fefefe'>" + qsTr("Start") + "</font>"
    
            onClicked: timer.start()
    
    
        }
    
       
    
        Timer {
                id: timer
                interval: 60000/parseInt(dial.value)
                running: false
                repeat: true
                triggeredOnStart: true
    
                onTriggered: {
                    playSound();
    
            }
    
    
    
        SoundEffect {
                id: soundFile
                source: "qrc:/sounds/sounds/sound.wav"
            }
    
    
        function playSound(sound) {    
            soundFile.play()
            }
    
    
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

  • Moderators

    @dev_x said in QT timer accuracy mobile:

    I've read some topics also suggesting ElapsedTime, but it would be to heavy on the battery.

    Don't overestimate that effect, measure it first :-)

    What option do I have for High Accuracy timer on mobile?

    I think keeping your app alive is the most important bit. Android and iOS are very aggressively trying to hibernate / slow down / stop apps which are not showing directly on screen. This means your CPU clock is constantly changing it's frequency, application is denied CPU time a lot etc. The only way to get a more reliable clock times is to keep the app running in the background and disabling battery optimizations.



  • This post is deleted!


  • @sierdzio

    Hi!

    So, for now I'm still developing it on windows, but actually the main goal is to develop for a linux based mobile platform (iOS and Android as well if possible). But just by running the app I can hear it's not ok.

    Any suggestion?


  • Moderators

    How are you using the timer, then?


  • Moderators

    hi
    @dev_x said in QT timer accuracy mobile:

    The timer range can go from every two second to 0.2 of a second...
    But just a bit above one second it starts to already rush a little bit... (enough to not accomplish the goals).

    can you clarify that for me?

    DO you have a QTimer that is running and you detect timeouts that vary from 0.2 to 2 seconds? What is the interval you have set?



  • @sierdzio @J-Hilk Just updated post to contain relevant code. The timer is triggered when button clicked. The timer is defined by 60s splited by the number defined in dial control..



  • @dev_x QML Timer are synchronized with the rendering thread and are not precise, see documentation.

    The Timer type is synchronized with the animation timer. Since the animation timer is usually set to 60fps, the resolution of Timer will be at best 16ms.

    If you need high accuracy, you have to use QTimer in a C++ class.
    By the way, QML is not the right place to made time consuming/accuray relevant processing. QML is very cool for building IHM but for data processing C++ is the right choice.



  • @KroMignon Is it a easy to task to call a c++ function without changing much this original code?



  • @dev_x said in QT timer accuracy mobile:

    Is it a easy to task to call a c++ function without changing much this original code?

    Interfacing C++ and QML is not that complicated, there are many examples around this forum and in Qt documentation ==> https://doc.qt.io/qt-5/qtqml-cppintegration-topic.html

    But it depends on what exactly you want to achieve...
    The problem with your code is that, each time you are changing the Dial button, you will also change the Timer interval and, according to documentation, this will restart your Timer from 0:

    If the Timer is running and one of its properties is changed, the elapsed time will be reset. For example, if a Timer with interval of 1000ms has its repeat property changed 500ms after starting, the elapsed time will be reset to 0, and the Timer will be triggered 1000ms later.

    So to made your QML smarter, I would suggest this modifications:

        Timer {
                id: timer
                interval: 60000
                running: false
                repeat: true
                triggeredOnStart: true
    
                onTriggered: {
                    // change interval after trigger to avoid restarting timer on each Dial rotation
                    interval = 60000/parseInt(dial.value)
                    playSound();
            }
    


  • @KroMignon thank you. I've tested, it didn't improved much (time wise). I will give a look at how to implement this timer in c++ without changing to much the logic...



  • @dev_x said in QT timer accuracy mobile:

    it didn't improved much (time wise).

    To be honest, I don't really understand what your problem exactly is!
    What do you want to achieve? What is your current problem?
    Are you sure the problem source is the Timer instance?
    According to your code, Timer interval should be between 200ms (60000/300) and 1714ms (60000/35). Timer precision is about 20ms. So there is no problem with that.

    I don't believe using QTimer will change anything.



  • @KroMignon said in QT timer accuracy mobile:

    200ms (60000/300) and 1714ms (60000/35). Timer precision is about 20ms. So there is no problem with that.
    I don't believe using QTimer will change anything.

    Yes, I really believe it's related with the timer or the system (windows). I will test it on my linux laptop. The timer is just not constant, I can hear the sound not being precise (and it's just a very short sound. Think about this like a metronome, but there is a beat random beat every 7/8 than rushes/delays... after a few repetitions, it's 'way' of...

    There are others commenting on this:

    https://stackoverflow.com/questions/42421675/qtimer-not-accurate-at-all/42422121

    https://stackoverflow.com/questions/30626887/improving-qtimer-accuracy

    And I also may have to make the intervals even shorter... split a minute by up to 300/400...

    How would you solve if it had to be as rigorous as a metronome?



  • @dev_x said in QT timer accuracy mobile:

    How would you solve if it had to be as rigorous as a metronome?

    As written before, QML is not the right place for time relevant operation. JavaScript/QML has very poor performances compared to C++!

    I would create a C++ class to handle this, a simple QObject based class with includes a QSoundEffect to play the sound and a QTimer for the play loop and some PROPERTY to interface with QML, like:

    • sound file for QSoundEffect
    • interval for the QTimer

    The register this class to be usable from QML.


Log in to reply