Skip to content

Commit 859360b

Browse files
committed
DRIVERS.md: Changes offered by @bai-yi-bai.
1 parent b94be59 commit 859360b

File tree

1 file changed

+63
-34
lines changed

1 file changed

+63
-34
lines changed

v3/docs/DRIVERS.md

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ goes outside defined bounds.
2020
2. [Installation and usage](./DRIVERS.md#2-installation-and-usage)
2121
3. [Interfacing switches](./DRIVERS.md#3-interfacing-switches) Switch debouncer with callbacks.
2222
3.1 [Switch class](./DRIVERS.md#31-switch-class)
23-
4. [Interfacing pushbuttons](./DRIVERS.md#4-interfacing-pushbuttons) Extends Switch for long and double click events
23+
4. [Interfacing pushbuttons](./DRIVERS.md#4-interfacing-pushbuttons) Extends Switch for long and double-click events
2424
4.1 [Pushbutton class](./DRIVERS.md#41-pushbutton-class)
2525
     4.1.1 [The suppress constructor argument](./DRIVERS.md#411-the-suppress-constructor-argument)
2626
     4.1.2 [The sense constructor argument](./DRIVERS.md#412-the-sense-constructor-argument)
@@ -131,10 +131,18 @@ asyncio.run(my_app()) # Run main application code
131131

132132
# 4. Interfacing pushbuttons
133133

134-
The `primitives.pushbutton` module provides the `Pushbutton` class. This is a
135-
generalisation of `Switch` to support normally open or normally closed switches
136-
connected to ground or 3V3. Can run a `callable` on on press, release,
137-
double-click or long press events.
134+
The `primitives.pushbutton` module provides the `Pushbutton` class for use with
135+
simple mechanical, spring-loaded push buttons. This class is a generalisation
136+
of the `Switch` class. `Pushbutton` supports open or normally closed buttons
137+
connected to ground or 3V3. To a human, pushing a button is seen as a single
138+
event, but the micro-controller sees voltage changes corresponding to two
139+
events: press and release. A long button press adds the component of time and a
140+
double-click appears as four voltage changes. The asynchronous `Pushbutton`
141+
class provides the logic required to handle these user interactions by
142+
monitoring these events over time.
143+
144+
Instances of this class can run a `callable` on on press, release, double-click
145+
or long press events.
138146

139147
## 4.1 Pushbutton class
140148

@@ -183,8 +191,9 @@ any existing callback will be disabled.
183191
Class attributes:
184192
1. `debounce_ms` Debounce time in ms. Default 50.
185193
2. `long_press_ms` Threshold time in ms for a long press. Default 1000.
186-
3. `double_click_ms` Threshold time in ms for a double click. Default 400.
194+
3. `double_click_ms` Threshold time in ms for a double-click. Default 400.
187195

196+
A simple Pyboard demo:
188197
```python
189198
from pyb import LED
190199
from machine import Pin
@@ -211,42 +220,62 @@ number of coroutines.
211220

212221
### 4.1.1 The suppress constructor argument
213222

214-
When the button is pressed `press_func` runs immediately. This minimal latency
215-
is ideal for applications such as games. Consider a long press: `press_func`
216-
runs initially, then `long_func`, and finally `release_func`. In the case of a
217-
double-click `press_func` and `release_func` will run twice; `double_func` runs
218-
once.
219-
220-
There can be a need for a `callable` which runs if a button is pressed but
221-
only if a doubleclick or long press function does not run. The `suppress` arg
222-
changes the behaviour of `release_func` to fill that role. This has timing
223-
implications.
224-
225-
The soonest that the absence of a long press can be detected is on button
226-
release. Absence of a double click can only be detected when the double click
227-
timer times out without a second press occurring.
228-
229-
Note `suppress` affects the behaviour of `release_func` only. Other callbacks
230-
including `press_func` behave normally.
231-
232-
If the `suppress` constructor arg is set, `release_func` will be launched as
233-
follows:
234-
1. If `double_func` does not exist on rapid button release.
235-
2. If `double_func` exists, after the expiration of the doubleclick timer.
236-
3. If `long_func` exists and the press duration causes `long_func` to be
223+
The purpose of the `suppress` argument is to disambiguate the response when an
224+
application requires either, or both, long-press and double-click events. It
225+
works by modifying the behavior of the `release_func`. By design, whenever a
226+
button is pressed, the `press_func` runs immediately. This minimal latency is
227+
ideal for applications such as games. The `Pushbutton` class provides the
228+
ability to suppress 'intermediate' events and reduce them down to one single
229+
event. The `suppress` argument is useful for applications where long-press,
230+
single-press, and double-click events are desired, such as clocks, watches, or
231+
menu navigation. However, long-press and double-click detection introduces
232+
additional latency to ensure correct classification of events and is therefore
233+
not suitable for all applications. To illustrate the default library behavior,
234+
consider how long button presses and double-clicks are interpreted.
235+
236+
A long press is seen as three events:
237+
238+
* `press_func`
239+
* `long_func`
240+
* `release_func`
241+
242+
Similarly, a double-click is seen as five events:
243+
244+
* `press_func`
245+
* `release_func`
246+
* `press_func`
247+
* `release_func`
248+
* `double_func`
249+
250+
There can be a need for a callable which runs if a button is pressed, but only
251+
if a double-click or long-press function does not run. The suppress argument
252+
changes the behaviour of the `release_func` to fill that role. This has timing
253+
implications. The soonest that the absence of a long press can be detected is
254+
on button release. Absence of a double-click can only be detected when the
255+
double-click timer times out without a second press occurring.
256+
257+
Note: `suppress` affects the behaviour of the `release_func` only. Other
258+
callbacks including `press_func` behave normally.
259+
260+
If the `suppress = True` constructor argument is set, the `release_func` will
261+
be launched as follows:
262+
263+
* If `double_func` does not exist on rapid button release.
264+
* If `double_func` exists, after the expiration of the double-click timer.
265+
* If `long_func` exists and the press duration causes `long_func` to be
237266
launched, `release_func` will not be launched.
238-
4. If `double_func` exists and a double click occurs, `release_func` will not
267+
* If `double_func` exists and a double-click occurs, `release_func` will not
239268
be launched.
240269

241270
In the typical case where `long_func` and `double_func` are both defined, this
242271
ensures that only one of `long_func`, `double_func` and `release_func` run. In
243-
the case of a single short press, `release_func` will be delayed until the
272+
the case of a single short press, the `release_func` will be delayed until the
244273
expiry of the double-click timer (because until that time a second click might
245274
occur).
246275

247-
The following script may be used to demonstrate the effect of this arg. As
248-
written it assumes a Pi Pico with a pushbutton between GPIO 18 and Gnd, with
249-
the primitives installed.
276+
The following script may be used to demonstrate the effect of this argument. As
277+
written, it assumes a Pi Pico with a push button attached between GPIO 18 and
278+
Gnd, with the primitives installed.
250279
```python
251280
from machine import Pin
252281
import uasyncio as asyncio

0 commit comments

Comments
 (0)