Merge pull request #14 from adafruit/jepler-rotary-example

Add rotaryencoder example
This commit is contained in:
Scott Shawcroft 2021-03-11 11:03:38 -08:00 committed by GitHub
commit 3ff94aa9da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

119
examples/rotaryencoder.py Normal file
View 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