from machine import Pin import sys class Encoder: _increment_grid = [[0, -1, 1, None], [1, 0, None, -1], [-1, None, 0, 1], [None, 1, -1, 0]] @property def total_change(self): return self._total_change def __init__(self, channel_a, channel_b): self.channel_a = self._configure_channel(channel_a) self.channel_b = self._configure_channel(channel_b) self.reset() def reset(self): self._previous_value = None self._total_change = 0 def _irq_cb(self, input_pin): print('IRQ handler called') current_value = (self.channel_a.value() * 2) + self.channel_b.value() if self._previous_value == None: self._previous_value = current_value return try: change_amount = self._increment_grid[self._previous_value][current_value] self._total_change += change_amount except TypeError: print('Detected invalid encoder state! Can the system keep up?', file=sys.stderr) self._previous_value = current_value def _configure_channel(self, pin): p = pin if isinstance(pin, Pin) else Pin(pin, Pin.IN, pull=Pin.PULL_UP) p.irq(self._irq_cb, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING)) return p