@@ -133,75 +133,89 @@ def current_duration(self):
133
133
134
134
135
135
class Button (Debouncer ):
136
- """Debounce counter"""
136
+ """
137
+ Debouncer for buttons. Reports ``pressed`` and ``released`` for the button state.
138
+ Counts multiple short presses, allowing to detect double clicks, triple clicks, etc.
139
+ Reports long presses separately. A long press can immediately follow multiple clicks,
140
+ in which case the long click will be reported in the same update as the short clicks.
141
+
142
+ :param DigitalInOut/function pin: the DigitalIO or function to debounce.
143
+ :param int short_duration_ms: the maximum length of a short press in milliseconds.
144
+ :param int long_duration_ms: the minimum length of a long press in milliseconds.
145
+ :param bool value_when_pressed: the value of the predicate when the button is
146
+ pressed. Defaults to False (for pull up buttons).
147
+ """
137
148
138
149
def __init__ (
139
150
self ,
140
151
pin ,
141
152
short_duration_ms = 200 ,
142
153
long_duration_ms = 500 ,
143
- active_down = True ,
154
+ value_when_pressed = False ,
144
155
** kwargs
145
156
):
146
157
self .short_duration_ms = short_duration_ms
147
158
self .long_duration_ms = long_duration_ms
148
- self .active_down = active_down
159
+ self .value_when_pressed = value_when_pressed
149
160
self .last_change_ms = ticks_ms ()
150
161
self .short_counter = 0
151
162
self .short_to_show = 0
152
163
self .long_registered = False
153
- self .long_showed = False
164
+ self .long_to_show = False
154
165
super ().__init__ (pin , ** kwargs )
155
166
156
- def _pushed (self ):
157
- return (self .active_down and super ().fell ) or (
158
- not self .active_down and super ().rose
167
+ @property
168
+ def pressed (self ):
169
+ """Return whether the button was pressed or not at the last update."""
170
+ return (self .value_when_pressed and self .rose ) or (
171
+ not self .value_when_pressed and self .fell
159
172
)
160
173
161
- def _released (self ):
162
- return (self .active_down and super ().rose ) or (
163
- not self .active_down and super ().fell
174
+ @property
175
+ def released (self ):
176
+ """Return whether the button was release or not at the last update."""
177
+ return (self .value_when_pressed and self .fell ) or (
178
+ not self .value_when_pressed and self .rose
164
179
)
165
180
166
181
def update (self , new_state = None ):
167
182
super ().update (new_state )
168
- if self ._pushed () :
183
+ if self .pressed :
169
184
self .last_change_ms = ticks_ms ()
170
185
self .short_counter = self .short_counter + 1
171
- elif self ._released () :
186
+ elif self .released :
172
187
self .last_change_ms = ticks_ms ()
173
188
if self .long_registered :
174
189
self .long_registered = False
175
- self .long_showed = False
176
190
else :
177
191
duration = ticks_diff (ticks_ms (), self .last_change_ms )
178
192
if (
179
193
not self .long_registered
180
- and self .value != self .active_down
194
+ and self .value == self .value_when_pressed
181
195
and duration > self .long_duration_ms
182
196
):
183
197
self .long_registered = True
198
+ self .long_to_show = True
184
199
self .short_to_show = self .short_counter - 1
185
200
self .short_counter = 0
186
201
elif (
187
202
self .short_counter > 0
188
- and self .value == self .active_down
203
+ and self .value != self .value_when_pressed
189
204
and duration > self .short_duration_ms
190
205
):
191
206
self .short_to_show = self .short_counter
192
207
self .short_counter = 0
208
+ else :
209
+ self .long_to_show = False
210
+ self .short_to_show = 0
193
211
194
212
@property
195
213
def short_count (self ):
196
- """Return the number of short press"""
197
- ret = self .short_to_show
198
- self .short_to_show = 0
199
- return ret
214
+ """Return the number of short press if a series of short presses has
215
+ ended at the last update."""
216
+ return self .short_to_show
200
217
201
218
@property
202
219
def long_press (self ):
203
- """Return whether long press has occured"""
204
- if self .long_registered and not self .long_showed :
205
- self .long_showed = True
206
- return True
207
- return False
220
+ """Return whether a long press has occured at the last update."""
221
+ return self .long_to_show
0 commit comments