From 564fafd6d5be604e7edbd6b2914f93986105ec89 Mon Sep 17 00:00:00 2001 From: Sandor Attila Gerendi Date: Sat, 13 Feb 2021 21:14:11 +0200 Subject: [PATCH 1/3] Create pio_quadrature_encoder.py Example that is using StateMachine to offload quadrature encoder pooling. --- examples/rp2/pio_quadrature_encoder.py | 99 ++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 examples/rp2/pio_quadrature_encoder.py diff --git a/examples/rp2/pio_quadrature_encoder.py b/examples/rp2/pio_quadrature_encoder.py new file mode 100644 index 0000000000000..2fa38e8a123fe --- /dev/null +++ b/examples/rp2/pio_quadrature_encoder.py @@ -0,0 +1,99 @@ +""" +This implementation offloads the quadrature sensor continuous pooling to the StateMachine pio_quadrature, +pio_quadrature will detect state changes and push the values then raises an interrupt that is handled by +encoder_state_changed_irq_handler + +encoder_state_changed_irq_handler was inspired from +https://electronics.stackexchange.com/questions/360637/quadrature-encoder-most-efficient-software-implementation + +""" + +from machine import Pin +from rp2 import PIO, StateMachine +import utime +import array + + +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 + ]) + + +counter = 0 +direction = 0 +lut_index = 0 + +def encoder_state_changed_irq_handler(sm): + global counter, direction, lut_index + lut_index |= sm.get() & 3 + counter += state_look_up_table[lut_index] + if state_look_up_table[lut_index] != 0: + direction = 1 if (state_look_up_table[lut_index] > 0) else 0 + lut_index = ((lut_index << 2) & 0b1100) | (direction << 4) + + +@rp2.asm_pio() +def pio_quadrature(in_init=rp2.PIO.IN_LOW): + wrap_target() + label("again") + in_(pins, 2) + mov(x, isr) + jmp(x_not_y, "push_data") + mov(isr, null) + jmp("again") + label("push_data") + push() + irq(block, rel(0)) + mov(y, x) + wrap() + + + +sm = StateMachine(0, pio_quad, freq=160000, in_base=Pin(2)) +sm.irq(encoder_state_changed_irq_handler) +sm.exec("set(y, 99)") # add a last value for y that would be always different then the input +sm.active(1) + +while True: + utime.sleep(2) + print(counter) From 5366ead756cc04a322be6e0196b3e444052156e8 Mon Sep 17 00:00:00 2001 From: Sandor Attila Gerendi Date: Tue, 28 Dec 2021 12:01:48 +0200 Subject: [PATCH 2/3] Fixes missing import and botched refactoring reported by robert-hh --- examples/rp2/pio_quadrature_encoder.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/rp2/pio_quadrature_encoder.py b/examples/rp2/pio_quadrature_encoder.py index 2fa38e8a123fe..7945b3410bad7 100644 --- a/examples/rp2/pio_quadrature_encoder.py +++ b/examples/rp2/pio_quadrature_encoder.py @@ -9,6 +9,7 @@ """ from machine import Pin +import rp2 from rp2 import PIO, StateMachine import utime import array @@ -89,7 +90,7 @@ def pio_quadrature(in_init=rp2.PIO.IN_LOW): -sm = StateMachine(0, pio_quad, freq=160000, in_base=Pin(2)) +sm = StateMachine(0, pio_quadrature, freq=160000, in_base=Pin(2)) sm.irq(encoder_state_changed_irq_handler) sm.exec("set(y, 99)") # add a last value for y that would be always different then the input sm.active(1) From c79be30ca661194d50fb1dc5a4af70aef50d29f4 Mon Sep 17 00:00:00 2001 From: Sandor Attila Gerendi Date: Thu, 30 Dec 2021 17:50:12 +0200 Subject: [PATCH 3/3] Cater for the case where another state change occurs while the ISR is running. Thank you peterhinch --- examples/rp2/pio_quadrature_encoder.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/rp2/pio_quadrature_encoder.py b/examples/rp2/pio_quadrature_encoder.py index 7945b3410bad7..cc6cf2ec51b6e 100644 --- a/examples/rp2/pio_quadrature_encoder.py +++ b/examples/rp2/pio_quadrature_encoder.py @@ -66,11 +66,12 @@ def encoder_state_changed_irq_handler(sm): global counter, direction, lut_index - lut_index |= sm.get() & 3 - counter += state_look_up_table[lut_index] - if state_look_up_table[lut_index] != 0: - direction = 1 if (state_look_up_table[lut_index] > 0) else 0 - lut_index = ((lut_index << 2) & 0b1100) | (direction << 4) + while sm.rx_fifo(): + lut_index |= sm.get() & 3 + counter += state_look_up_table[lut_index] + if state_look_up_table[lut_index] != 0: + direction = 1 if (state_look_up_table[lut_index] > 0) else 0 + lut_index = ((lut_index << 2) & 0b1100) | (direction << 4) @rp2.asm_pio() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy