From 0297fe856aa185e6a1f45b97a2501834850c0119 Mon Sep 17 00:00:00 2001 From: Benjamin Zeiss Date: Wed, 2 Mar 2022 03:27:14 +0100 Subject: [PATCH] 8bit encoder detection + debounced button detection, numpy removal (#710) * debounce interrupt events for rotary events and button presses with 400 microseconds by default. * Massive improvements for the encoder detection. Removed numpy as a dependency. * Debounce button presses which started to jump around. * formatting cleanup. --- easyinstall.sh | 4 +- python/ctrlboard/README.md | 1 + python/ctrlboard/requirements.txt | 3 +- .../src/ctrlboard_hw/ctrlboard_hw.py | 42 +++++++++------ python/ctrlboard/src/ctrlboard_hw/encoder.py | 51 ++++++------------- .../src/ctrlboard_hw/hardware_button.py | 1 + 6 files changed, 47 insertions(+), 55 deletions(-) diff --git a/easyinstall.sh b/easyinstall.sh index 288fa308..58269dd8 100755 --- a/easyinstall.sh +++ b/easyinstall.sh @@ -992,8 +992,8 @@ function installRaScsiCtrlBoard() { updateRaScsiGit sudo apt-get update && sudo apt-get install libjpeg-dev libpng-dev libopenjp2-7-dev i2c-tools raspi-config -y > shiftval) & 0b11111111 rot_a = self.button_value(input_register, 0) rot_b = self.button_value(input_register, 1) + button_rotary = self.button_value(input_register, 5) button_1 = self.button_value(input_register, 2) button_2 = self.button_value(input_register, 3) @@ -176,19 +186,21 @@ class CtrlBoardHardware(Observable): if button_rotary == 0: self.rotary_button.state_interrupt = bool(button_rotary) + rot_tmp_state = 0b11 if rot_a == 0: - self.rotary.enc_a.state_interrupt = bool(rot_a) - + rot_tmp_state &= 0b10 if rot_b == 0: + rot_tmp_state &= 0b01 + + if rot_tmp_state != self.rot_prev_state: + self.rot_prev_state = rot_tmp_state + self.rotary.enc_a.state_interrupt = bool(rot_a) self.rotary.enc_b.state_interrupt = bool(rot_b) + self.check_rotary_encoder(self.rotary) self.check_button_press(self.rotary_button) self.check_button_press(self.button1) self.check_button_press(self.button2) - self.check_rotary_encoder(self.rotary) - - self.rotary.state = 0b11 - self.input_register_buffer = 0 @staticmethod def detect_i2c_devices(_bus): diff --git a/python/ctrlboard/src/ctrlboard_hw/encoder.py b/python/ctrlboard/src/ctrlboard_hw/encoder.py index 0af34d7a..f5568f33 100644 --- a/python/ctrlboard/src/ctrlboard_hw/encoder.py +++ b/python/ctrlboard/src/ctrlboard_hw/encoder.py @@ -10,57 +10,36 @@ class Encoder: self.enc_a = enc_a self.enc_b = enc_b self.pos = 0 - self.state = 0b0011 + self.state = 0b00000000 self.direction = 0 def update(self): """Updates the internal attributes wrt. to the encoder position and direction.""" - self.update2() - - def update2(self): - """Primary method for detecting the direction""" value_enc_a = self.enc_a.state_interrupt value_enc_b = self.enc_b.state_interrupt self.direction = 0 - state = self.state & 0b0011 + state = self.state & 0b00111111 if value_enc_a: - state |= 0b0100 + state |= 0b01000000 if value_enc_b: - state |= 0b1000 + state |= 0b10000000 - if state == 0b1011: + # clockwise pattern detection + if (state == 0b11010010 or state == 0b11001000 or state == 0b11011000 or + state == 0b11010001 or state == 0b11011011 or state == 0b11100000 or + state == 0b11001011): self.pos += 1 self.direction = 1 - - if state == 0b0111: + self.state = 0b00000000 + return + # counter-clockwise pattern detection + elif (state == 0b11000100 or state == 0b11100100 or state == 0b11100001 or + state == 0b11000111 or state == 0b11100111): self.pos -= 1 self.direction = -1 + self.state = 0b00000000 + return self.state = state >> 2 - - self.enc_a.state_interrupt = True - self.enc_b.state_interrupt = True - - def update1(self): - """Secondary, less well working method to detect the direction""" - if self.enc_a.state_interrupt is True and self.enc_b.state_interrupt is True: - return - - if self.enc_a.state_interrupt is False and self.enc_b.state_interrupt is False: - self.enc_a.state_interrupt = True - self.enc_b.state_interrupt = True - return - - self.direction = 0 - - if self.enc_a.state_interrupt is False: - self.pos += 1 - self.direction = 1 - elif self.enc_a.state_interrupt is True: - self.pos -= 1 - self.direction = -1 - - self.enc_a.state_interrupt = True - self.enc_b.state_interrupt = True diff --git a/python/ctrlboard/src/ctrlboard_hw/hardware_button.py b/python/ctrlboard/src/ctrlboard_hw/hardware_button.py index 43268f68..d8e79226 100644 --- a/python/ctrlboard/src/ctrlboard_hw/hardware_button.py +++ b/python/ctrlboard/src/ctrlboard_hw/hardware_button.py @@ -11,6 +11,7 @@ class HardwareButton: self.state = True self.state_interrupt = True self.name = "n/a" + self.last_press = None def read(self): """Reads the configured port of the i2c multiplexer"""