Support a special form of macro based on rotary encoder directions

This commit is contained in:
Josh Klar 2018-10-11 02:31:45 -07:00
parent e2c9567bbf
commit 6589982eda
No known key found for this signature in database
GPG Key ID: 220F99BD7DB7A99E
4 changed files with 99 additions and 1 deletions

View File

@ -0,0 +1,76 @@
import math
from kmk.common.event_defs import (hid_report_event, keycode_down_event,
keycode_up_event)
from kmk.common.keycodes import Media
from kmk.common.rotary_encoder import RotaryEncoder
VAL_FALSE = False + 1
VAL_NONE = True + 2
VAL_TRUE = True + 1
VOL_UP_PRESS = keycode_down_event(Media.KC_AUDIO_VOL_UP)
VOL_UP_RELEASE = keycode_up_event(Media.KC_AUDIO_VOL_UP)
VOL_DOWN_PRESS = keycode_down_event(Media.KC_AUDIO_VOL_DOWN)
VOL_DOWN_RELEASE = keycode_up_event(Media.KC_AUDIO_VOL_DOWN)
class RotaryEncoderMacro:
def __init__(self, pos_pin, neg_pin, slop_history=24, slop_threshold=0.7):
self.encoder = RotaryEncoder(pos_pin, neg_pin)
self.max_history = slop_history
self.history = bytearray(slop_history)
self.history_idx = 0
self.history_threshold = math.floor(slop_threshold * slop_history)
def scan(self):
# Anti-slop logic
self.history[self.history_idx] = 0
reading = self.encoder.direction()
self.history[self.history_idx] = VAL_NONE if reading is None else reading + 1
self.history_idx += 1
if self.history_idx >= self.max_history:
self.history_idx = 0
nones = 0
trues = 0
falses = 0
for val in self.history:
if val == VAL_NONE:
nones += 1
elif val == VAL_TRUE:
trues += 1
elif val == VAL_FALSE:
falses += 1
if nones >= self.history_threshold:
return None
if trues >= self.history_threshold:
return self.on_increase()
if falses >= self.history_threshold:
return self.on_decrease()
def on_decrease(self):
pass
def on_increase(self):
pass
class VolumeRotaryEncoder(RotaryEncoderMacro):
def on_decrease(self):
yield VOL_DOWN_PRESS
yield hid_report_event
yield VOL_DOWN_RELEASE
yield hid_report_event
def on_increase(self):
yield VOL_UP_PRESS
yield hid_report_event
yield VOL_UP_RELEASE
yield hid_report_event

View File

@ -19,6 +19,9 @@ class Firmware:
logger = logging.getLogger(__name__)
logger.setLevel(log_level)
import kmk_keyboard_user
self.encoders = getattr(kmk_keyboard_user, 'encoders', [])
self.hydrated = False
self.store = Store(kmk_reducer, log_level=log_level)
@ -58,3 +61,10 @@ class Firmware:
if update:
self.store.dispatch(update)
for encoder in self.encoders:
eupdate = encoder.scan()
if eupdate:
for event in eupdate:
self.store.dispatch(event)

View File

@ -11,9 +11,12 @@ class Anything:
def __repr__(self):
return 'Anything<{}>'.format(self.name)
def init(self, *args, **kwargs):
pass
@property
def value(self):
return None
return False
class Passthrough:
@ -23,6 +26,10 @@ class Passthrough:
class Pin:
board = Passthrough()
IN = 'IN'
OUT = 'OUT'
PULL_DOWN = 'PULL_DOWN'
PULL_UP = 'PULL_UP'
def __call__(self, *args, **kwargs):
return self.board

View File

@ -1,5 +1,6 @@
from kmk.common.consts import DiodeOrientation, UnicodeModes
from kmk.common.keycodes import KC
from kmk.common.macros.rotary_encoder import VolumeRotaryEncoder
from kmk.common.macros.simple import send_string, simple_key_sequence
from kmk.common.macros.unicode import unicode_string_sequence
from kmk.common.pins import Pin as P
@ -15,6 +16,10 @@ rows = (P.D12, P.D11, P.D10)
diode_orientation = DiodeOrientation.COLUMNS
unicode_mode = UnicodeModes.LINUX
encoders = [
VolumeRotaryEncoder(P.A3, P.A2),
]
emoticons = AttrDict({
# Emojis
'BEER': r'🍺',