import time from machine import Pin, enable_irq, disable_irq from micropython import schedule from _thread import allocate_lock """ 00 0 01 1 11 2 10 3 """ class IgnoreIRQ: def __enter__(self): self._irq = disable_irq() def __exit__(self, exc_type, exc_obj, exc_tb): enable_irq(self._irq) class Encoder: def __init__(self, a, b): self.a = Pin(a, mode=Pin.IN, pull=Pin.PULL_UP) self.b = Pin(b, mode=Pin.IN, pull=Pin.PULL_UP) self._last = self.gray_bin() self._value = 0 self._lock = allocate_lock() def start(self): self.a.irq(handler=self._edge, trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING) self.b.irq(handler=self._edge, trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING) def stop(self): self.a.irq(handler=None, trigger=0) self.b.irq(handler=None, trigger=0) def gray_bin(self) -> int: a, b = self.a(), self.b() if not a and not b: return 0 elif not a and b: return 1 elif a and b: return 2 elif a and not b: return 3 def _edge(self, pin: Pin): # start = time.ticks_us() with self._lock, IgnoreIRQ(): current = self.gray_bin() if current == (self._last - 1) % 4: self._value += 1 elif current == (self._last + 1) % 4: self._value -= 1 self._last = current # self.delta_time_us = time.ticks_us() - start @property def value(self): with self._lock: return self._value enc = Encoder(2, 3) enc.start() last = None while True: current = enc.value if current != last: print(current) last = current time.sleep_ms(10)