Skip to content

Instantly share code, notes, and snippets.

@codepope
Created February 15, 2021 21:08

Revisions

  1. codepope created this gist Feb 15, 2021.
    135 changes: 135 additions & 0 deletions rgbkeypadcp.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,135 @@
    import board
    import digitalio
    import busio
    import random
    import time

    class PicoRGBkeypad:
    WIDTH=4
    HEIGHT=4
    NUM_PAD=WIDTH*HEIGHT
    CS_PIN=board.GP17
    SCK_PIN=board.GP18
    MOSI_PIN=board.GP19
    BUFFERSIZE=8+NUM_PAD*4
    SDA_PIN=board.GP4
    SCL_PIN=board.GP5
    KEYPAD_ADDRESS=0x20

    def __init__(self):
    self.cs=digitalio.DigitalInOut(self.CS_PIN)
    self.cs.direction=digitalio.Direction.OUTPUT
    self.cs.value=True
    self.spi=busio.SPI(self.SCK_PIN,MOSI=self.MOSI_PIN)

    self.i2c=busio.I2C(self.SCL_PIN,self.SDA_PIN,frequency=40000)

    self.buffer=bytearray(self.BUFFERSIZE)
    self.set_brightness(0.1)
    self.update()

    def update(self):
    self.cs.value=False
    while not self.spi.try_lock():
    pass
    try:
    self.spi.write(self.buffer)
    finally:
    self.spi.unlock()

    def set_brightness(self,b):
    if b<0.0 or b>1.0:
    return
    binval=0b1110000 | int(b*0b11111)
    for i in range(self.NUM_PAD):
    self.buffer[4+i*4] = binval



    def illuminate_xy(self,x,y,r,g,b):
    if x < 0 or x >= self.WIDTH or y < 0 or y >= self.HEIGHT:
    return
    offset = 4 + ((x + (y * self.WIDTH)) * 4)
    self.buffer[offset + 1] = b
    self.buffer[offset + 2] = g
    self.buffer[offset + 3] = r

    def illuminate(self,i,r,g,b):
    offset = 4 + (i * 4)
    self.buffer[offset + 1] = b
    self.buffer[offset + 2] = g
    self.buffer[offset + 3] = r

    def clear(self):
    for i in range(self.NUM_PAD):
    self.illuminate(i,0,0,0)

    def get_button_states(self):
    while not self.i2c.try_lock():
    pass
    try:
    self.i2c.writeto(self.KEYPAD_ADDRESS,bytes([0x0]))
    result=bytearray(2)
    self.i2c.readfrom_into(self.KEYPAD_ADDRESS, result)
    finally:
    self.i2c.unlock()
    return ~((result[0]) | (result[1] << 8)) & 0xffff

    def get_num_pads(self):
    return self.NUM_PAD


    keypad=PicoRGBkeypad()

    # keypad.init()
    keypad.set_brightness(1.0)

    lit = 0
    last_button_states = 0
    colour_index = 0

    NUM_PADS = keypad.get_num_pads()
    while True:
    button_states = keypad.get_button_states()
    if last_button_states != button_states:
    last_button_states = button_states
    if button_states > 0:
    if lit == 0xffff:
    # all buttons are already lit, reset the test
    lit = 0
    colour_index += 1
    if colour_index >= 6:
    colour_index = 0
    else:
    button = 0
    for find in range (0, NUM_PADS):
    # check if this button is pressed and no other buttons are pressed
    if button_states & 0x01 > 0:
    if not (button_states & (~0x01)) > 0:
    lit = lit | (1 << button)
    break
    button_states >>= 1
    button += 1

    for i in range (0, NUM_PADS):
    if (lit >> i) & 0x01:
    if colour_index == 0:
    keypad.illuminate(i, 0x00, 0x20, 0x00)
    elif colour_index == 1:
    keypad.illuminate(i, 0x20, 0x20, 0x00)
    elif colour_index == 2:
    keypad.illuminate(i, 0x20, 0x00, 0x00)
    elif colour_index == 3:
    keypad.illuminate(i, 0x20, 0x00, 0x20)
    elif colour_index == 4:
    keypad.illuminate(i, 0x00, 0x00, 0x20)
    elif colour_index == 5:
    keypad.illuminate(i, 0x00, 0x20, 0x20)
    else:
    keypad.illuminate(i, 0x05, 0x05, 0x05)

    keypad.update()

    time.sleep(0.1)