InfiniTime icon indicating copy to clipboard operation
InfiniTime copied to clipboard

Keep updating motion during sleep when Bluetooth is on

Open apilat opened this issue 2 years ago • 6 comments

Since connected Bluetooth devices can request motion data at any point, we should keep updating it when we are connected to one. Currently stale data will be delivered when the screen is turned off. Some wake up settings already cause motion data to be updated with the screen off so this change should not have a significant impact on battery life.

apilat avatar Jun 29 '22 12:06 apilat

This is also enabled in https://github.com/InfiniTimeOrg/InfiniTime/pull/1133 .

Keep in mind that continuously broadcasting the motion data consumes quite a bit of power, refer to https://github.com/StarGate01/p8b-infinitime/tree/master/poweranalysis (The analysis was performed for my high-frequency motion implementation, but it should give a rough idea still) . Ideally, the user would have the option to toggle this broadcast.

StarGate01 avatar Jun 30 '22 03:06 StarGate01

Continuously polling the accelerometer during sleep is also enabled by some features in order to detect wakeup so I assume that the power used for this is reasonably small or at least acceptable, but if not I'm willing to make this behavior optional. If I'm reading the code correctly, this if will prevent broadcasting unless the companion specifically requested notifications, in which case I think using some power for this is reasonable (otherwise we would be providing incorrect data).

apilat avatar Jun 30 '22 09:06 apilat

First of all, I like this change. I use apps to read the acceleration data as well.

Concerning the code flow: You are correct, the service only sends out data if the peer is subscribed. So for a default use-case, power consumption concerning the BLE radio should stay the same.

The new motion data is ingressed via MotionController::Update, which is called by SystemTask::UpdateMotion. The system task code returns early if the watch is sleeping, and does not need to wake up by a motion event. In my PR I removed the whole sleeping check , since all the function does afterwards is updating the motion service and checking the wake-up conditions again.

Your patch, if I read that correctly, adds an additional pass-through condition bleController.IsConnected, which is essentially most of the time in normal use (I guess).

Continuously polling the accelerometer during sleep is also enabled by some features in order to detect wakeup

This is only enabled if you want the watch to wake up at motion events.

To wrap up, I am debating if we need that check at all, or if it could be more-fine grained - e.g. checking if the BLE motion service is subscribed instead of checking if Bluetooth is connected in general. I think giving the user the option to conserve energy by disabling motion wakeup should be considered.

Maybe @Riksu9000 has some thoughts on this.

StarGate01 avatar Jun 30 '22 13:06 StarGate01

In general we should make the behaviour the most efficient and require the least input from the user. In this case the best solution to me seems to be updating motion only when it is needed, so when a motion based wakeup method is enabled or the service is subscribed. That way the user can save battery by disabling wakeup methods and the motion data is still accessible when needed.

Riksu9000 avatar Jun 30 '22 14:06 Riksu9000

In this case the best solution to me seems to be updating motion only when it is needed, so when a motion based wakeup method is enabled or the service is subscribed.

This is now implemented. I couldn't find an existing way to access MotionService from SystemTask so I ended up adding MotionController::GetService().

apilat avatar Jun 30 '22 15:06 apilat

Would it not be better to add MotionService to SystemTask's constructor? That seems to be how it is done in most other cases.

FintasticMan avatar Jun 30 '22 15:06 FintasticMan