From 1700aff408c5550c56bbcffc1d5d89d93f3fcb7d Mon Sep 17 00:00:00 2001 From: xs5871 Date: Sun, 17 Apr 2022 11:28:36 +0000 Subject: [PATCH] implements scanner with rotaryio --- docs/scanners.md | 23 ++++++++++++++++++++++ kmk/scanners/encoder.py | 43 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 kmk/scanners/encoder.py diff --git a/docs/scanners.md b/docs/scanners.md index 25a5c19..8fd14c8 100644 --- a/docs/scanners.md +++ b/docs/scanners.md @@ -99,6 +99,7 @@ class MyKeyboard(KMKKeyboard): ) ``` + ## Digitalio Scanners ### digitalio MatrixScanner @@ -120,6 +121,28 @@ class MyKeyboard(KMKKeyboard): ) ``` + +## Rotary Encoder Scanners + +### RotaryioEncoder + +Matrix events from a quadrature ("rotary") encoder? + +```python +from kmk.scanners.encoder import RotaryioEncoder + +class MyKeyboard(KMKKeyboard): + def __init__(self): + # create and register the scanner + self.matrix = RotaryioEncoder( + pin_a=board.GP0, + pin_b=board.GP1, + # optional + divisor=4, + ) +``` + + ## `Scanner` base class If you require a different type of scanner, you can create your own by diff --git a/kmk/scanners/encoder.py b/kmk/scanners/encoder.py new file mode 100644 index 0000000..301ebb6 --- /dev/null +++ b/kmk/scanners/encoder.py @@ -0,0 +1,43 @@ +import keypad +import rotaryio + +from kmk.scanners import Scanner + + +class RotaryioEncoder(Scanner): + def __init__(self, pin_a, pin_b, divisor=4): + self.encoder = rotaryio.IncrementalEncoder(pin_a, pin_b, divisor) + self.position = 0 + self._pressed = False + self._queue = [] + + @property + def key_count(self): + return 2 + + def scan_for_changes(self): + position = self.encoder.position + + if position != self.position: + self._queue.append(position - self.position) + self.position = position + + if not self._queue: + return + + key_number = self.offset + if self._queue[0] > 0: + key_number += 1 + + if self._pressed: + self._queue[0] -= 1 if self._queue[0] > 0 else -1 + + if self._queue[0] == 0: + self._queue.pop(0) + + self._pressed = False + + else: + self._pressed = True + + return keypad.Event(key_number, self._pressed)