Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uC Power Consumption and sleep mode #24

Closed
NeoLegends opened this issue Mar 21, 2024 · 3 comments · Fixed by #45
Closed

uC Power Consumption and sleep mode #24

NeoLegends opened this issue Mar 21, 2024 · 3 comments · Fixed by #45
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@NeoLegends
Copy link

NeoLegends commented Mar 21, 2024

Hey! First of all thank you very much for releasing this awesome firmware! I have a question regarding power consumption.

I am planning on building a wearable BLE keyboard for outdoor scenaria, where a low power consumption is important for battery life. This would mean in my project I would like to rely on embassys interrupt-triggered pin level change notifications to allow the uC to go to sleep when no key is pressed and whenever the BLE stack permits this. Getting this right could enable a half-year battery-life (or so) on a button cell or so.

From afar rmk looks like perfect fit for the software for this project. However, as far as I understand the project, rmk will currently regularly poll the keyboard GPIO pins for their level instead of relying on embassy's interrupt-triggered async GPIO pin implementation to be notified on changes of the pin levels:

rmk/rmk/src/matrix.rs

Lines 84 to 107 in 243ba43

pub(crate) async fn scan(&mut self) -> Result<(), Infallible> {
for (out_idx, out_pin) in self.output_pins.iter_mut().enumerate() {
// Pull up output pin, wait 1us ensuring the change comes into effect
out_pin.set_high()?;
Timer::after_micros(1).await;
for (in_idx, in_pin) in self.input_pins.iter_mut().enumerate() {
// Check input pins and debounce
let changed = self.debouncer.detect_change_with_debounce(
in_idx,
out_idx,
in_pin.is_high()?,
&self.key_states[out_idx][in_idx],
);
if changed {
self.key_states[out_idx][in_idx].toggle_pressed();
}
self.key_states[out_idx][in_idx].changed = changed;
}
out_pin.set_low()?;
}
Ok(())
}

This would imply the uC cannot/does not go to a lower power level in between key presses, and would cause a "high" (in terms of what is possible for mobile scenaria) power consumption. Is that correct? Is this something you would like to improve?

I'm not sure I know enough about DIY keyboards to be able to drive a new, fully async implementation here (I think an async implementation would need quite some work on the debouncing/post-processing side), but would you be open to PRs on this topic?

Thank you in advance and best regards!

@HaoboGu
Copy link
Owner

HaoboGu commented Mar 21, 2024

Yes, rmk now does the traditional polling way when scanning pin matrix. It is because rmk was wired only before I migrated the whole project to embassy.

It should be possible to rewrite matrix scanning in an async way, but there are two issues to be solved:

  • how to perform async scanning when it comes to a key matrix? things become a little bit more complex if there are more than one keys are pressed simultaneously

  • how to perform async per-key deboucing? I couldn't find any reference for it

If above issues could be solved I'm very glad to migrate to async implementation. And I always open for PRs which about this😄

@HaoboGu HaoboGu added enhancement New feature or request help wanted Extra attention is needed labels Mar 23, 2024
@HaoboGu
Copy link
Owner

HaoboGu commented Mar 31, 2024

Just some info to share: I did some measurement on power consumption, the idle power consumption is about 5ma when doing advertising, and 7ma after connected for nrf52840. It could be saved a lot if we had sleep mode,that's for sure.

@HaoboGu
Copy link
Owner

HaoboGu commented Jun 6, 2024

I just opened a PR which achieves relatively lower power consumption(~700ua when idle, and ~6ma when sending BLE keyboard report). For a 1500mah battery, the estimated battery life is ~2months.

This PR is what I can achieve for now, I still have no idea about the full async way of processing the matrix scanning..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants