117 lines
3.3 KiB
Python
117 lines
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()
|