Skip to content

Instantly share code, notes, and snippets.

@trepidacious
Created February 2, 2021 21:57
Show Gist options
  • Save trepidacious/07534dd04df519100e0e3923850a61c6 to your computer and use it in GitHub Desktop.
Save trepidacious/07534dd04df519100e0e3923850a61c6 to your computer and use it in GitHub Desktop.
Pico RGB keypad
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