Skip to content

Add low-power event-driven timing support for battery-powered remotes - #67

Open
HelsingenMersken wants to merge 1 commit into
0x1abin:masterfrom
HelsingenMersken:develop
Open

Add low-power event-driven timing support for battery-powered remotes#67
HelsingenMersken wants to merge 1 commit into
0x1abin:masterfrom
HelsingenMersken:develop

Conversation

@HelsingenMersken

Copy link
Copy Markdown

Motivation

Battery-powered remote controls based on 2.4 GHz proprietary wireless or Bluetooth SoCs are extremely sensitive to standby power consumption.

The existing periodic polling API requires the MCU to wake up at every TICKS_INTERVAL, even when no button activity is present. On devices that spend most of their lifetime in sleep mode, these unnecessary wakeups can reduce battery life.

This PR adds an optional event-driven low-power API. It allows the MCU to sleep until either:

  • A GPIO button edge occurs
  • The next button-state deadline expires

This can reduce unnecessary wakeups and help extend battery life without introducing platform-specific sleep or timer dependencies into MultiButton.

Changes

  • Add button_ticks_low_power(uint32_t elapsed_ms)
    • Accepts the actual elapsed time since the previous call
    • Returns the delay in milliseconds until the next required wakeup
    • Returns 0 when no timer is required and the system may wait for a GPIO edge
  • Preserve the existing button_ticks() periodic polling API
  • Use deferred debounce confirmation to avoid repeated wakeups during the debounce period
  • Preserve sub-tick elapsed time for accurate deadline calculation
  • Avoid periodic long-press hold wakeups when no hold callback is registered
  • Add MULTIBUTTON_ENABLE_DOUBLE_CLICK
    • Double-click detection remains enabled by default
    • It can be disabled to avoid waiting for the double-click interval and further reduce wakeups
  • Add English and Chinese low-power integration documentation
  • Add unit tests for low-power timing, debounce, long press, sub-tick deadlines, and disabled double-click support

Compatibility

The existing API and default button behavior remain unchanged. Applications using button_ticks() can continue to work without modification.

The low-power API is optional and does not depend on any specific RTOS, timer, GPIO, Bluetooth, or 2.4 GHz SoC implementation.

Typical integration

  1. Configure the button GPIO to generate interrupts on both edges.
  2. Call button_ticks_low_power(elapsed_ms) after a GPIO edge or timer expiration.
  3. Start a one-shot timer using the returned delay.
  4. If the function returns 0, stop the timer and allow the MCU to sleep until the next GPIO edge.

Actual power savings depend on the MCU, GPIO, timer, and sleep-mode implementation, but the API makes it possible to avoid fixed-period button polling while idle.

Testing

  • Default configuration: 22/22 unit tests passed
  • Double-click disabled configuration: passed
  • Built with GCC using -std=c99 -Wall -Wextra -Werror -pedantic
  • Tested on hardware: fr801x BLE remote controller

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant