Scanning Interval and Debouncing
By default, all the scanners in the keypad
module scan their inputs at 20 millisecond intervals. This is enough time to debounce most mechanical keys, which can take quite a few milliseconds to settle down. If you have keys that need more (or less) debouncing, you can set the optional interval
parameter when you create a scanner. The interval
is given in floating-point seconds. For example:
# SPDX-FileCopyrightText: 2022 Dan Halbert for Adafruit Industries # # SPDX-License-Identifier: MIT import keypad import board km = keypad.KeyMatrix( row_pins=(board.A0, board.A1, board.A2, board.A3), column_pins=(board.D0, board.D1, board.D2), # Allow 50 msecs to debounce. interval=0.050, ) while True: event = km.events.get() if event: print(event)
Queue Size and Queue Overflow
The EventQueue
for each scanner is of fixed size. The default size is 64 events. You can change this value by setting the optional max_events
parameter:
# SPDX-FileCopyrightText: 2022 Dan Halbert for Adafruit Industries # # SPDX-License-Identifier: MIT import keypad import board k = keypad.Keys( (board.D8, board.D9), value_when_pressed=False, pull=True, # Increase event queue size to 128 events. max_events=128, ) while True: event = k.events.get() if event: print(event)
If your program doesn't keep up while reading events, the event queue can become full. New events will be discarded. If this happens, the EventQueue.overflowed
property is set to True
on the event queue. You can clear the event queue with the EventQueue.clear()
method; that also sets the overflowed
flag to False
. Since you have lost events, you probably also want to forget the existing state of the keys and start over. you can do that by calling reset()
on the scanner. scanner.reset()
clears any key-pressed information, so it will immediately generate key-pressed events for any keys that were pressed at the time you reset. For example:
# SPDX-FileCopyrightText: 2022 Dan Halbert for Adafruit Industries # # SPDX-License-Identifier: MIT import keypad import board k = keypad.Keys( (board.D8, board.D9), value_when_pressed=False, pull=True, ) while True: # Check if we lost some events. if k.events.overflowed: k.events.clear() # Empty the event queue. k.reset() # Forget any existing presses. Start over. event = k.events.get() if event: print(event)
You don't have to check for queue overflow. For most programs, it will never happen, or it's not important if it happens: the user will adjust.
Avoiding Storage Allocation
EventQueue.get()
creates a new Event
every time it returns an event. These Events probably become unused quite quickly, and add to the "garbage" that must be collected periodically. You can avoid generating new Event
objects each time by using the EventQueue.get_into(event)
method, which writes into an existing Event
. It returns True
if it wrote into the Event
, and False
otherwise (when EventQueue.get()
would have returned None
).
Here's an example of using get_into()
:
# SPDX-FileCopyrightText: 2022 Dan Halbert for Adafruit Industries # # SPDX-License-Identifier: MIT import board import keypad keys = keypad.Keys((board.D8,), value_when_pressed=False, pull=True) # Create an event we will reuse over and over. event = keypad.Event() while True: if keys.events.get_into(event): print(event)
Comparing Events and Using Events as Dictionary Keys
Event implements __eq__()
and __hash__()
, so you can test if two Events are equivalent, and you can store them in a dictionary. For example, here's a program that translates button pushes on pins D8 and D9 into the strings "LEFT"
and "RIGHT"
. And if you push the button on D10, the program stops.
# SPDX-FileCopyrightText: 2022 Dan Halbert for Adafruit Industries # # SPDX-License-Identifier: MIT import board from keypad import Keys, Event keys = Keys((board.D8, board.D9, board.D10), value_when_pressed=False, pull=True) LEFT_EVENT = Event(0, True) # Button 0 (D8) pressed RIGHT_EVENT = Event(1, True) # Button 1 (D9) pressed STOP_EVENT = Event(2, True) # Button 2 (D10) pressed DIRECTION = { LEFT_EVENT: "LEFT", RIGHT_EVENT: "RIGHT", } while True: event = keys.events.get() if event: if event == STOP_EVENT: print("stop") break # Look up the event. If not found, direction is None. direction = DIRECTION.get(event) if direction: print(direction)
Text editor powered by tinymce.