diff --git a/gui/primitives/encoder.py b/gui/primitives/encoder.py index 759422b..783a69f 100644 --- a/gui/primitives/encoder.py +++ b/gui/primitives/encoder.py @@ -1,6 +1,6 @@ # encoder.py Asynchronous driver for incremental quadrature encoder. -# Copyright (c) 2021-2022 Peter Hinch +# Copyright (c) 2021-2023 Peter Hinch # Released under the MIT License (MIT) - see LICENSE file # Thanks are due to @ilium007 for identifying the issue of tracking detents, @@ -11,11 +11,32 @@ import uasyncio as asyncio from machine import Pin +from select import poll, POLLIN + + +def ready(tsf, poller): + poller.register(tsf, POLLIN) + + def is_rdy(): + return len([t for t in poller.ipoll(0) if t[0] is tsf]) > 0 + + return is_rdy + class Encoder: - - def __init__(self, pin_x, pin_y, v=0, div=1, vmin=None, vmax=None, - mod=None, callback=lambda a, b : None, args=(), delay=100): + def __init__( + self, + pin_x, + pin_y, + v=0, + div=1, + vmin=None, + vmax=None, + mod=None, + callback=lambda a, b: None, + args=(), + delay=100, + ): self._pin_x = pin_x self._pin_y = pin_y self._x = pin_x() @@ -25,8 +46,9 @@ class Encoder: self.delay = delay # Pause (ms) for motion to stop/limit callback frequency if ((vmin is not None) and v < vmin) or ((vmax is not None) and v > vmax): - raise ValueError('Incompatible args: must have vmin <= v <= vmax') + raise ValueError("Incompatible args: must have vmin <= v <= vmax") self._tsf = asyncio.ThreadSafeFlag() + self._tsf_ready = ready(self._tsf, poll()) # Create a ready function trig = Pin.IRQ_RISING | Pin.IRQ_FALLING try: xirq = pin_x.irq(trigger=trig, handler=self._x_cb, hard=True) @@ -58,8 +80,10 @@ class Encoder: plcv = pcv # Previous value after limits applied delay = self.delay while True: - await self._tsf.wait() - await asyncio.sleep_ms(delay) # Wait for motion to stop. + if self._tsf_ready(): # Ensure ThreadSafeFlag is clear + await self._tsf.wait() + await self._tsf.wait() # Wait for an edge + await asyncio.sleep_ms(delay) # Wait for motion/bounce to stop. hv = self._v # Sample hardware (atomic read). if hv == pv: # A change happened but was negated before continue # this got scheduled. Nothing to do.