Text Editor
Adafruit recommends using the Mu editor for editing your CircuitPython code. You can get more info in this guide.
Alternatively, you can use any text editor that saves simple text files.
Download the Project Bundle
Your project will use a specific set of CircuitPython libraries and the code.py file. In order to get the libraries you need, click on the Download Project Bundle link below, and uncompress the .zip file.
Drag the contents of the uncompressed bundle directory onto your Feather board's CIRCUITPY drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.
# SPDX-FileCopyrightText: Copyright (c) 2021 John Park for Adafruit # # SPDX-License-Identifier: MIT # Deco Keypad import time import board from digitalio import DigitalInOut, Pull from adafruit_debouncer import Debouncer import usb_hid from adafruit_hid.keyboard import Keyboard from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS from adafruit_hid.keycode import Keycode import neopixel print("- Deco Keypad -") time.sleep(1) # Sleep for a bit to avoid a race condition on some systems # ----- Keymap ----- # # change as needed, e.g. capital A (Keycode.SHIFT, Keycode.A) switch_a_output = Keycode.Z switch_b_output = Keycode.X # ----- Keyboard setup ----- # keyboard = Keyboard(usb_hid.devices) keyboard_layout = KeyboardLayoutUS(keyboard) # We're in the US :) # ----- Key setup ----- # switch_a_in = DigitalInOut(board.D5) switch_b_in = DigitalInOut(board.D6) switch_a_in.pull = Pull.UP switch_b_in.pull = Pull.UP switch_a = Debouncer(switch_a_in) switch_b = Debouncer(switch_b_in) # ----- NeoPixel setup ----- # MAGENTA = 0xFF00FF CYAN = 0x0088DD WHITE = 0xCCCCCC BLACK = 0x000000 pixel_pin = board.D9 pixels = neopixel.NeoPixel(pixel_pin, 2, brightness=1.0) pixels.fill(BLACK) time.sleep(0.3) pixels.fill(WHITE) time.sleep(0.3) pixels.fill(BLACK) time.sleep(0.3) pixels[0] = MAGENTA pixels[1] = CYAN while True: switch_a.update() # Debouncer checks for changes in switch state switch_b.update() if switch_a.fell: keyboard.press(switch_a_output) pixels[0] = WHITE if switch_a.rose: keyboard.release(switch_a_output) pixels[0] = MAGENTA if switch_b.fell: keyboard.press(switch_b_output) pixels[1] = WHITE if switch_b.rose: keyboard.release(switch_b_output) pixels[1] = CYAN
To adjust the key mapping of the keys, look for this section of the code:
# ----- Keymap ----- # # change as needed, e.g. capital A (Keycode.SHIFT, Keycode.A) switch_a_output = Keycode.Z switch_b_output = Keycode.X
switch_a
is the keyswitch closer to the USB port. You can use single keystrokes, or multi-key combos as shown in the comment.
For more info on using USB HID keycodes, check out this documentation.
Libraries
The code first imports libraries to help out with a number of tasks, including time
, board
for pin definitions, digitalio
and adafruit_debouncer
to simplify key press and release detection, usb_hid
and adafruit_hid.keyboard
, plus neopixel
.
import time import board from digitalio import DigitalInOut, Pull from adafruit_debouncer import Debouncer import usb_hid from adafruit_hid.keyboard import Keyboard from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS from adafruit_hid.keycode import Keycode import neopixel
Keyboard Setup
This section sets the keymapping, keyboard setup, and pin setup with digitalio and debouncer.
switch_a_output = Keycode.Z switch_b_output = Keycode.X # ----- Keyboard setup ----- # keyboard = Keyboard(usb_hid.devices) keyboard_layout = KeyboardLayoutUS(keyboard) # We're in the US :) # ----- Key setup ----- # switch_a_in = DigitalInOut(board.D5) switch_b_in = DigitalInOut(board.D6) switch_a_in.pull = Pull.UP switch_b_in.pull = Pull.UP switch_a = Debouncer(switch_a_in) switch_b = Debouncer(switch_b_in)
NeoPixels
You'll create some color definitions and set up the two on-board NeoPixels next. Once they're set up, you'll give them a little startup blink so you know when the board has been reset.
# ----- NeoPixel setup ----- # MAGENTA = 0xFF00FF CYAN = 0x0088DD WHITE = 0xCCCCCC BLACK = 0x000000 pixel_pin = board.D9 pixels = neopixel.NeoPixel(pixel_pin, 2, brightness=1.0) pixels.fill(BLACK) time.sleep(0.3) pixels.fill(WHITE) time.sleep(0.3) pixels.fill(BLACK) time.sleep(0.3) pixels[0] = MAGENTA pixels[1] = CYAN
Main Loop
The main code loop uses the debouncer to check both switches.
When either switch is pressed, the debouncer
notices that it fell
(voltage goes from high to low since we're using the built-in pull up resistor on each digital pin). Then, the keyboard.press()
command sends the keyboard output for the associated key, and sets the NeoPixel to white.
When the debouncer
registers that it rose
, this means the key has been released, and the keyboard.release()
command is sent for that keycode. The NeoPixel color returns to its default for that key.
switch_a.update() # Debouncer checks for changes in switch state switch_b.update() if switch_a.fell: keyboard.press(switch_a_output) pixels[0] = WHITE if switch_a.rose: keyboard.release(switch_a_output) pixels[0] = MAGENTA if switch_b.fell: keyboard.press(switch_b_output) pixels[1] = WHITE if switch_b.rose: keyboard.release(switch_b_output) pixels[1] = CYAN