API Reference¶
chumicro_buttons.core¶
Button reads one momentary button or switch: a debounced level, the edges either side of it, and the durations built on top (long press, auto-repeat, click counting). Buttons reads several keys on one scan and hands you each as a Button.
chumicro_buttons.core
¶
Buttons and switches: debounced level, edges, long press, repeat, and click counting.
Button
¶
One momentary button or switch, read as a debounced level plus what it meant.
Every reading is a plain attribute refreshed by check(now_ms), and the just_ family
is true only for the tick the thing happened on, so a loop can read them without consuming
anything. A switch that stays where you put it uses the same object, reading pressed
and watching the edges for when it moved. Constructing with pin builds the runtime's
own source, a firmware keypad scan on CircuitPython and a capture interrupt on
MicroPython, and both catch a tap that starts and ends between two passes of your loop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pin
|
object | None
|
Runtime pin object for the key, or None when a parent drives this button. |
None
|
ticks
|
object
|
The clock every duration here is judged by, |
required |
source
|
object | None
|
Pre-built edge source; overrides |
None
|
active_low
|
bool
|
True when a pressed key reads low. True suits a button wired to ground with the internal pull-up enabled, which is nearly always the wiring. |
True
|
settle_ms
|
int
|
Debounce window in milliseconds, and the shortest press that can be reported. Raise it for a switch that bounces badly, lower it for fast tapping, and use zero for a button with hardware debouncing behind it. |
DEFAULT_SETTLE_MS
|
long_press_ms
|
int
|
Hold time that fires |
DEFAULT_LONG_PRESS_MS
|
repeat_ms
|
int
|
Interval between |
0
|
repeat_delay_ms
|
int
|
Hold time before repeat starts. |
DEFAULT_REPEAT_DELAY_MS
|
click_ms
|
int
|
Quiet time after a release that closes a click series and publishes
|
0
|
check(now_ms)
¶
Drain captured edges and advance the timers by one tick.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
now_ms
|
int
|
Tick this pass of the loop is measured from. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True when anything happened, so a quiet tick can skip |
handle(now_ms)
¶
Call whichever callbacks this tick's readings earned.
next_deadline(now_ms)
¶
Return the earliest tick a timer here fires at, or None while none is armed.
The runner reads this before it sleeps, so a long press, an auto-repeat, or a click window fires on time instead of at the next unrelated wake. A press is a pin edge rather than a timer, so no deadline can name one; an edge that lands mid-sleep is captured with its real timestamp and reported at the next tick.
deinit()
¶
Release the pins and any interrupt the source installed.
Buttons
¶
Several keys on one source, ticked together and read one key at a time.
buttons[0] is a :class:Button carrying that key's readings and its own callbacks, and
the whole-panel callbacks take the key number instead. On CircuitPython this is one
firmware keypad scan across all the pins rather than one per key, which is both cheaper
and what makes chords land on the same tick.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pins
|
object | None
|
Runtime pin objects, one per key. |
None
|
ticks
|
object
|
The clock every duration here is judged by, |
required |
source
|
object | None
|
Pre-built edge source; overrides |
None
|
active_low
|
bool
|
True when a pressed key reads low. |
True
|
settle_ms
|
int
|
Debounce window in milliseconds; 0 trusts the signal. |
DEFAULT_SETTLE_MS
|
long_press_ms
|
int
|
Hold time that fires |
DEFAULT_LONG_PRESS_MS
|
repeat_ms
|
int
|
Interval between repeat fires while held. Zero disables it. |
0
|
repeat_delay_ms
|
int
|
Hold time before repeat starts. |
DEFAULT_REPEAT_DELAY_MS
|
click_ms
|
int
|
Quiet time that closes a click series. Zero disables click counting. |
0
|
check(now_ms)
¶
Drain captured edges into every key and advance their timers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
now_ms
|
int
|
Tick this pass of the loop is measured from. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True when any key produced news this tick, so a quiet tick can skip |
handle(now_ms)
¶
Call the per-key callbacks, then the whole-panel ones.
next_deadline(now_ms)
¶
Return the earliest tick any key's timer fires at, or None while none is armed.
deinit()
¶
Release the pins and any interrupt the source installed.
__len__()
¶
Return how many keys this panel reads.
__getitem__(key_index)
¶
Return the :class:Button for key_index.
chumicro_buttons.matrix¶
KeyMatrix reads a keypad wired as rows by columns. Keys are numbered row-major and carry the same readings and callbacks as any other button.
chumicro_buttons.matrix
¶
A keypad wired as rows by columns, read as the same buttons everything else reads.
KeyMatrix
¶
Bases: Buttons
A keypad whose keys sit where a row crosses a column, read one key at a time.
Wiring keys as a grid is what lets twelve of them share seven pins, and every key still
reads as an ordinary button: matrix[5] is a :class:~chumicro_buttons.core.Button with
its own pressed, its own edges, and its own long press, repeat, and click counting.
Keys are numbered row-major, so the key at row, column is
row * len(column_pins) + column, and with three columns key 4 is row 1, column 1.
CircuitPython drives the grid in the firmware's own background scan; MicroPython drives it
once per check(now_ms), because a grid has to be scanned a row at a time and column
interrupts would report keys nobody touched.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
row_pins
|
object | None
|
Runtime pin objects for the rows. |
None
|
column_pins
|
object | None
|
Runtime pin objects for the columns. |
None
|
ticks
|
object
|
The clock every duration here is judged by, |
required |
source
|
object | None
|
Pre-built edge source; overrides the pins. Tests inject a fake here. |
None
|
columns_to_anodes
|
bool
|
Which way the matrix's diodes face. Leave it True when each diode's striped end points at a row pin, which is how ready-made keypads are built. Guessing wrong is quiet rather than damaging: the diodes block the scan and no key ever reads as pressed, so a keypad that reports nothing is the symptom to try it on. |
True
|
settle_ms
|
int
|
Debounce window in milliseconds; 0 trusts the signal. |
DEFAULT_SETTLE_MS
|
long_press_ms
|
int
|
Hold time that fires |
DEFAULT_LONG_PRESS_MS
|
repeat_ms
|
int
|
Interval between repeat fires while held. Zero disables it. |
0
|
repeat_delay_ms
|
int
|
Hold time before repeat starts. |
DEFAULT_REPEAT_DELAY_MS
|
click_ms
|
int
|
Quiet time that closes a click series. Zero disables click counting. |
0
|
chumicro_buttons.testing¶
FakeButtonSource stands in for the hardware so button logic can be tested on a host. Queue the edges, tick the button, assert on what it made of them.
chumicro_buttons.testing
¶
Test-support helpers: a hand-driven :class:FakeButtonSource.
FakeButtonSource
¶
Edge source a test drives by hand instead of by hardware.
Queue the edges you want the button to see, then tick the button. Each edge carries its own timestamp, which is how a test exercises the case that matters on a real board: an edge captured earlier than the tick that noticed it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key_count
|
int
|
How many keys this source reports. |
1
|
press(key_index=0, at_ms=0)
¶
Queue a press edge for key_index stamped at at_ms.
release(key_index=0, at_ms=0)
¶
Queue a release edge for key_index stamped at at_ms.
poll(now_ms)
¶
Record that a capture step was asked for; the queue is filled by the test.
next_event()
¶
Advance to the next queued edge, or report the queue drained.
deinit()
¶
Record that the button released this source.