Created
February 2, 2021 21:57
-
-
Save trepidacious/07534dd04df519100e0e3923850a61c6 to your computer and use it in GitHub Desktop.
Pico RGB keypad
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import board | |
import busio | |
import usb_hid | |
from adafruit_bus_device.i2c_device import I2CDevice | |
import adafruit_dotstar | |
from adafruit_hid.keyboard import Keyboard | |
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS | |
from adafruit_hid.keycode import Keycode | |
from adafruit_hid.consumer_control import ConsumerControl | |
from adafruit_hid.consumer_control_code import ConsumerControlCode | |
from digitalio import DigitalInOut, Direction, Pull | |
# Emergency cat GIF example for Pimoroni RGB Keypad for Raspberry Pi Pico | |
# Prerequisites | |
# | |
# Requires Adafruit CircuitPython: https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython | |
# | |
# Also requires the following CircuitPython libs: adafruit_hid, adafruit_bus_device, adafruit_dotstar | |
# (drop them into the lib folder) | |
# | |
# Save this code in code.py on your Raspberry Pi Pico CIRCUITPY drive | |
# | |
# Note that this example is specific for macOS and uses button 0 to trigger the macro. | |
# Pull CS pin low to enable level shifter | |
cs = DigitalInOut(board.GP17) | |
cs.direction = Direction.OUTPUT | |
cs.value = 0 | |
# Set up APA102 pixels | |
num_pixels = 16 | |
pixels = adafruit_dotstar.DotStar(board.GP18, board.GP19, num_pixels, brightness=0.1, auto_write=True) | |
# Set up I2C for IO expander (addr: 0x20) | |
i2c = busio.I2C(board.GP5, board.GP4) | |
device = I2CDevice(i2c, 0x20) | |
# Set up the keyboard | |
kbd = Keyboard(usb_hid.devices) | |
layout = KeyboardLayoutUS(kbd) | |
cc = ConsumerControl(usb_hid.devices) | |
# Function to map 0-255 to position on colour wheel | |
def colourwheel(pos): | |
if pos < 0 or pos > 255: | |
return (0, 0, 0) | |
if pos < 85: | |
return (255 - pos * 3, pos * 3, 0) | |
if pos < 170: | |
pos -= 85 | |
return (0, 255 - pos * 3, pos * 3) | |
pos -= 170 | |
return (pos * 3, 0, 255 - pos * 3) | |
def hv(h, v): | |
h = colourwheel(h) | |
return (h[0] * v * 256 / 65536, h[1] * v * 256 / 65536, h[2] * v * 256 / 65536) | |
# Read button states from the I2C IO expander on the keypad | |
def read_button_states(x, y): | |
pressed = [0] * 16 | |
with device: | |
# Read from IO expander, 2 bytes (8 bits) correspond to the 16 buttons | |
device.write(bytes([0x0])) | |
result = bytearray(2) | |
device.readinto(result) | |
b = result[0] | result[1] << 8 | |
# Loop through the buttons | |
for i in range(x, y): | |
if not (1 << i) & b: | |
pressed[i] = 1 | |
else: | |
pressed[i] = 0 | |
return pressed | |
clicks = [ | |
lambda _: kbd.send(Keycode.CONTROL, Keycode.SHIFT, Keycode.P), | |
lambda _: kbd.send(Keycode.P), | |
lambda _: kbd.send(Keycode.P), | |
lambda _: kbd.send(Keycode.P), | |
lambda _: kbd.send(Keycode.P), | |
lambda _: kbd.send(Keycode.P), | |
lambda _: kbd.send(Keycode.P), | |
lambda _: cc.send(ConsumerControlCode.VOLUME_INCREMENT), | |
lambda _: kbd.send(Keycode.P), | |
lambda _: kbd.send(Keycode.P), | |
lambda _: kbd.send(Keycode.P), | |
lambda _: cc.send(ConsumerControlCode.VOLUME_DECREMENT), | |
lambda _: cc.send(ConsumerControlCode.SCAN_PREVIOUS_TRACK), | |
lambda _: cc.send(ConsumerControlCode.PLAY_PAUSE), | |
lambda _: cc.send(ConsumerControlCode.STOP), | |
lambda _: cc.send(ConsumerControlCode.SCAN_NEXT_TRACK), | |
] | |
# Store energy level for display | |
energy = [0] * num_pixels | |
# debounce - require two successive reads with button pressed before we click | |
debounce = [0] * num_pixels | |
debouncemax = 2 | |
# Keep reading button states, setting pixels | |
while True: | |
pressed = read_button_states(0, 16) | |
for i in range(0, num_pixels): | |
if pressed[i]: | |
energy[i] += 64 | |
debounce[i] += 1 | |
if debounce[i] == debouncemax: | |
clicks[i](0) | |
elif debounce[i] > debouncemax: | |
debounce[i] = debouncemax | |
if energy[i] > 255: | |
energy[i] = 255 | |
else: | |
energy[i] -= 8 | |
debounce[i] = 0 | |
if (energy[i]) < 0: | |
energy[i] = 0 | |
# pixels[i] = (i*3, max(0, int(i*1 - 8)), 64) | |
e = energy[i] | |
# pixels[i] = (max(e, i*6), max(0, int(i*2 - 16)), max(e, 64)) | |
# pixels[i] = (max(e, i*6), max(e, int(i*2 - 16)), max(e, 64)) | |
pixels[i] = (max(e, i*10), max(e, int(i*4 - 32)), max(e, 128)) | |
# pixels[i] = hv(i * 12, energy[i]) | |
# pixels[i] = colourwheel(i * 16) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment