Skip to content

Commit

Permalink
Added extra construction support to Encoder.py to support pullup dire…
Browse files Browse the repository at this point in the history
…ction from Code.py (#891)

* Added support to Encoder.py to allow GPIOEncoder to accept tuple for pin_button construction.  This includes allowance for pull resistor (pullup/pulldown) customisation directly from code.py.  Additionally the change preserves state generation semantics for pin_button.get_value(self) and depends upon the pull direction.  The default pull direction remains as digitalio.Pull.UP

* Replaced multiline ternary/conditional expression with a regular If statement for EncoderPin.get_value() as suggested in review

* Prior commit failed test. Audio Mute was assigned to the encoder push button action and was activating upon keyboard USB insertion without user interaction. Fixed this error.

* Implemented the reviewer suggestion for the GPIO constructor to take in an additional optional  argument defaulting to Pull.UP instead of overloading the  argument with a tuple.  This is tested, and documented in English

* Fix formatting encoder.py

---------

Co-authored-by: Gordon Jamieson <[email protected]>
Co-authored-by: xs5871 <[email protected]>
  • Loading branch information
3 people authored Oct 18, 2023
1 parent 2e2c276 commit 4df8a9d
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
4 changes: 2 additions & 2 deletions docs/en/encoder.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ encoder_handler = EncoderHandler()
keyboard.modules = [layers, holdtap, encoder_handler]
```

2. Define the pins for each encoder: `pin_a`, `pin_b` for rotations, `pin_button` for the switch in the encoder. Set switch to `None` if the encoder's button is handled differently (as a part of matrix for example) or not at all. If you want to invert the direction of the encoder, set the 4th (optional) parameter `is_inverted` to `True`. 5th parameter is [encoder divisor](#encoder-resolution) (optional), it can be either `2` or `4`.
2. Define the pins for each encoder: `pin_a`, `pin_b` for rotations, `pin_button` for the switch in the encoder. Set switch to `None` if the encoder's button is handled differently (as a part of matrix for example) or not at all. If you want to invert the direction of the encoder, set the 4th (optional) parameter `is_inverted` to `True`. 5th parameter is [encoder divisor](#encoder-resolution) (optional), it can be either `2` or `4`. If your encoder button pull direction is not the default of `digitalio.Pull.UP`, you may specify the 6th (optional) parameter `button_pull` as `digitalio.Pull.DOWN`.

```python
# Regular GPIO Encoder
encoder_handler.pins = (
Expand Down
28 changes: 21 additions & 7 deletions kmk/modules/encoder.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,15 @@ def vel_report(self):


class GPIOEncoder(BaseEncoder):
def __init__(self, pin_a, pin_b, pin_button=None, is_inverted=False, divisor=None):
def __init__(
self,
pin_a,
pin_b,
pin_button=None,
is_inverted=False,
divisor=None,
button_pull=digitalio.Pull.UP,
):
super().__init__(is_inverted)

# Divisor can be 4 or 2 depending on whether the detent
Expand All @@ -121,9 +129,10 @@ def __init__(self, pin_a, pin_b, pin_button=None, is_inverted=False, divisor=Non

self.pin_a = EncoderPin(pin_a)
self.pin_b = EncoderPin(pin_b)
self.pin_button = (
EncoderPin(pin_button, button_type=True) if pin_button is not None else None
)
if pin_button:
self.pin_button = EncoderPin(pin_button, button_type=True, pull=button_pull)
else:
self.pin_button = None

self._state = (self.pin_a.get_value(), self.pin_b.get_value())
self._start_state = self._state
Expand All @@ -138,9 +147,10 @@ def button_event(self):


class EncoderPin:
def __init__(self, pin, button_type=False):
def __init__(self, pin, button_type=False, pull=digitalio.Pull.UP):
self.pin = pin
self.button_type = button_type
self.pull = pull
self.prepare_pin()

def prepare_pin(self):
Expand All @@ -150,12 +160,16 @@ def prepare_pin(self):
else:
self.io = digitalio.DigitalInOut(self.pin)
self.io.direction = digitalio.Direction.INPUT
self.io.pull = digitalio.Pull.UP
self.io.pull = self.pull
else:
self.io = None

def get_value(self):
return self.io.value
io = self.io
result = io.value
if digitalio.Pull.UP != io.pull:
result = not result
return result


class I2CEncoder(BaseEncoder):
Expand Down

0 comments on commit 4df8a9d

Please sign in to comment.