Skip to content

Commit 3ff94aa

Browse files
authored
Merge pull request #14 from adafruit/jepler-rotary-example
Add rotaryencoder example
2 parents 74330ed + 5a7e52c commit 3ff94aa

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

examples/rotaryencoder.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# SPDX-FileCopyrightText: 2021 Jeff Epler, written for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
#
5+
# This example is adapted in part from micropython:
6+
# https://github.com/micropython/micropython/pull/6894/files
7+
8+
import adafruit_pioasm
9+
import board
10+
import rp2pio
11+
import array
12+
import digitalio
13+
14+
15+
class IncrementalEncoder:
16+
_state_look_up_table = array.array(
17+
"b",
18+
[
19+
# Direction = 1
20+
0, # 00 to 00
21+
-1, # 00 to 01
22+
+1, # 00 to 10
23+
+2, # 00 to 11
24+
+1, # 01 to 00
25+
0, # 01 to 01
26+
+2, # 01 to 10
27+
-1, # 01 to 11
28+
-1, # 10 to 00
29+
+2, # 10 to 01
30+
0, # 10 to 10
31+
+1, # 10 to 11
32+
+2, # 11 to 00
33+
+1, # 11 to 01
34+
-1, # 11 to 10
35+
0, # 11 to 11
36+
# Direction = 0
37+
0, # 00 to 00
38+
-1, # 00 to 01
39+
+1, # 00 to 10
40+
-2, # 00 to 11
41+
+1, # 01 to 00
42+
0, # 01 to 01
43+
-2, # 01 to 10
44+
-1, # 01 to 11
45+
-1, # 10 to 00
46+
-2, # 10 to 01
47+
0, # 10 to 10
48+
+1, # 10 to 11
49+
-2, # 11 to 00
50+
+1, # 11 to 01
51+
-1, # 11 to 10
52+
0, # 11 to 11
53+
],
54+
)
55+
56+
_sm_code = adafruit_pioasm.assemble(
57+
"""
58+
again:
59+
in pins, 2
60+
mov x, isr
61+
jmp x!=y, push_data
62+
mov isr, null
63+
jmp again
64+
push_data:
65+
push
66+
mov y, x
67+
"""
68+
)
69+
70+
_sm_init = adafruit_pioasm.assemble("set y 31")
71+
72+
def __init__(self, pin_a, pin_b):
73+
if not rp2pio.pins_are_sequential([pin_a, pin_b]):
74+
raise ValueError("Pins must be sequential")
75+
76+
self._sm = rp2pio.StateMachine(
77+
self._sm_code,
78+
160_000,
79+
init=self._sm_init,
80+
first_in_pin=pin_a,
81+
in_pin_count=2,
82+
pull_in_pin_up=0b11,
83+
in_shift_right=False,
84+
)
85+
86+
self._counter = 0
87+
self._direction = 0
88+
self._lut_index = 0
89+
self._buffer = bytearray(1)
90+
91+
def _update_state_machine(self, state):
92+
lut_index = self._lut_index | (state & 3)
93+
lut = self._state_look_up_table[lut_index]
94+
self._counter += lut
95+
if lut:
96+
self._direction = 1 if (lut > 0) else 0
97+
self._lut_index = ((lut_index << 2) & 0b1100) | (self._direction << 4)
98+
99+
def deinit(self):
100+
self._sm.deinit()
101+
102+
@property
103+
def value(self):
104+
while self._sm.in_waiting:
105+
self._sm.readinto(self._buffer)
106+
self._update_state_machine(self._buffer[0])
107+
return self._counter
108+
109+
110+
encoder = IncrementalEncoder(board.GP2, board.GP3)
111+
112+
old_value = None
113+
while True:
114+
gen()
115+
116+
value = encoder.value
117+
if old_value != value:
118+
print("Encoder:", value)
119+
old_value = value

0 commit comments

Comments
 (0)