kopia lustrzana https://github.com/peterhinch/micropython-micro-gui
encoder.py: Improve encoder response.
rodzic
4117ddf230
commit
5fea5d948c
|
@ -1,6 +1,6 @@
|
||||||
# encoder.py Asynchronous driver for incremental quadrature encoder.
|
# 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
|
# Released under the MIT License (MIT) - see LICENSE file
|
||||||
|
|
||||||
# Thanks are due to @ilium007 for identifying the issue of tracking detents,
|
# Thanks are due to @ilium007 for identifying the issue of tracking detents,
|
||||||
|
@ -11,11 +11,32 @@
|
||||||
|
|
||||||
import uasyncio as asyncio
|
import uasyncio as asyncio
|
||||||
from machine import Pin
|
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:
|
class Encoder:
|
||||||
|
def __init__(
|
||||||
def __init__(self, pin_x, pin_y, v=0, div=1, vmin=None, vmax=None,
|
self,
|
||||||
mod=None, callback=lambda a, b : None, args=(), delay=100):
|
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_x = pin_x
|
||||||
self._pin_y = pin_y
|
self._pin_y = pin_y
|
||||||
self._x = pin_x()
|
self._x = pin_x()
|
||||||
|
@ -25,8 +46,9 @@ class Encoder:
|
||||||
self.delay = delay # Pause (ms) for motion to stop/limit callback frequency
|
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):
|
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 = asyncio.ThreadSafeFlag()
|
||||||
|
self._tsf_ready = ready(self._tsf, poll()) # Create a ready function
|
||||||
trig = Pin.IRQ_RISING | Pin.IRQ_FALLING
|
trig = Pin.IRQ_RISING | Pin.IRQ_FALLING
|
||||||
try:
|
try:
|
||||||
xirq = pin_x.irq(trigger=trig, handler=self._x_cb, hard=True)
|
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
|
plcv = pcv # Previous value after limits applied
|
||||||
delay = self.delay
|
delay = self.delay
|
||||||
while True:
|
while True:
|
||||||
await self._tsf.wait()
|
if self._tsf_ready(): # Ensure ThreadSafeFlag is clear
|
||||||
await asyncio.sleep_ms(delay) # Wait for motion to stop.
|
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).
|
hv = self._v # Sample hardware (atomic read).
|
||||||
if hv == pv: # A change happened but was negated before
|
if hv == pv: # A change happened but was negated before
|
||||||
continue # this got scheduled. Nothing to do.
|
continue # this got scheduled. Nothing to do.
|
||||||
|
|
Ładowanie…
Reference in New Issue