/ ItsyBitsy_Keybow / code.py
code.py
1 # SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 # ItsyBitsy Keypad 6 # Uses ItsyBitsy M4/M0 plus Pimoroni Keybow 7 # To build a customizable USB keypad 8 9 import time 10 import board 11 from digitalio import DigitalInOut, Direction, Pull 12 import usb_hid 13 from adafruit_hid.keyboard import Keyboard 14 from adafruit_hid.keycode import Keycode 15 from adafruit_hid.consumer_control import ConsumerControl 16 from adafruit_hid.consumer_control_code import ConsumerControlCode 17 import adafruit_dotstar as dotstar 18 19 dots = dotstar.DotStar(board.SCK, board.MOSI, 12, brightness=0.4) 20 21 RED = 0xFF0000 22 AMBER = 0xAA9900 23 BLUE = 0x0066FF 24 MAGENTA = 0xFF00FF 25 PURPLE = 0x3B0F85 26 BLACK = 0x000000 27 28 kbd = Keyboard(usb_hid.devices) 29 cc = ConsumerControl(usb_hid.devices) 30 31 orientation = 1 # 0 = portrait/vertical, 1 = landscape/horizontal 32 if orientation == 0: 33 key_dots = [0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11] 34 # 0 #4 #8 35 # 1 #5 #9 36 # 2 #6 #10 37 # 3 #7 #11 38 if orientation == 1: 39 key_dots = [3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8] 40 # 3 #2 #1 #0 41 # 7 #6 #5 #4 42 # 11 #10 #9 #8 43 44 45 def dot_on(dot, color): 46 dots[dot] = color 47 48 49 def dot_off(dot): 50 dots[dot] = BLACK 51 52 53 # Pin definitions 54 if orientation == 0: # 0 = portrait/vertical 55 pins = [ 56 board.D11, 57 board.D12, 58 board.D2, 59 board.D10, 60 board.D9, 61 board.D7, 62 board.A5, 63 board.A4, 64 board.A3, 65 board.A2, 66 board.A1, 67 board.A0, 68 ] 69 if orientation == 1: # 1 = landscape/horizontal 70 pins = [ 71 board.A2, 72 board.A5, 73 board.D10, 74 board.D11, 75 board.A1, 76 board.A4, 77 board.D9, 78 board.D12, 79 board.A0, 80 board.A3, 81 board.D7, 82 board.D2, 83 ] 84 # the two command types -- MEDIA for ConsumerControlCodes, KEY for Keycodes 85 # this allows button press to send the correct HID command for the type specified 86 MEDIA = 1 87 KEY = 2 88 keymap = { 89 (0): (AMBER, MEDIA, ConsumerControlCode.PLAY_PAUSE), 90 (1): (AMBER, MEDIA, ConsumerControlCode.MUTE), 91 (2): (AMBER, MEDIA, ConsumerControlCode.VOLUME_DECREMENT), 92 (3): (AMBER, MEDIA, ConsumerControlCode.VOLUME_INCREMENT), 93 (4): (BLUE, KEY, (Keycode.GUI, Keycode.C)), 94 (5): (BLUE, KEY, (Keycode.GUI, Keycode.V)), 95 (6): (MAGENTA, KEY, [Keycode.UP_ARROW]), 96 (7): (PURPLE, KEY, [Keycode.BACKSPACE]), 97 (8): (BLUE, KEY, [Keycode.SPACE]), 98 (9): (MAGENTA, KEY, [Keycode.LEFT_ARROW]), 99 (10): (MAGENTA, KEY, [Keycode.DOWN_ARROW]), 100 (11): (MAGENTA, KEY, [Keycode.RIGHT_ARROW]), 101 } 102 103 switches = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 104 for i in range(12): 105 switches[i] = DigitalInOut(pins[i]) 106 switches[i].direction = Direction.INPUT 107 switches[i].pull = Pull.UP 108 109 switch_state = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 110 111 print("ItsyBitsy Keybow") 112 113 # Starup lights 114 for k in range(12): 115 dot_on(key_dots[k], RED) 116 time.sleep(0.05) 117 dot_on(key_dots[k], keymap[k][0]) # use individual key colors from set 118 time.sleep(0.05) 119 120 while True: 121 for button in range(12): 122 if switch_state[button] == 0: 123 if not switches[button].value: 124 try: 125 if keymap[button][1] == KEY: 126 kbd.press(*keymap[button][2]) 127 else: 128 cc.send(keymap[button][2]) 129 dot_on(key_dots[button], RED) 130 except ValueError: # deals w six key limit 131 pass 132 print("pressed key{}".format(button)) 133 switch_state[button] = 1 134 135 if switch_state[button] == 1: 136 if switches[button].value: 137 try: 138 if keymap[button][1] == KEY: 139 kbd.release(*keymap[button][2]) 140 dot_on(key_dots[button], keymap[button][0]) 141 except ValueError: 142 pass 143 print("released key{}".format(button)) 144 switch_state[button] = 0 145 146 time.sleep(0.01) # debounce