8000 RP2040 rotaryio fails with two encoders · Issue #10024 · adafruit/circuitpython · GitHub
[go: up one dir, main page]

Skip to content

RP2040 rotaryio fails with two encoders #10024

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
todbot opened this issue Feb 3, 2025 · 6 comments · Fixed by #10025
Closed

RP2040 rotaryio fails with two encoders #10024

todbot opened this issue Feb 3, 2025 · 6 comments · Fixed by #10025
Assignees
Labels
bug rotaryio rp2040 Raspberry Pi RP2040
Milestone

Comments

@todbot
Copy link
todbot commented Feb 3, 2025

CircuitPython version and board name

Adafruit CircuitPython 9.2.4 on 2025-01-29; Raspberry Pi Pico with rp2040

and:
Adafruit CircuitPython 9.2.4-5-g3236a0f200 on 2025-01-31; Raspberry Pi Pico with rp2040  
  ("absolute newest" as of noon PST 3 Feb 2025)
Adafruit CircuitPython 9.2.3 on 2025-01-17; Raspberry Pi Pico with rp2040
Adafruit CircuitPython 9.2.2 on 2025-01-09; Raspberry Pi Pico with rp2040

Code/REPL

import time, board, rotaryio

encoder1 = rotaryio.IncrementalEncoder(board.GP19, board.GP18)
encoder2 = rotaryio.IncrementalEncoder(board.GP4, board.GP5)

while True:
    print(encoder1.position, encoder2.position)
    time.sleep(0.1)

Behavior

Code hangs on creation of encoder2, which is obviously not correct.

Code should repeatedly print position of both encoders.

Description

Works on 9.2.1.
Does not work on 9.2.2 and above.
Related to #9682?

Additional information

Redditor had his issue too: https://old.reddit.com/r/circuitpython/comments/1igqzyf/two_incrementalencoders_fail/

@todbot todbot added the bug label Feb 3, 2025
@todbot
Copy link
Author
todbot commented Feb 3, 2025

Update: It appears to get out of hanging if a change happens on encoder2. But then encoder1 does not work.

@jepler jepler added this to the 9.2.x milestone Feb 3, 2025
@jepler
Copy link
jepler commented Feb 3, 2025

From 9.2.1 to 9.2.2 the big thing seems to be my PIO re-org to support the high pins on rp2350b (#9901). I know there were also changes to interrupts (or was it DMA? which this driver doesn't use-- #9980) but those seem to have occurred after 9.2.3.

@dhalbert dhalbert added rp2040 Raspberry Pi RP2040 rotaryio labels Feb 3, 2025
@jepler jepler self-assigned this Feb 4, 2025
@jepler
Copy link
jepler commented Feb 4, 2025
(gdb) where
#0  _transfer (data_out=<optimized out>, out_len=0, 
    out_stride_in_bytes=0 '\000', swap_out=false, swap_in=false, 
    in_stride_in_bytes=1 '\001', in_len=536939816, 
    data_in=0x20080dd7 "\020l\344\n\020d\344\n\020\020\n\001  \r\001 d\344\n\020l\344\n\020\254\377", self=0x20010d28) at common-hal/rp2pio/StateMachine.c:984
#1  common_hal_rp2pio_statemachine_readinto (self=self@entry=0x20010d28, 
    data=data@entry=0x20080dd7 "\020l\344\n\020d\344\n\020\020\n\001  \r\001 d\344\n\020l\344\n\020\254\377", len=len@entry=1, 
    stride_in_bytes=stride_in_bytes@entry=1 '\001', swap=swap@entry=false)
    at common-hal/rp2pio/StateMachine.c:1031
#2  0x10042930 in common_hal_rotaryio_incrementalencoder_construct (
    self=self@entry=0x20010d20, pin_a=pin_a@entry=0x100ae46c <pin_GPIO43>, 
    pin_b=pin_b@entry=0x100ae464 <pin_GPIO44>)
    at common-hal/rotaryio/IncrementalEncoder.c:85

The hang occurs when constructing the 2nd encoder instance. However, if I modify the StateMachine implementation so that "use_existing_program" always returns false, the problem stops. Or at least it successfully constructs the StateMachine object in this case. I don't have any encoders hooked up.

@jepler
Copy link
jepler commented Feb 4, 2025

I wrote some code so that I didn't need any encoder knobs for testing.

# Test simulated encoder (issue #10024) for metro rp2350
# Connect jumper wires from RX/TX/D2/D3 to A0/A1/A2/A3
# Each encoder should count.
import board, rotaryio
import digitalio

d = digitalio.DigitalInOut(board.D0)
d.switch_to_output(False)
e = digitalio.DigitalInOut(board.D1)
e.switch_to_output(False)
f = digitalio.DigitalInOut(board.D2)
f.switch_to_output(False)
g = digitalio.DigitalInOut(board.D3)
g.switch_to_output(False)

r1 = rotaryio.IncrementalEncoder(board.A0, board.A1, divisor=1)
r1.position = 0
r2 = rotaryio.IncrementalEncoder(board.A2, board.A3, divisor=1)
r2.position = 0

for _ in range(8):
    d.value = True
    print(f"{+d.value}{+e.value} {r1.position} {r2.position}")
    e.value = True
    print(f"{+d.value}{+e.value} {r1.position} {r2.position}")
    d.value = False
    print(f"{+d.value}{+e.value} {r1.position} {r2.position}")
    e.value = False
    print(f"{+d.value}{+e.value} {r1.position} {r2.position}")

for _ in range(8):
    f.value = True
    print(f"{+f.value}{+g.value} {r1.position} {r2.position}")
    g.value = True
    print(f"{+f.value}{+g.value} {r1.position} {r2.position}")
    f.value = False
    print(f"{+f.value}{+g.value} {r1.position} {r2.position}")
    g.value = False
    print(f"{+f.value}{+g.value} {r1.position} {r2.position}")

jepler added a commit to jepler/circuitpython that referenced this issue Feb 4, 2025
.. for duplicate programs, like two IncrementalEncoder instances.

Closes: adafruit#10024
@todbot
Copy link
Author
todbot commented Feb 4, 2025

Verified that fix #10025 does make two encoders work on RP2040 Pico and RP2350 Pico2.

@jepler
Copy link
jepler commented Feb 4, 2025

Thanks for testing, @todbot !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug rotaryio rp2040 Raspberry Pi RP2040
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants
0