95 lines
2.5 KiB
Python
95 lines
2.5 KiB
Python
from analogio import AnalogIn
|
|
from supervisor import ticks_ms
|
|
|
|
from kmk.modules import Module
|
|
|
|
|
|
class PotentiometerState:
|
|
def __init__(self, direction: int, position: int):
|
|
self.direction = direction
|
|
self.position = position
|
|
|
|
|
|
class Potentiometer:
|
|
def __init__(self, pin, move_callback, is_inverted=False):
|
|
self.is_inverted = is_inverted
|
|
self.read_pin = AnalogIn(pin)
|
|
self._direction = None
|
|
self._pos = self.get_pos()
|
|
self._timestamp = ticks_ms()
|
|
self.cb = move_callback
|
|
|
|
# callback function on events.
|
|
self.on_move_do = lambda state: self.cb(state)
|
|
|
|
def get_state(self) -> PotentiometerState:
|
|
return PotentiometerState(
|
|
direction=(self.is_inverted and -self._direction or self._direction),
|
|
position=(self.is_inverted and -self._pos or self._pos),
|
|
)
|
|
|
|
def get_pos(self):
|
|
'''
|
|
Read from the analog pin assingned, truncate to 7 bits,
|
|
average over 10 readings, and return a value 0-127
|
|
'''
|
|
return int(sum([(self.read_pin.value >> 9) for i in range(10)]) / 10)
|
|
|
|
def update_state(self):
|
|
self._direction = 0
|
|
new_pos = self.get_pos()
|
|
if abs(new_pos - self._pos) > 2:
|
|
# movement detected!
|
|
if new_pos > self._pos:
|
|
self._direction = 1
|
|
else:
|
|
self._direction = -1
|
|
self._pos = new_pos
|
|
if self.on_move_do is not None:
|
|
self.on_move_do(self.get_state())
|
|
|
|
|
|
class PotentiometerHandler(Module):
|
|
def __init__(self):
|
|
self.potentiometers = []
|
|
self.pins = None
|
|
|
|
def on_runtime_enable(self, keyboard):
|
|
return
|
|
|
|
def on_runtime_disable(self, keyboard):
|
|
return
|
|
|
|
def during_bootup(self, keyboard):
|
|
if self.pins:
|
|
for args in self.pins:
|
|
self.potentiometers.append(Potentiometer(*args))
|
|
return
|
|
|
|
def before_matrix_scan(self, keyboard):
|
|
'''
|
|
Return value will be injected as an extra matrix update
|
|
'''
|
|
for potentiometer in self.potentiometers:
|
|
potentiometer.update_state()
|
|
|
|
return keyboard
|
|
|
|
def after_matrix_scan(self, keyboard):
|
|
'''
|
|
Return value will be replace matrix update if supplied
|
|
'''
|
|
return
|
|
|
|
def before_hid_send(self, keyboard):
|
|
return
|
|
|
|
def after_hid_send(self, keyboard):
|
|
return
|
|
|
|
def on_powersave_enable(self, keyboard):
|
|
return
|
|
|
|
def on_powersave_disable(self, keyboard):
|
|
return
|