Merge pull request #14 from adafruit/jepler-rotary-example
Add rotaryencoder example
This commit is contained in:
commit
3ff94aa9da
1 changed files with 119 additions and 0 deletions
119
examples/rotaryencoder.py
Normal file
119
examples/rotaryencoder.py
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# SPDX-FileCopyrightText: 2021 Jeff Epler, written for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# This example is adapted in part from micropython:
|
||||
# https://github.com/micropython/micropython/pull/6894/files
|
||||
|
||||
import adafruit_pioasm
|
||||
import board
|
||||
import rp2pio
|
||||
import array
|
||||
import digitalio
|
||||
|
||||
|
||||
class IncrementalEncoder:
|
||||
_state_look_up_table = array.array(
|
||||
"b",
|
||||
[
|
||||
# Direction = 1
|
||||
0, # 00 to 00
|
||||
-1, # 00 to 01
|
||||
+1, # 00 to 10
|
||||
+2, # 00 to 11
|
||||
+1, # 01 to 00
|
||||
0, # 01 to 01
|
||||
+2, # 01 to 10
|
||||
-1, # 01 to 11
|
||||
-1, # 10 to 00
|
||||
+2, # 10 to 01
|
||||
0, # 10 to 10
|
||||
+1, # 10 to 11
|
||||
+2, # 11 to 00
|
||||
+1, # 11 to 01
|
||||
-1, # 11 to 10
|
||||
0, # 11 to 11
|
||||
# Direction = 0
|
||||
0, # 00 to 00
|
||||
-1, # 00 to 01
|
||||
+1, # 00 to 10
|
||||
-2, # 00 to 11
|
||||
+1, # 01 to 00
|
||||
0, # 01 to 01
|
||||
-2, # 01 to 10
|
||||
-1, # 01 to 11
|
||||
-1, # 10 to 00
|
||||
-2, # 10 to 01
|
||||
0, # 10 to 10
|
||||
+1, # 10 to 11
|
||||
-2, # 11 to 00
|
||||
+1, # 11 to 01
|
||||
-1, # 11 to 10
|
||||
0, # 11 to 11
|
||||
],
|
||||
)
|
||||
|
||||
_sm_code = adafruit_pioasm.assemble(
|
||||
"""
|
||||
again:
|
||||
in pins, 2
|
||||
mov x, isr
|
||||
jmp x!=y, push_data
|
||||
mov isr, null
|
||||
jmp again
|
||||
push_data:
|
||||
push
|
||||
mov y, x
|
||||
"""
|
||||
)
|
||||
|
||||
_sm_init = adafruit_pioasm.assemble("set y 31")
|
||||
|
||||
def __init__(self, pin_a, pin_b):
|
||||
if not rp2pio.pins_are_sequential([pin_a, pin_b]):
|
||||
raise ValueError("Pins must be sequential")
|
||||
|
||||
self._sm = rp2pio.StateMachine(
|
||||
self._sm_code,
|
||||
160_000,
|
||||
init=self._sm_init,
|
||||
first_in_pin=pin_a,
|
||||
in_pin_count=2,
|
||||
pull_in_pin_up=0b11,
|
||||
in_shift_right=False,
|
||||
)
|
||||
|
||||
self._counter = 0
|
||||
self._direction = 0
|
||||
self._lut_index = 0
|
||||
self._buffer = bytearray(1)
|
||||
|
||||
def _update_state_machine(self, state):
|
||||
lut_index = self._lut_index | (state & 3)
|
||||
lut = self._state_look_up_table[lut_index]
|
||||
self._counter += lut
|
||||
if lut:
|
||||
self._direction = 1 if (lut > 0) else 0
|
||||
self._lut_index = ((lut_index << 2) & 0b1100) | (self._direction << 4)
|
||||
|
||||
def deinit(self):
|
||||
self._sm.deinit()
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
while self._sm.in_waiting:
|
||||
self._sm.readinto(self._buffer)
|
||||
self._update_state_machine(self._buffer[0])
|
||||
return self._counter
|
||||
|
||||
|
||||
encoder = IncrementalEncoder(board.GP2, board.GP3)
|
||||
|
||||
old_value = None
|
||||
while True:
|
||||
gen()
|
||||
|
||||
value = encoder.value
|
||||
if old_value != value:
|
||||
print("Encoder:", value)
|
||||
old_value = value
|
||||
Loading…
Reference in a new issue