Git Product home page Git Product logo

keybow2040-circuitpython's Introduction

Keybow 2040 CircuitPython

⚠️ This library is now part of PMK- see: https://github.com/pimoroni/pmk-circuitpython ⚠️

keybow2040-circuitpython is preserved here for posterity.


This CircuitPython library is for the RP2040-powered Keybow 2040 from Pimoroni, a 16-key mini mechanical keyboard with RGB backlit keys. Find out more about Keybow 2040 at the link below.

Learn more about Keybow 2040 at pimoroni.com

It also works on Raspberry Pi Pico mounted in RGB Keypad Base from Pimoroni a 16-key mini rubber keyboard with RGB backlit keys. Find out more about Pico RGB Keypad Base at the link below.

Learn more about Pico RGB Keypad Base at pimoroni.com

The library abstracts away most of the complexity of having to check pin states, and interact with the LED driver library, and exposes classes for individual keys and the whole Keybow (a collection of Key instances).

Keybow 2040 with backlit keys on marble background

Getting started quickly!

Hardware-dependent part

Keybow 2040

You'll need to grab the latest version of Adafruit's Keybow 2040-flavoured CircuitPython, from the link below.

Download the Adafruit CircuitPython binary for Keybow 2040

Unplug your Keybow 2040's USB-C cable, press and hold the button on the top edge of Keybow 2040 while plugging the USB-C cable back into your computer to mount it as a drive (it should show up as RPI-RP2 or something similar).

Drag and drop the adafruit-circuitpython-pimoroni_keybow2040-en_US-XXXXX.uf2 file that you downloaded onto the drive and it should reboot and load the CircuitPython firmware. The drive should now show up as CIRCUITPY.

The Adafruit IS31FL3731 LED driver library for CircuitPython is a prequisite for this Keybow 2040 library, so you'll need to download it from GitHub at the link below, and then drop the adafruit_is31fl3731 folder into the lib folder on your CIRCUITPY drive.

Download the Adafruit IS31FL3731 CircuitPython library

Pico RGB Keypad

You'll need to grab the latest version of Adafruit's Raspberry Pi Pico-flavoured CircuitPython, from the link below.

Download the Adafruit CircuitPython binary for Raspberry Pi Pico

Unplug your Pi Pico's micro USB cable, press and hold the BOOTSEL button on the top of Pi Pico while plugging the micro USB cable back into your computer to mount it as a drive (it should show up as RPI-RP2 or something similar).

Drag and drop the adafruit-circuitpython-raspberry_pi_pico-en_US-XXXXX.uf2 file that you downloaded onto the drive and it should reboot and load the CircuitPython firmware. The drive should now show up as CIRCUITPY.

The Adafruit DotStar LED driver library for CircuitPython is a prequisite for this Keybow 2040 library, so you'll need to download it from GitHub at the link below, and then drop the adafruit_dotstar.py file into the lib folder on your CIRCUITPY drive.

[Download the Adafruit DotStar CircuitPython library](<https://github.com/adafruit/Adafruit_CircuitPython_DotStar)

Hardware-independent part

Finally, drop the lib contents (keybow2040.py file and keybow_hardware folder) from this library into the lib folder on your CIRCUITPY drive also, and you're all set!

Pick one of the examples (I'd suggest the reactive.press.py example to begin), copy the code, and save it in the code.py file on your CIRCUITPY drive using your favourite text editor. As soon as you save the code.py file, or make any other changes, then it should load up and run the code!

Examples are by default using Keybow 2040 hardware, if you want to run them on Pico RGB Keypad, you need to change the hardware. Comment out the line:

from keybow_hardware.pim56x import PIM56X as Hardware

and uncomment the line:

from keybow_hardware.pim551 import PIM551 as Hardware

Index

Library functionality

This section covers most of the functionality of the library itself, without delving into additional functions like USB MIDI or HID (they're both covered later!)

Imports and setup

All of your programs will need to start with the following:

from keybow_hardware.pim56x import PIM56X as Hardware
from keybow2040 import Keybow2040

hardware = Hardware()
keybow = Keybow2040(hardware)

First, this imports a hardware object representing the board. A hardware object hides technical details on how keys and LEDs are connected and exposes them via uniform interface. You need to choose the correct hardware object for your hardware. If you're curious, hardware differences are explained below, but all you need to know is that for Keybow 2040 you need an import:

from keybow_hardware.pim56x import PIM56X as Hardware

and for Pico RGB Keypad Base:

from keybow_hardware.pim551 import PIM551 as Hardware

On Keybow 2040 (PIM56X) keys are read directly via GPIO, and LEDs are set via IS31FL3731 LED driver connected over I2C bus.

On Pico RGB Keypad Base (PIM551) keys are connected via TCA9555 GPIO extender connected over I2C bus and LEDs are DotStar LEDs connected via SPI bus.

Since both boards use I2C bus, hardware object also exposes it in case you need to access it (Keybow 2040 has even I2C connecting pads exposed): i2c = hardware.i2c()

In the rest of this file examples of the code will use PIM56X hardware object. If you're running them on Pico RGB Keypad Base, don't forget to change it accordingly.

The Keybow2040() class, imported from the keybow2040 module, is instantiated and passed the hardware object. Instantiating this sets up all of the pins, keys, and LEDs, and provides access to all of the attributes and methods associated with it.

The Keybow class

The Keybow class exposes a number of handy attributes and methods. The main one you'll be interested in is the .keys attribute, which is a list of Key class instances, one for each key.

keys = keybow.keys

The indices of the keys in that list correspond to their position on the keypad, staring from the bottom left corner (when the USB connector is at the top), which is key 0, going upwards in columns, and ending at the top right corner, which is key 15.

More about the Key class later...

A super important method of the Keybow class is .update() method. It updates all of the keys, key states, and other attributes like the time of the last key press, and sleep state of the LEDs.

You need to call this method on your Keybow class at the very start of each iteration of your program's main loop, as follows:

while True:
    keybow.update()

An interlude on timing!

Another super important thing is not to include any time.sleep()s in your main loop! Doing so will ruin the latency and mean that you'll miss key press events. Just don't do it.

If you need introduce timed events, then you have to go about it in a slightly (!!) roundabout fashion, by using time.monotonic() a constantly incremented count of seconds elapsed, and use it to check the time elapsed since your last event, for example you could do this inside your while True loop:

time_interval = 10

# An event just happened!

time_last_fired = time.monotonic()
time_elapsed = 0

# ... some iterations later

time_elapsed = time.monotonic() - time_last_fired

if time_elapsed > time_interval:
    # Fire your event again!

There's a handy keybow.time_of_last_press attribute that allows you to quickly check if a certain amount of time has elapsed since any key press, and that attribute gets updated every time keybow.update() is called.

Key presses

There are a few ways that you can go about detecting key presses, some global methods on the Keybow class instance, and some on the Key class instances themselves.

Keybow class methods for detecting presses and key states

keybow.get_states() will return a list of the state of all of the keys, in order, with a state of 0 being not pressed, and 1 being pressed. You can then loop through that list to do whatever you like.

keybow.get_pressed() will return a list of the key numbers (indices in the list of keys) that are currently pressed. If you only care about key presses, then this is an efficient way to do things, especially since you have all the key numbers in a list.

keybow.any_pressed() returns a Boolean (True/False) that tells you whether any keys are currently being pressed. Handy if you want to attach a behaviour to all of the keys, which this is effectively a proxy for.

keybow.none_pressed() is similar to .any_pressed(), in that it returns a Boolean also, but... you guessed it, it returns True if no keys are being pressed, and False if any keys are pressed.

Key class methods for detecting key presses

If we want to check whether key 0 is pressed, we can do so as follows:

keys = keybow.keys()

while True:
    keybow.update()

    if keys[0].pressed:
        # Do something!

The .pressed attribute returns a Boolean that is True if the key is pressed and False if it is not pressed.

key.state is another way to check the state of a key. It will equal 1 if the key is pressed and 0 if it is not pressed.

If you want to attach an additional behaviour to your key, you can use key.held to check if a key is being key rather than being pressed and released quickly. It returns True if the key is held and False if it is not.

The default hold time (after which key.held is True) for all of the keys is 0.75 seconds, but you can change key.hold_time to adjust this to your liking, on a per key basis.

This means that we could extend the example above to be:

keys = keybow.keys()

while True:
    keybow.update()

    if keys[0].pressed:
        # Do something!

    if keys[0].held:
        # Do something else!

The reactive-press.py example shows in more detail how to handle key presses.

LEDs!

LEDs can be set either globally for all keys, using the Keybow class instance, or on a per-key basis, either through the Keybow class, or using a Key class instance.

To set all of the keys to the same colour, you can use the .set_all() method of the Keybow class, to which you pass three 0-255 integers for red, green, and blue. For example, to set all of the keys to magenta:

keybow.set_all(255, 0, 255)

To set an individal key through your Keybow class instance, you can do as follows, to set key 0 to white:

keybow.set_led(0, 255, 255, 255)

To set the colour on the key itself, you could do as follows, again to set key 0 to white:

keybow.keys[0].set_led(255, 255, 255)

A key retains its RGB value, even if it is turned off, so once a key has its colour set with key.rgb = (255, 0, 0) for example, you can turn it off using key.led_off() or even key.set_led(0, 0, 0) and then when you turn it back on with key.led_on(), then it will still be red when it comes back on.

As a convenience, and to avoid having to check key.lit, there is a key.toggle_led() method that will toggle the current state of the key's LED (on to off, and vice versa).

There's a handy hsv_to_rgb() function that can be imported from the keybow2040 module to convert an HSV colour (a tuple of floats from 0.0 to 1.0) to an RGB colour (a tuple of integers from 0 to 255), as follows:

from keybow2040 import hsv_to_rgb

h = 0.5  # Hue
s = 1.0  # Saturation
v = 1.0  # Value

r, g, b = hsv_to_rgb(h, s, v)

The rainbow.py example shows a more complex example of how to animate the keys' LEDs, including the use of the hsv_to_rgb() function.

LED sleep

The Keybow class has an .led_sleep_enabled attribute that is disabled (set to False) by default, and an .led_sleep_time attribute (set to 60 seconds by default) that determines how many seconds need to elapse before LED sleep is triggered and the LEDs turn off.

The time elapsed since the last key press is constantly updated when keybow.update() is called in your main loop, and if the .led_sleep_time is exceeded then LED sleep is triggered.

Because keys retain their RGB values when toggled off, when asleep, a tap on any key will wake all of the LEDs up at their last state before sleep.

Enabling LED sleep with a sleep time of 10 seconds could be done as simply as:

keybow.led_sleep_enabled = True
keybow.led_sleep_time = 10

There's also a .sleeping attribute that returns a Boolean, that you can check to see whether the LEDs are sleeping or not.

Attaching functions to keys with decorators

There are three decorators that can be attached to functions to link that function to, i) a key press, ii) a key release, or iii) a key hold.

Here's an example of how you could attach a decorator to a function that lights up that key yellow when it is pressed, turns all of the LEDs on when held, and turns them all off when released:

from keybow_hardware.pim56x import PIM56X as Hardware
from keybow2040 import Keybow2040

keybow = Keybow2040(Hardware())
keys = keybow.keys

key = keys[0]
rgb = (255, 255, 0)
key.rgb = rgb

@keybow.on_press(key)
def press_handler(key):
    key.led_on()

@keybow.on_release(key)
def release_handler(key):
    keybow.set_all(0, 0, 0)

@keybow.on_hold(key)
def hold_handler(key):
    keybow.set_all(*rgb)

while True:
    keybow.update()

The decorators.py example has another example of how to use the .on_hold() decorator to toggle LEDs on and off when a key is held.

Key combos

Key combos can provide a way to add additional behaviours to keys that only get triggered if a combination of keys is pressed. The best way to achieve this is using the .held attribute of a key, meaning that the key can also have a .pressed behaviour too.

Here's a brief example of how you could do this inside your main loop, with key 0 as the modifier key, and key 1 as the action key:

keys = keybow.keys

modifier_key = keys[0]
action_key = keys[1]

while True:
    keybow.update()

    if modifier_key.held and action_key.pressed:
        # Do something!

Of course, you could chain these together, to require two modifer keys to be held and a third to be pressed, and so on...

The colour-picker.py example has an example of using a modifier key to change the hue of the keys.

USB HID

This covers setting up a USB HID keyboard and linking physical key presses to keyboard key presses on a connected computer.

Setup

USB HID requires the adafruit_hid CircuitPython library. Download it from the link below and drop the adafruit_hid folder into the lib folder on your CIRCUITPY drive.

Download the Adafruit HID CircuitPython library

You'll need to connect your Keybow to a computer using a USB cable, just like you would with a regular USB keyboard.

Sending key presses

Here's an example of setting up a keyboard object and sending a 0 key press when key 0 is pressed, using an .on_press() decorator:

from keybow_hardware.pim56x import PIM56X as Hardware
from keybow2040 import Keybow2040

import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

keybow = Keybow2040(Hardware())
keys = keybow.keys

keyboard = Keyboard(usb_hid.devices)
layout = KeyboardLayoutUS(keyboard)

key = keys[0]

@keybow.on_press(key)
def press_handler(key):
    keyboard.send(Keycode.ZERO)

while True:
    keybow.update()

You can find a list of all of the keycodes available at the HID CircuitPython library documentation here.

If you wanted to take this a bit further and make a full keymap for your keyboard, then you could create a list of 16 different keycodes and then use the number of the key press registered by the press_handler function as an index into your keymap to get the keycode to send for each key.

from keybow_hardware.pim56x import PIM56X as Hardware
from keybow2040 import Keybow2040

import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

keybow = Keybow2040(Hardware())
keys = keybow.keys

keyboard = Keyboard(usb_hid.devices)
layout = KeyboardLayoutUS(keyboard)

keymap =    [Keycode.ZERO,
             Keycode.ONE,
             Keycode.TWO,
             Keycode.THREE,
             Keycode.FOUR,
             Keycode.FIVE,
             Keycode.SIX,
             Keycode.SEVEN,
             Keycode.EIGHT,
             Keycode.NINE,
             Keycode.A,
             Keycode.B,
             Keycode.C,
             Keycode.D,
             Keycode.E,
             Keycode.F]

for key in keys:
    @keybow.on_press(key)
    def press_handler(key):
        keycode = keymap[key.number]
        keyboard.send(keycode)

while True:
    keybow.update()

This code is available in the hid-keys-simple.py example.

As well as sending a single keypress, you can send multiple keypresses at once, simply by adding them as additional argumemnts to keyboard.send(), e.g. keyboard.send(Keycode.A, Keycode.B) and so on.

Sending strings of text

Rather than the incovenience of sending multiple keycodes using keyboard.send(), there's a different method to send whole strings of text at once, using the layout object we created.

from keybow_hardware.pim56x import PIM56X as Hardware
from keybow2040 import Keybow2040

import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

keybow = Keybow2040(Hardware())
keys = keybow.keys

keyboard = Keyboard(usb_hid.devices)
layout = KeyboardLayoutUS(keyboard)

key = keys[0]

@keybow.on_press(key)
def press_handler(key):
    layout.write("Pack my box with five dozen liquor jugs.")

while True:
    keybow.update()

A press of key 0 will send that whole string of text at once!

Be aware that strings sent like that take a little while to virtually "type", so you might want to incorporate a delay using keybow.time_of_last_press, and then check against a time_elapsed variable created with time_elapsed = time.monotonic() - keybow.time_of_last_press.

Also, be aware that the Adafruit HID CircuitPython library only currently supports US Keyboard layouts, so you'll have to work around that and map any keycodes that differ from their US counterpart to whatever your is.

USB MIDI

This covers basic MIDI note messages and how to link them to key presses.

Setup

USB MIDI requires the adafruit_midi CircuitPython library. Download it from the link below and then drop the adafruit_midi folder into the lib folder on your CIRCUITPY drive.

Download the Adafruit MIDI CircuitPython library

You'll need to connect your Keybow 2040 with a USB cable to a computer running a software synth or DAW like Ableton Live, to a hardware synth that accepts USB MIDI, or through a MIDI interface that will convert the USB MIDI messages to regular serial MIDI through a DIN connector.

Using USB MIDI, Keybow 2040 shows up as a device with the name Keybow 2040 (CircuitPython usb midi.ports[1])

In my testing, Keybow 2040 works with the Teenage Engineering OP-Z quite nicely.

Sending MIDI notes

Here's a complete, minimal example of how to send a single MIDI note (middle C, or MIDI note number 60) when key 0 is pressed, sending a note on message when pressed and a note off message when released.

from keybow_hardware.pim56x import PIM56X as Hardware
from keybow2040 import Keybow2040

import usb_midi
import adafruit_midi
from adafruit_midi.note_off import NoteOff
from adafruit_midi.note_on import NoteOn

keybow = Keybow2040(Hardware())
keys = keybow.keys

midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0)

key = keys[0]
note = 60
velocity = 127

was_pressed = False

while True:
    keybow.update()

    if key.pressed:
        midi.send(NoteOn(note, velocity))
        was_pressed = True
    elif not key.pressed and was_pressed:
        midi.send(NoteOff(note, 0))
        was_pressed = False

There'a more complete example of how to set up all of Keybow's keys with associated MIDI notes using decorators in the midi-keys.py example.

The example above, and the midi-keys.py example both send notes on MIDI channel 0 (all channels), but you can set this to a specific channel, if you like, by changing out_channel= when you instantiate your midi object.

keybow2040-circuitpython's People

Contributors

dynamonic avatar freekyfrank avatar gadgetoid avatar matemaciek avatar sandyjmacdonald avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

keybow2040-circuitpython's Issues

Keybow crashes if key pressed when computer is not running

I've observed that if the Keybow is powered but the computer it's attached to is not running, then the Keybow will crash. This is because in the depths of circuitpython, the send_report function will timeout, which will raise an Exception (I think an OSError, but not sure), which won't be caught, thus crashing the Keybow. That's not ideal.

I've hacked together a fix, but this repository seems somewhat abandoned, so I'd like to get confirmation that it's alive before putting some effort into tidying it up and submitting it as a patch.

Running any example crashes

Hey there, thanks for providing the extensive docs to get started.

I somehow run into an exception with using this lib.

I'm running (also tried with 7.0 & 7.1.0-rc.0)

Adafruit CircuitPython 7.1.0-beta.3 on 2021-12-13; Pimoroni Keybow 2040 with rp2040
Board ID:pimoroni_keybow2040

The exception:

code.py output:
Traceback (most recent call last):
  File "code.py", line 14, in <module>
  File "/lib/keybow2040.py", line 68, in __init__
  File "/lib/adafruit_is31fl3731/__init__.py", line 99, in __init__
  File "/lib/adafruit_is31fl3731/__init__.py", line 146, in _init
  File "/lib/adafruit_is31fl3731/__init__.py", line 169, in sleep
  File "/lib/adafruit_is31fl3731/__init__.py", line 135, in _register
  File "/lib/adafruit_is31fl3731/__init__.py", line 131, in _bank
  File "/lib/adafruit_is31fl3731/__init__.py", line 118, in _i2c_write_reg
AttributeError: 'PIM56X' object has no attribute 'try_lock'

I tried debugging by myself, but with limited success. Any help much appreciated.

Could this work with the Pico Keypad?

Hi,
I was wondering if this lib could work with the pico keypad as i love the advanced hid you created.

apologies if i have done this wrong i am a git noobie.

kind regards

Tempusfugit.

BOOTSEL button as user input

While 16 buttons are a lot for macro actions, in my use case I've maxed out and used every single one of them. It would be awesome to be able to use the BOOTSELbutton as a quick way to turn off the lights (for example, or trigger other actions), but it doesn't seem to be mapped in this library. Can someone point out to me, what I have to change to get that, or maybe it could be even implemented here? I'm sure some users could benefit from it.
Thanks!

keybow 2040 keyboard library problem

If this is the wrong place to raise this issue then please close it and tell me where I should go.

When I tried to upgrade my Keybow 2040 to the latest software, the "from adafruit_hid.key[...anything...]" dependencies broke. The reactive-press.py and rainbow.py still work fine, but the hid-key*.py do not work, I can no longer use the keybow 2040 as a keyboard.

I downloaded these versions :

https://circuitpython.org/board/pimoroni_keybow2040/
md5sum = 87d600d81cbe0d5590868b3b74f3f0d1 *adafruit-circuitpython-pimoroni_keybow2040-en_US-7.0.0.uf2

...
File: boot_out.txt :
Adafruit CircuitPython 7.0.0 on 2021-09-20; Pimoroni Keybow 2040 with rp2040
Board ID:pimoroni_keybow2040
...

https://github.com/adafruit/Adafruit_CircuitPython_IS31FL3731
md5sum = e1038d6621566df25c6baa831d105e94 *Adafruit_CircuitPython_IS31FL3731-main.zip

...
commit 06896940f91b8b0084d0a100f38398a02280ce16
Date: Tue Nov 23 13:03:03 2021 -0600
...

https://github.com/pimoroni/keybow2040-circuitpython
md5sum = 0f7540daf9aa6a260fa49b3fae8835a1 *keybow2040-circuitpython-master.zip

...
commit 7770d33
Date: Fri Nov 5 15:45:45 2021 +0000
...

This issue may be an error on my part but I would like to request a table of the different software versions that were tested together. I want to "sync" my keybow 2040 to known compatible sofware versions. If I had this then it would place the onus on me to make sure I am doing everything correctly.

Thank you for all the hard work everyone put into this.

Receive HID packets

Hi, I'm searching high and low for a solution to receive packets of data on the keybow. While sending in HID mode is available in examples and the Adafruit library, I'd appreciate an example to receive packets.

My scenario: any button on the keybow is in 'master' mode. I.e. the device it controls on my network is controlled from the pad. Pad to device. I use it to control IoT devices. However, I would like to read events or statuses, say, by changing button color. Device on network to button on keybow.

Thanks for any tips. MQTT status reading and sending to keybow would be awesome

Thanks

Way to switch off the Rainbow with Keyheld ?

I'm a little stuck, and this is technically not an issue for a PR, but possibly a very viable example update if it can be working. I have combined and have working well the HID and rainbow examples as can be seen at https://gist.github.com/wildestpixel/2a2c36aea8ccbf7054aab0d372e23db3 to effect a controller for Moode Audio.

Pretty as this is I have tried to recode to switch off the rainbow effect at night with a long key press below (yes I know it follows a normal keypress but I'm cool with that as it can be on mpc stop for example).

Problem is that this doesn't increment my counter by 1 and doesn't switch off the rainbow as the output of counter is always "0". I want to be able to achieve a manner of having rainbow and being able to switch it off - not necessarily correcting my code, but as an example modification of the current rainbow.py as I think it would be very useful for users to be able to switch off the lovely lights when they need them off.

import board
import math
from keybow2040 import Keybow2040, number_to_xy, hsv_to_rgb

import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

# Set up Keybow
i2c = board.I2C()
keybow = Keybow2040(i2c)
keys = keybow.keys

# Set up the keyboard and layout
keyboard = Keyboard(usb_hid.devices)
layout = KeyboardLayoutUS(keyboard)

# A map of keycodes that will be mapped sequentially to each of the keys, 0-15
keymap =    ["rad1",
             "rad1",
             "mpc toggle",
             "toggle_disp1",
             "rad2",
             "rad2",
             "mpc stop",
             "volm",
             "rad3",
             "rad3",
             "mpc prev",
             "vold",
             "rad4",
             "rad4",
             "mpc next",
             "volu"]

# The colour to set the keys when pressed, yellow.
rgb = (255, 255, 255)

# Increment step to shift animation across keys.
step = 0


def rainbow():
    for i in range(16):
        x, y = number_to_xy(i)
        hue = (x + y + (step / 20)) / 8
        hue = hue - int(hue)
        hue = hue - math.floor(hue)
        r, g, b = hsv_to_rgb(hue, 1, 1)
        # Display it on the key!
        keys[i].set_led(r, g, b)

def rainbowoff():
    for i in range(16):
        x, y = number_to_xy(i)
        hue = (x + y + (step / 20)) / 8
        hue = hue - int(hue)
        hue = hue - math.floor(hue)
        r, g, b = hsv_to_rgb(hue, 1, 1)
        # Don't display it on the key!
        keys[i].set_led(0, 0, 0)

def countup(counter):
    counter = (counter + 1) % len(things)

counter = 0
things = [ rainbow, rainbowoff ]

# Attach handler functions to all of the keys
for key in keys:
    # A press handler that sends the keycode and turns on the LED
    @keybow.on_press(key)
    def press_handler(key):
        keycode = keymap[key.number]
        layout.write(keycode)
        keyboard.send(Keycode.ENTER)
        key.set_led(*rgb)

    @keybow.on_hold(key)
    def hold_handler(key):
        countup(counter)
        print(counter)

while True:
    # Always remember to call keybow.update()!
    keybow.update()

    step += 1
    things[counter]()

Any help would be greatly appreciated. Also posted in similar vein at https://forums.adafruit.com/viewtopic.php?f=60&t=177038&p=870066#p870066

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.