123456789101112131415161718192021222324252627282930313233343536373839404142 |
- import machine
- 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):
- interrupt_mask = machine.disable_irq()
- current_value = (self.channel_a.value() * 2) + self.channel_b.value()
- if self._previous_value == None:
- self._previous_value = current_value
- machine.enable_irq(interrupt_mask)
- 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
- machine.enable_irq(interrupt_mask)
- 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
|