Pico RGB Keypad Base as a USB HID device - SOLVED

That’s rather helpful of you Martin. Many thanks.

I think between us all we have now got this pretty much figured out. I do like “a lot less bother”. :)

This is such an informative thread. I had hesitated buying the RGB keypad as I expected a problem between Pimoroni’s firmware and the available CircuitPython implementation of USB HID, just now waiting for them to come back in stock! Thanks for posing the problem, coming up with solutions and the 3d file, all!

1 Like

Got all the hardware, followed the guide, and it works like a charm! My keyboard doesn’t have volume/mute controls, so using the HID control codes solved this problem, and the keycodes make MS Teams interaction so much easier. Got another one for my son to use during online school lessons.

Thank you so much for this thread. I got a pico & a pimoroni & this is brilliant.

One quick question about the code though. I’ve gone with the code ColinD posted rather than Martin’s class (cos I didn’t understand it!) & Qbalsdon’s github because well, it looked slightly more complex than I needed (plus I love the colourwheel!)

Anyway, I’ve tweaked the code slightly so that my buttons are lit up all the time on brightness 0.1. What I want to do is have the button I press get brighter, but all I’ve managed to achieve is to make all the buttons get brighter when I press one of them.

Could anyone look at my code & advise how I need to code it? (Can you tell I’m not a python expert?)

while True:
pressed = read_button_states(0, 16)
pixels.brightness = 0.1
for i in range(16):
    pixels[i] = colourwheel(i * 16)

if pressed[0]:
    pixels.brightness = 1

    if not held[0]:
        consumer_control.send(ConsumerControlCode.PLAY_PAUSE)
        held[0] = 1

Hi nfrancis,
The problem is caused by the pixels.brightness=1 line. That tells the microcontroller to set every pixel to maximum brightness when the [0] key is pressed (see: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-dotstar-leds.pdf ).

Ideally you would use pixels[0].brightness=1 to specify just for that pixel, however this fails with:

AttributeError: ‘tuple’ object cannot assign attribute ‘brightness’

You can change the colour of a pixel though with

    pixels[0] = (0,255,0) # green

By that logic you can also change the brightness of a pixel by using a different value, eg (50,0,0) is a dark red where-as (150,0,0) is brighter, up to (255,0,0).

As an example run this code and press the [0] red key (hold down to run on a loop). You will see the brightness gradually increase. Note that I’ve intentionally not put this code in a loop so you can see the numbers used making it easy to experiment.

while True:
    pressed = read_button_states(0, 16)
    pixels.brightness = 0.05

    if pressed[0]:
#        pixels[0].brightness = 1
        pixels[0] = (10,0,0)
        time.sleep(0.5)
        pixels[0] = (50,0,0)
        time.sleep(0.5)
        pixels[0] = (100,0,0)
        time.sleep(0.5)
        pixels[0] = (150,0,0)
        time.sleep(0.5)
        pixels[0] = (200,0,0)
        time.sleep(0.5)
        pixels[0] = (255,0,0)
        time.sleep(0.5)
    
    if not held[0]:
        held[0] = 1

Sorry that’s not a perfect solution but it’s the best my brain can come up with on my morning coffee break. I’ll spend a bit more time thinking about this over lunch.

Hi Colin
That’s really helpful, thank you!

I’d also tried the pixels[0].brightness = 1 & hit the same brick wall.

Hadn’t thought about adjusting the RGB values though. Slightly more challenging with the colour wheel assigning RGB values but I’ll have a crack at implementing it.
Nick

To help I grabbed these for you:

0(255, 0, 0)
1(207, 48, 0)
2(159, 96, 0)
3(111, 144, 0)
4(63, 192, 0)
5(15, 240, 0)
6(0, 222, 33)
7(0, 174, 81)
8(0, 126, 129)
9(0, 78, 177)
10(0, 30, 225)
11(18, 0, 237)
12(66, 0, 189)
13(114, 0, 141)
14(162, 0, 93)
15(210, 0, 45)

If you, for eg, divide numbers by 2 (round up to whole integer) you’d get a half-brightness etc.

The above are then multiplied (and rounded ) by the brightness value. Eg: if pixels.brightness = 0.1 then it is (255*.1) the same as setting:

pixels[0] = (25,0,0)

and if pixels.brightness = 0.5 then:

pixels[0] = (128,0,0) # 255*.5=127.5 rounded up

etc.

Obviously you’d need to manually calculate for all. Then, you set brightness =1 but with “low” numbers for (R,G,B). To make bright you set higher numbers for the same.

That’s amazing - thank you! Code already updated & that works like a dream.

Maybe at some point I’ll dig into the above class or the GitHub when I feel like taking it to the next level.

BTW I used this temporary one-off print()

for i in range(16):
    print(str(i) + str(colourwheel(i*16)))
    pixels[i] = colourwheel(i * 16)

in the loop to retrieve that list.

1 Like

Love this code @ColinD - I’ve got this working following your tutorial and I’m going to add some extra stuff so it can read configuration from a YML file and set the button on, button off or button effects (such as pulse) as well as the key action. Might even make a little UI to configure it.

I’ve uploaded the work in progress to GitHub - kevinmcaleer/pideck

Great work @ColinD!

1 Like

Cheers, glad you’ve got it working.

One thing I would note is that this all dated from early last year. Hence, libraries have been updated and (a) cleaner solution(s) may now exist.