1
1
# encoder.py Asynchronous driver for incremental quadrature encoder.
2
2
3
- # Copyright (c) 2021-2022 Peter Hinch
3
+ # Copyright (c) 2021-2023 Peter Hinch
4
4
# Released under the MIT License (MIT) - see LICENSE file
5
5
6
- # For an explanation of the design please see
6
+ # For an explanation of the design please see
7
7
# [ENCODERS.md](https://github.com/peterhinch/micropython-samples/blob/master/encoders/ENCODERS.md)
8
8
9
9
# Thanks are due to the following collaborators:
19
19
20
20
import uasyncio as asyncio
21
21
from machine import Pin
22
+ from select import poll , POLLIN
22
23
23
- class Encoder :
24
24
25
- def __init__ (self , pin_x , pin_y , v = 0 , div = 1 , vmin = None , vmax = None ,
26
- mod = None , callback = lambda a , b : None , args = (), delay = 100 ):
25
+ def ready (tsf , poller ):
26
+ r = (tsf , POLLIN )
27
+ poller .register (* r )
28
+
29
+ def is_rdy ():
30
+ return r in poller .ipoll (0 )
31
+
32
+ return is_rdy
33
+
34
+
35
+ class Encoder :
36
+ def __init__ (
37
+ self ,
38
+ pin_x ,
39
+ pin_y ,
40
+ v = 0 ,
41
+ div = 1 ,
42
+ vmin = None ,
43
+ vmax = None ,
44
+ mod = None ,
45
+ callback = lambda a , b : None ,
46
+ args = (),
47
+ delay = 100 ,
48
+ ):
27
49
self ._pin_x = pin_x
28
50
self ._pin_y = pin_y
29
51
self ._x = pin_x ()
@@ -34,8 +56,9 @@ def __init__(self, pin_x, pin_y, v=0, div=1, vmin=None, vmax=None,
34
56
self ._trig = asyncio .Event ()
35
57
36
58
if ((vmin is not None ) and v < vmin ) or ((vmax is not None ) and v > vmax ):
37
- raise ValueError (' Incompatible args: must have vmin <= v <= vmax' )
59
+ raise ValueError (" Incompatible args: must have vmin <= v <= vmax" )
38
60
self ._tsf = asyncio .ThreadSafeFlag ()
61
+ self ._tsf_ready = ready (self ._tsf , poll ()) # Create a ready function
39
62
trig = Pin .IRQ_RISING | Pin .IRQ_FALLING
40
63
try :
41
64
xirq = pin_x .irq (trigger = trig , handler = self ._x_cb , hard = True )
@@ -67,6 +90,8 @@ async def _run(self, vmin, vmax, div, mod, cb, args):
67
90
plcv = pcv # Previous value after limits applied
68
91
delay = self .delay
69
92
while True :
93
+ if delay > 0 and self ._tsf_ready (): # Ensure ThreadSafeFlag is clear
94
+ await self ._tsf .wait ()
70
95
await self ._tsf .wait ()
71
96
await asyncio .sleep_ms (delay ) # Wait for motion to stop.
72
97
hv = self ._v # Sample hardware (atomic read).
0 commit comments