@@ -173,35 +173,33 @@ def __init__(self, rowpins, colpins, *, buffer=bytearray(10), db_delay=50):
173
173
super ().__init__ (buffer )
174
174
self .rowpins = rowpins
175
175
self .colpins = colpins
176
- self .db_delay = db_delay # Deounce delay in ms
177
- self ._state = 0 # State of all keys as bit array
176
+ self ._state = 0 # State of all keys as bitmap
178
177
for opin in self .rowpins : # Initialise output pins
179
178
opin (0 )
180
- asyncio .create_task (self .scan (len ( rowpins ) * len ( colpins ) ))
179
+ asyncio .create_task (self .scan (db_delay ))
181
180
182
181
def __getitem__ (self , scan_code ):
183
182
return bool (self ._state & (1 << scan_code ))
184
183
185
- async def scan (self , nbuttons ):
184
+ async def scan (self , db_delay ):
186
185
while True :
187
- await asyncio .sleep_ms (0 )
188
- cur = 0
186
+ cur = 0 # Current bitmap of key states
189
187
for opin in self .rowpins :
190
188
opin (1 ) # Assert output
191
189
for ipin in self .colpins :
192
190
cur <<= 1
193
191
cur |= ipin ()
194
192
opin (0 )
195
- if cur != self ._state : # State change
196
- pressed = cur & ~ self . _state
197
- self . _state = cur
198
- if pressed : # Ignore button release
199
- for v in range ( nbuttons ): # Find button index
200
- if pressed & 1 :
201
- break
202
- pressed >>= 1
203
- try :
204
- self . put_nowait ( v )
205
- except IndexError : # q full. Overwrite oldest
206
- pass
207
- await asyncio .sleep_ms (self . db_delay ) # Wait out bounce
193
+ pressed = cur & ~ self ._state # Newly pressed
194
+ if pressed : # There is a newly pressed button
195
+ sc = 0 # Find its scan code
196
+ while not pressed & 1 :
197
+ pressed >>= 1
198
+ sc += 1
199
+ try :
200
+ self . put_nowait ( sc )
201
+ except IndexError : # q full. Overwrite oldest
202
+ pass
203
+ changed = cur ^ self . _state # Any new press or release
204
+ self . _state = cur
205
+ await asyncio .sleep_ms (db_delay if changed else 0 ) # Wait out bounce
0 commit comments