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 regardsimport 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() } }
-
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 regardsimport 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() } }
@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.
-
@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.
-
How are you using the timer, then?
-
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 regardsimport 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() } }
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. -
@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?
-
@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(); }
-
@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...
-
@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?
-
@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 aQSoundEffect
to play the sound and aQTimer
for the play loop and somePROPERTY
to interface with QML, like:- sound file for
QSoundEffect
- interval for the
QTimer
The register this class to be usable from QML.
- sound file for