aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/extras
diff options
context:
space:
mode:
authorJanar Sööt <janar.soot@gmail.com>2018-07-01 15:41:14 +0300
committerKevinOConnor <kevin@koconnor.net>2018-07-01 08:41:14 -0400
commit3a1d9e779c08a18ac6b0b2e314b7c29df7fec95c (patch)
treebd74f687ad4f13eb1fe60faadb79a916d8ecb170 /klippy/extras
parentb41770caa657bc8a3eb1e41331aa3603c97dcaca (diff)
downloadkutter-3a1d9e779c08a18ac6b0b2e314b7c29df7fec95c.tar.gz
kutter-3a1d9e779c08a18ac6b0b2e314b7c29df7fec95c.tar.xz
kutter-3a1d9e779c08a18ac6b0b2e314b7c29df7fec95c.zip
buttons: Improve rotary encoder handler by using Ben Buxton state machine. (#445)
https://github.com/brianlow/Rotary Signed-off-by: Janar Sööt <janar.soot@gmail.com>
Diffstat (limited to 'klippy/extras')
-rw-r--r--klippy/extras/buttons.py46
1 files changed, 35 insertions, 11 deletions
diff --git a/klippy/extras/buttons.py b/klippy/extras/buttons.py
index fe683f8d..76727328 100644
--- a/klippy/extras/buttons.py
+++ b/klippy/extras/buttons.py
@@ -8,6 +8,35 @@ import logging
QUERY_TIME = .002
RETRANSMIT_COUNT = 50
+# Rotary encoder handler https://github.com/brianlow/Rotary
+# Copyright 2011 Ben Buxton (bb@cactii.net). Licenced under the GNU GPL Version 3.
+R_START = 0x0
+R_CW_FINAL = 0x1
+R_CW_BEGIN = 0x2
+R_CW_NEXT = 0x3
+R_CCW_BEGIN = 0x4
+R_CCW_FINAL = 0x5
+R_CCW_NEXT = 0x6
+R_DIR_CW = 0x10
+R_DIR_CCW = 0x20
+R_DIR_MSK = 0x30
+# Use the full-step state table (emits a code at 00 only)
+ENCODER_STATES = (
+ # R_START
+ (R_START, R_CW_BEGIN, R_CCW_BEGIN, R_START),
+ # R_CW_FINAL
+ (R_CW_NEXT, R_START, R_CW_FINAL, R_START | R_DIR_CW),
+ # R_CW_BEGIN
+ (R_CW_NEXT, R_CW_BEGIN, R_START, R_START),
+ # R_CW_NEXT
+ (R_CW_NEXT, R_CW_BEGIN, R_CW_FINAL, R_START),
+ # R_CCW_BEGIN
+ (R_CCW_NEXT, R_START, R_CCW_BEGIN, R_START),
+ # R_CCW_FINAL
+ (R_CCW_NEXT, R_CCW_FINAL, R_START, R_START | R_DIR_CCW),
+ # R_CCW_NEXT
+ (R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START)
+)
######################################################################
# Button state tracking
@@ -89,18 +118,13 @@ class RotaryEncoder:
def __init__(self, cw_callback, ccw_callback):
self.cw_callback = cw_callback
self.ccw_callback = ccw_callback
- self.next_callback = None
+ self.encoder_state = R_START
def encoder_callback(self, eventtime, state):
- # XXX - do full encoder state tracking
- if state == 3:
- self.next_callback = None
- elif state == 2:
- self.next_callback = self.ccw_callback
- elif state == 1:
- self.next_callback = self.cw_callback
- elif self.next_callback is not None:
- self.next_callback(eventtime)
- self.next_callback = None
+ self.encoder_state = ENCODER_STATES[self.encoder_state & 0xf][state & 0x3]
+ if (self.encoder_state & R_DIR_MSK) == R_DIR_CW:
+ self.cw_callback(eventtime)
+ elif (self.encoder_state & R_DIR_MSK) == R_DIR_CCW:
+ self.ccw_callback(eventtime)
######################################################################