MicroPython or Circuit for Pico RGB Rotary Breakout

Hi,

Has anyone got the rgb breakout rotary encoder working with micropython or circuitpython on a rpi pico?

(RGB Encoder Breakout – Pimoroni)

I’m having trouble trying to port the ioe example code to pico.

I saw this list as to what’s supported in the Pimoroni Micro Python uf2 file
I see RGB Encoder Breakout in the list. And it appears to be the one you have.

I do believe this is the Micro Python Pico stuff.
pimoroni-pico/micropython/examples at main · pimoroni/pimoroni-pico · GitHub

pimoroni-pico/micropython/examples/breakout_encoder at main · pimoroni/pimoroni-pico · GitHub

Many thanks, my google-fu was weak

I initially had circuit python on the pico and it detected the encoder breakout board on pins 11 & 12 during an i2c scan.

I flashed the pimoroni micropython, and loaded the demo from the examples linked above

from pimoroni_i2c import PimoroniI2C
from breakout_encoder import BreakoutEncoder

PINS_BREAKOUT_GARDEN = {"sda": 11, "scl": 12}
#PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}

steps_per_rev = 24

i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)
enc = BreakoutEncoder(i2c)

enc.set_brightness(1.0)
# enc.set_direction(BreakoutEncoder.DIRECTION_CCW)     # Uncomment this to flip the direction


# From CPython Lib/colorsys.py
def hsv_to_rgb(h, s, v):
    if s == 0.0:
        return v, v, v
    i = int(h * 6.0)
    f = (h * 6.0) - i
    p = v * (1.0 - s)
    q = v * (1.0 - s * f)
    t = v * (1.0 - s * (1.0 - f))
    i = i % 6
    if i == 0:
        return v, t, p
    if i == 1:
        return q, v, p
    if i == 2:
        return p, v, t
    if i == 3:
        return p, q, v
    if i == 4:
        return t, p, v
    if i == 5:
        return v, p, q


def count_changed(count):
    print("Count: ", count, sep="")
    h = ((count % steps_per_rev) * 360.0) / steps_per_rev     # Convert the count to a colour hue
    r, g, b = [int(255 * c) for c in hsv_to_rgb(h / 360.0, 1.0, 1.0)]  # rainbow magic
    enc.set_led(r, g, b)


count = 0

count_changed(count)
enc.clear_interrupt_flag()

while True:
    if enc.get_interrupt_flag():
        count = enc.read()
        enc.clear_interrupt_flag()

        while count < 0:
            count += steps_per_rev

        count_changed(count)

However, I get a “ValueError: bad SDA pin”.
If I try GP pin numbering (8, 9) I get “breakout not found” instead, which indicates the board is being detected on 11 & 12. Is it my soldering skills?

A simple reset fixed it - not my day today

Stuff happens. The links to that stuff could be better IMHO. If you look hard enough you will find it though. I went to the Pico Breakout Garden shop page where it lists all the breakouts, a link to Pimorni’s Micro Python stuff is there if you scroll down far enough.

I don’t suppose anyone has managed to get this to work with Circuit Python? I would love to incorporate it into my Macro Pad that’s currently using a normal rotary encoder using Stemma.

Thanks!

Darren.

I’m trying to do something similar. Got it working fine in MicroPython and regular Python, but I’m having trouble reverse engineering the MP or Python libraries to create a CircuitPython library I can use on the Keybow PMK image. Have you had any luck yet?

What is your exact problem when you try to reverse engineer the Python-libraries? I ported some of the Pimoroni (Pi-) Python-libs to CircuitPython and most of the work was to write simple wrappers to the low-level I2C (or SPI) methods. The IOExpander for example has a lot of i2c_writeXX methods that do the low-level I2C-communication and these have to be converted to the way CircuitPython speaks to the I2C bus. Same holds true of course for I2C bus/device creation.

Yes that’s exactly it. I’m still learning with I2C and so haven’t figured out how to port the low-level methods yet. I got as far replicating the smbus2 module used by IOExpander with this: pimoroni/circuitpython_adapter: A CircuitPython translation layer (github.com).

This module doesn’t replicate the i2c_msg class though and CircuitPython doesn’t have the uctypes library I think I need to replicate it myself, so I’ve hit a bit of a blocker just now. Any guidance would be wonderful! Could I use the CircuitPython i2ctarget as a substitute for smbus2 with a suitable adapter in between it and IOExpander?

In fact I found a CircuitPython-driver for the IOExpander at github, but I did not test it yet: GitHub - mathcampbell/IOExpanderCircuitPython: CircuitPytthon port of the Pimoroni IO Expander Breakout library. Maybe you want to give it a try.

1 Like

I’ve had a go at porting the io expander module to circuitpython in order to use a RGB encoder breakout on a Raspberry Pi Pico. It works to read the encoder value and set the RGB levels. Code here: GitHub - pddring/ioe-circuitpython: CircuitPython port of the library for the Nuvoton MS51 Pimoroni IO Expander Breakout

Brilliant, thanks for sharing. I’ll have a go at integrating this with my setup and let you know how I get on.