quadrature.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. from machine import Pin
  2. import sys
  3. class Encoder:
  4. _increment_grid = [[0, -1, 1, None],
  5. [1, 0, None, -1],
  6. [-1, None, 0, 1],
  7. [None, 1, -1, 0]]
  8. @property
  9. def total_change(self):
  10. return self._total_change
  11. def __init__(self, channel_a, channel_b):
  12. self.channel_a = self._configure_channel(channel_a)
  13. self.channel_b = self._configure_channel(channel_b)
  14. self.reset()
  15. def reset(self):
  16. self._previous_value = None
  17. self._total_change = 0
  18. def _irq_cb(self, input_pin):
  19. print('IRQ handler called')
  20. current_value = (self.channel_a.value() * 2) + self.channel_b.value()
  21. if self._previous_value == None:
  22. self._previous_value = current_value
  23. return
  24. try:
  25. change_amount = self._increment_grid[self._previous_value][current_value]
  26. self._total_change += change_amount
  27. except TypeError:
  28. print('Detected invalid encoder state! Can the system keep up?', file=sys.stderr)
  29. self._previous_value = current_value
  30. def _configure_channel(self, pin):
  31. p = pin if isinstance(pin, Pin) else Pin(pin, Pin.IN, pull=Pin.PULL_UP)
  32. p.irq(self._irq_cb, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING))
  33. return p