button_handler

This helper library simplifies the usage of buttons with CircuitPython, by detecting and differentiating button inputs, returning a set of the inputs and calling their corresponding functions.

  • Author(s): EGJ Moorington

Implementation Notes

Software and Dependencies:

class button_handler.Button(button_number: int = 0, config: ButtonInitConfig = ButtonInitConfig())

Contains information about a single button.

Parameters:
Raises:

ValueError – if button_number is smaller than 0.

enable_multi_press: bool = config.enable_multi_press = True

Whether to account for the possibility of another short press following a short press and counting that as a multi-press. If set to false, ButtonHandler.update() returns a short press ButtonInput object immediately after a short press.

long_press_threshold: float = config.long_press_threshold = 1000

The minimum length of a press to count as a long press, and the time the button should be pressed before counting as being held down.

max_multi_press: int = config.max_multi_press = 2

The maximum amount of button presses that a multi-press can be. ButtonHandler.update() returns the appropriate multi-press ButtonInput object immediaetly after the button has been pressed this many times.

multi_press_interval: float = config.multi_press_interval = 175

The time frame from a button release within which another release should occur to count as a multi-press.

Caution

Attributes with a leading underscore (_) are meant for internal use only, and accessing them may cause unexpected behaviour. Please consider accessing a property (if available) instead.

_button_number: int = button_number = 0

The index number associated with the button. Consider using button_number instead.

_is_holding: bool = False

Whether the button has been held down for at least the time specified by long_press_threshold. Consider using is_holding instead.

_is_pressed: bool = False

Whether the button is currently pressed. Consider using is_pressed instead.

_last_press_time: float | None = None

The time (in miliseconds, tracked by supervisor.ticks_ms()) that has passed since the start of the previous press of a multi-press. It is set to None after the time specified by multi_press_interval has passed.

_press_count: int = 0

The amount of times the button has been pressed since the last multi-press ended. It is set to 0 if the time set by multi_press_interval passes after a short press.

_press_start_time: float = ticks_ms()

The time (in milliseconds, tracked by supervisor.ticks_ms()) at which the last button press began.

_check_multi_press_timeout(current_time: int) int | None

Caution

Methods with a leading underscore (_) are meant for internal use only, and calling them may cause unexpected behaviour. Please refrain from using them.

Check whether a multi-press has ended. If it has, return the amount of times the button was pressed in that multi-press.

Parameters:

current_time (int) – The current time, provided by supervisor.ticks_ms().

Returns:

The amount of times the button was pressed in a multi-press, if a multi-press has ended.

Return type:

int or None

_is_held(current_time: int) bool

Caution

Methods with a leading underscore (_) are meant for internal use only, and calling them may cause unexpected behaviour. Please refrain from using them.

Check whether the button has been held down for at least the time specified by long_press_threshold.

Parameters:

current_time (int) – The current time, provided by supervisor.ticks_ms().

Returns:

Whether the button just began being held down.

Return type:

bool

property button_number

The index number associated with the button.

Type:

int

property is_holding

Whether the button has been held down for at least the time specified by long_press_threshold.

Type:

bool

property is_pressed

Whether the button is currently pressed.

Type:

bool

class button_handler.ButtonHandler(event_queue: EventQueue, callable_inputs: set[ButtonInput], button_amount: int = 1, config: dict[int, ButtonInitConfig] = None)

Handles different types of button presses.

Parameters:
Raises:

ValueError – if button_amount is smaller than 1, or if it is not an int.

callable_inputs: set[ButtonInput] = callable_inputs

A set of ButtonInput objects used to define which functions to call when a specific input is detected.

Caution

Attributes with a leading underscore (_) are meant for internal use only, and accessing them may cause unexpected behaviour. Please consider accessing a property (if available) instead.

_event: keypad.Event = Event()

The keypad.Event object used to store the next event to handle.

_event_queue: keypad.EventQueue = event_queue

The keypad.EventQueue object the handler should read events from.

_call_callbacks(inputs: set[ButtonInput]) None

Caution

Methods with a leading underscore (_) are meant for internal use only, and calling them may cause unexpected behaviour. Please refrain from using them.

Call the callback function associated with every ButtonInput object detected during execution of update().

Parameters:

inputs (set[ButtonInput]) – A set containing every input whose callback is to be called.

_handle_buttons() set[ButtonInput]

Caution

Methods with a leading underscore (_) are meant for internal use only, and calling them may cause unexpected behaviour. Please refrain from using them.

Check if any button began being held down since the last time this mehod was called and if any multi-press ended, and return every detected ButtonInput.

Returns:

A set containing every detected ButtonInput.

Return type:

set[ButtonInput]

_handle_event(event: Event) ButtonInput | None

Caution

Methods with a leading underscore (_) are meant for internal use only, and calling them may cause unexpected behaviour. Please refrain from using them.

Process a keypad.Event and return a ButtonInput based on it.

Parameters:

event (keypad.Event) – The keypad.Event object to process.

Returns:

The detected ButtonInput, if any.

Return type:

ButtonInput or None

property buttons: list[Button]

The Button objects that the handler handles.

Returns:

The list of Button objects that the handler handles.

Return type:

list[Button]

update() set[ButtonInput]

Check if any button ended a multi-press since the last time this method was called, process the next keypad.Event in _event_queue, call all the relevant callback functions and return a set of the detected ButtonInputs.

Returns:

Returns a set containing all of the detected ButtonInputs

Return type:

set[ButtonInput]

class button_handler.ButtonInitConfig(enable_multi_press: bool = True, multi_press_interval: float = 175, long_press_threshold: float = 1000, max_multi_press: int = 2)

Holds configuration values to pass when a ButtonHandler object is initialised.

Parameters:
  • enable_multi_press (bool) – Sets enable_multi_press (whether to track multi-presses).

  • multi_press_interval (float) – Sets multi_press_interval (the time frame within which two presses should occur to count as a multi-press).

  • long_press_threshold (float) – Sets long_press_threshold (the minimum length of a press to count as a long press).

  • max_multi_press (int) – Sets max_multi_press (the maximum amount of presses a multi-press can have).

enable_multi_press: bool = enable_multi_press = True

Whether to account for the possibility of another short press following a short press and counting as a multi-press. If set to false, ButtonHandler.update() returns a short press ButtonInput object immediately after a short press.

long_press_threshold: float = long_press_threshold = 1000

The minimum length of a press to count as a long press, and the time the button should be pressed before counting as being held down.

max_multi_press: int = max_multi_press = 2

The maximum amount of button presses that a multi-press can be. ButtonHandler.update() returns the appropriate multi-press ButtonInput object immediaetly after the button has been pressed this many times.

multi_press_interval: float = multi_press_interval = 175

The time frame from a button release within which another release should occur to count as a multi-press.

class button_handler.ButtonInput(action: int | str, button_number: int = 0, callback: Callable[[], None] = lambda : ..., timestamp: int = 0)

Defines a button’s input’s characteristics.

Parameters:
  • action (InputAction) – Sets action (the action associated with the input).

  • button_number (int) – Sets button_number (the number of the button associated with the input).

  • callback (Callable[[], None]) – Sets callback (the callback associated with the input).

  • timestamp (int) – Sets timestamp (the time at which the input was performed).

type InputAction = int | str

Represents the action the ButtonInput object represents. Using a constant defined by ButtonInput when available is recommended. To represent a multi-press, use the number of presses in that multi-press. Available constants are SHORT_PRESS, DOUBLE_PRESS, HOLD and LONG_PRESS.

button_number: int = 0

The index number of the button associated with the input.

callback: Callable[[], None] = lambda: None

The function to call when the input is detected and returned by ButtonHandler.update().

timestamp: int = 0

The timestamp (in milliseconds, provided by supervisor.ticks_ms()) at which the input was performed.

Warning

Variables written in upper case with underscores are constants and should not be modified. Doing so may cause unexpected behaviour.

SHORT_PRESS: int = 1

Represents a short press to pass as an argument to parameter action in ButtonInput.

DOUBLE_PRESS: int = 2

Represents a double press to pass as an argument to parameter action in ButtonInput.

HOLD: str = "H"

Represents a hold action to pass as an argument to parameter action in ButtonInput.

LONG_PRESS: str = "L"

Represents a long press to pass as an argument to parameter action in ButtonInput.

Caution

Attributes with a leading underscore (_) are meant for internal use only, and accessing them may cause unexpected behaviour. Please consider accessing a property (if available) instead.

_action: InputAction = action

The action associated with the input. Consider accessing action instead.

__eq__(other: object) bool

Note

This method defines the functionality of the equality operator (==). Consider using it instead.

Return whether two ButtonInput objects are the same. True if both action and button_number are the same in both objects.

Parameters:

other (object) – The object to compare the input to.

Returns:

Whether the two objects are the same.

Return type:

bool

__hash__() int

Note

This method is called by hash(). Consider using it instead.

Hash a ButtonInput object to an int.

Returns:

The hash value of the input.

Return type:

int

See also

__eq__() — two ButtonInput objects hash to the same value if they are equal.

__str__() str

Note

This method is called by str(). Consider using it instead.

Return a concise string representaton of the ButtonInput object.

Returns:

The string representation.

Return type:

str

property action

The action associated with the input.

Type:

InputAction

Parameters:

action (InputAction) – The action associated with the input.

Raises:

ValueError – if action is not a valid action. Valid actions are SHORT_PRESS, DOUBLE_PRESS, HOLD, LONG_PRESS and any int bigger than 0.

button_handler.timestamp_diff(time1: int, time2: int) int

Compute the difference between two ticks values, assuming that they are within 228 ticks.

Parameters:
  • time1 (int) – The minuend of the time difference, in milliseconds.

  • time2 (int) – The subtrahend of the time difference, in milliseconds.

Return int:

The difference between the two ticks values, in milliseconds.