pimoroni-pico/micropython/examples/keybow2040/usb_rgb_keypad.py

117 wiersze
3.3 KiB
Python

import machine
import usb.device
from usb.device.keyboard import KeyboardInterface, KeyCode
from pimoroni import Button
from is31fl3731 import Matrix_Keybow2040
# A very basic HID Keyboard example for Keybow 2040
# Inspired by: https://github.com/micropython/micropython-lib/blob/master/micropython/usb/examples/device/keyboard_example.py
# This example requires a Pico USB compatible firmware, eg: pico_usb-1.23.0-pimoroni-micropython.uf2
# Don't forget to copy over is31fl3731.py too!
# The pin order for Keybow 2040 is weird,
# But the below is laid out to match the pad with USB up
# from top left to bottom right.
KEYS = {
18: KeyCode.A, 14: KeyCode.B, 10: KeyCode.C, 6: KeyCode.D,
19: KeyCode.E, 15: KeyCode.F, 11: KeyCode.G, 7: KeyCode.H,
20: KeyCode.I, 16: KeyCode.J, 12: KeyCode.K, 8: KeyCode.L,
21: KeyCode.M, 17: KeyCode.N, 13: KeyCode.O, 9: KeyCode.P,
}
# Another look up table for the balmy LED positioning
PIXELS = {
18: (3, 0), 14: (3, 1), 10: (3, 2), 6: (3, 3),
19: (2, 0), 15: (2, 1), 11: (2, 2), 7: (2, 3),
20: (1, 0), 16: (1, 1), 12: (1, 2), 8: (1, 3),
21: (0, 0), 17: (0, 1), 13: (0, 2), 9: (0, 3),
}
# We'll fill this with Button instances
BUTTONS = {}
VALUES = {}
MAX_ON_TIME = 20.0
# 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
class Keybow2040(KeyboardInterface):
def on_led_update(self, led_mask):
pass
def main():
for pin, keycode in KEYS.items():
BUTTONS[pin] = Button(pin, repeat_time=0)
VALUES[pin] = 0
m = Matrix_Keybow2040(machine.I2C(0, 400000))
k = Keybow2040()
usb.device.get().init(k, builtin_driver=True)
keys = [0, 0, 0, 0, 0, 0]
while True:
changed = False
if k.is_open():
for pin, code in KEYS.items():
pressed = BUTTONS[pin].read()
if pressed:
VALUES[pin] = MAX_ON_TIME
# If the key is pressed then try to insert
# it at the first zero. Otherwise (try to) replace
# its keycode with 0 to clear that press.
c = code if pressed else 0
i = 0 if pressed else code
try:
keys[keys.index(i)] = c
changed = True
except ValueError:
# Either our 6-key list is full
# or we're releasing a key that's not in it!
# Or handling a key that isn't pressed.
pass
if changed:
k.send_keys(keys)
for pin, code in KEYS.items():
x, y = PIXELS[pin]
v = VALUES[pin] / MAX_ON_TIME
r, g, b = [int(c * 255) for c in hsv_to_rgb(x / 4.0, 0.7, 1.0 - v)]
m.pixelrgb(x, y, r, g, b)
if VALUES[pin] > 0:
VALUES[pin] -= 1
if __name__ == "__main__":
print("Starting Keybow 2040...")
main()