Raw rotary encoder support
This commit is contained in:
parent
3b0cd6c421
commit
e2c9567bbf
57
kmk/common/rotary_encoder.py
Normal file
57
kmk/common/rotary_encoder.py
Normal file
@ -0,0 +1,57 @@
|
||||
from kmk.common.pins import PULL_UP
|
||||
|
||||
|
||||
class RotaryEncoder:
|
||||
# Please don't ask. I don't know. All I know is bit_value
|
||||
# works as expected. Here be dragons, etc. etc.
|
||||
MIN_VALUE = False + 1 << 1 | True + 1
|
||||
MAX_VALUE = True + 1 << 1 | True + 1
|
||||
|
||||
def __init__(self, pos_pin, neg_pin):
|
||||
self.pos_pin = pos_pin
|
||||
self.neg_pin = neg_pin
|
||||
|
||||
self.pos_pin.switch_to_input(pull=PULL_UP)
|
||||
self.neg_pin.switch_to_input(pull=PULL_UP)
|
||||
|
||||
self.prev_bit_value = self.bit_value()
|
||||
|
||||
def value(self):
|
||||
return (self.pos_pin.value(), self.neg_pin.value())
|
||||
|
||||
def bit_value(self):
|
||||
'''
|
||||
Returns 2, 3, 5, or 6 based on the state of the rotary encoder's two
|
||||
bits. This is a total hack but it does what we need pretty efficiently.
|
||||
Shrug.
|
||||
'''
|
||||
return self.pos_pin.value() + 1 << 1 | self.neg_pin.value() + 1
|
||||
|
||||
def direction(self):
|
||||
'''
|
||||
Compares the current rotary position against the last seen position.
|
||||
|
||||
Returns True if we're rotating "positively", False if we're rotating "negatively",
|
||||
and None if no change could safely be detected for any reason (usually this
|
||||
means the encoder itself did not change)
|
||||
'''
|
||||
new_value = self.bit_value()
|
||||
rolling_under = self.prev_bit_value == self.MIN_VALUE and new_value == self.MAX_VALUE
|
||||
rolling_over = self.prev_bit_value == self.MAX_VALUE and new_value == self.MIN_VALUE
|
||||
increasing = new_value > self.prev_bit_value
|
||||
decreasing = new_value < self.prev_bit_value
|
||||
self.prev_bit_value = new_value
|
||||
|
||||
if rolling_over:
|
||||
return True
|
||||
elif rolling_under:
|
||||
return False
|
||||
|
||||
if increasing:
|
||||
return True
|
||||
if decreasing:
|
||||
return False
|
||||
|
||||
# Either no change, or not a type of change we can safely detect,
|
||||
# so safely do nothing
|
||||
return None
|
Loading…
x
Reference in New Issue
Block a user