@@ -20,7 +20,7 @@ goes outside defined bounds.
20
20
2 . [ Installation and usage] ( ./DRIVERS.md#2-installation-and-usage )
21
21
3 . [ Interfacing switches] ( ./DRIVERS.md#3-interfacing-switches ) Switch debouncer with callbacks.
22
22
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
24
24
4.1 [ Pushbutton class] ( ./DRIVERS.md#41-pushbutton-class )
25
25
  ;  ;  ;  ;  ; 4.1.1 [ The suppress constructor argument] ( ./DRIVERS.md#411-the-suppress-constructor-argument )
26
26
  ;  ;  ;  ;  ; 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
131
131
132
132
# 4. Interfacing pushbuttons
133
133
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.
138
146
139
147
## 4.1 Pushbutton class
140
148
@@ -183,8 +191,9 @@ any existing callback will be disabled.
183
191
Class attributes:
184
192
1 . ` debounce_ms ` Debounce time in ms. Default 50.
185
193
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.
187
195
196
+ A simple Pyboard demo:
188
197
``` python
189
198
from pyb import LED
190
199
from machine import Pin
@@ -211,42 +220,62 @@ number of coroutines.
211
220
212
221
### 4.1.1 The suppress constructor argument
213
222
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
237
266
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
239
268
be launched.
240
269
241
270
In the typical case where ` long_func ` and ` double_func ` are both defined, this
242
271
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
244
273
expiry of the double-click timer (because until that time a second click might
245
274
occur).
246
275
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.
250
279
``` python
251
280
from machine import Pin
252
281
import uasyncio as asyncio
0 commit comments