It's easy to use your NeoKey socket breakouts with CircuitPython and the built-in keypad
module. You can use the key switches to control the NeoPixel LEDs using the Adafruit CircuitPython NeoPixel library. You can create a tiny keyboard using the Adafruit CircuitPython HID library. This page covers how to do both!
CircuitPython Microcontroller Wiring
The first thing you need to do is wire up your NeoKey socket breakouts. The diagram below uses the MX version, but the wiring is identical for the CHOC version.
- QT Py GND to ground rail on breadboard
- QT Py 3V to power rail on breadboard
- Both NeoKey breakouts S+ to power rail on breadboard
- Both NeoKey breakouts S- to ground rail on breadboard
- Both NeoKey breakouts C to ground rail on breadboard
- QT Py A1 to left breakout A
- QT Py A2 to right breakout A
- QT Py A3 to left breakout I
- Left breakout O to right breakout I
- Pi 3.3V to power rail on breadboard
- Pi GND to ground rail on breadboard
- Both NeoKey breakouts S+ to power rail on breadboard
- Both NeoKey breakouts S- to ground rail on breadboard
- Both NeoKey breakouts C to ground rail on breadboard
- Pi GPIO4 to left breakout A
- Pi GPIO17 to right breakout A
- Pi GPIO18 to left breakout I
- Left breakout O to right breakout I
Python Installation of NeoPixel Library
You'll need to install the Adafruit_Blinka library that provides the CircuitPython support in Python.
From your command line run the following commands:
pip3 install adafruit-circuitpython-neopixel
If your default Python is version 3 you may need to run 'pip' instead. Just make sure you aren't trying to use CircuitPython on Python 2.x, it isn't supported!
CircuitPython Usage
To run all of the CircuitPython demos, you need to first install the Adafruit_CircuitPython_NeoPixel library and its dependency. To run the HID demo, you will also need to install the Adafruit_CircuitPython_HID library. To install a library, you copy it into the lib folder on your CIRCUITPY drive. Then you need to update code.py with the example script.
Thankfully, we can do this in one go. In each of the demos, click the Download Project Bundle button to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the code.py file to your CIRCUITPY drive.
You'll find these instructions and details about necessary libraries for each specific demo with all three of the examples below.
Python Usage
Once you have the library pip3
installed on your computer, copy or download the following example to your computer, and run the following, replacing code.py with whatever you named the file:
python3 code.py
Key Press NeoPixel Random Color Demo
Click the Download Project Bundle button to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the code.py file to your CIRCUITPY drive.
Your CIRCUITPY/lib folder should contain the following files:
- adafruit_pixelbuf.mpy
- neopixel.mpy

# SPDX-FileCopyrightText: 2023 Kattni Rembor for Adafruit Industries # # SPDX-License-Identifier: MIT """NeoKey Breakout Random NeoPixel Color Demo""" import random import board import keypad import neopixel from rainbowio import colorwheel # --- CONFIGURATION --- # NeoPixel brightness. Must be a float or integer between 0.0 and 1.0, where 0 is off and # 1 is maximum brightness. Defaults to 0.3. BRIGHTNESS = 0.3 # NeoPixel and key switch pins. If using different pins, update to match your wiring setup. # pylint: disable=simplifiable-condition # Check to see if a Raspberry Pi is present, and set the appropriate pins. if "CE0" and "CE1" in dir(board): # These pins are Pi-specific. PIXEL_PIN = board.D18 KEY_PINS = ( board.D4, board.D17, ) # Otherwise, assume a microcontroller, and set the appropriate pins. else: PIXEL_PIN = board.A3 KEY_PINS = ( board.A1, board.A2, ) # --- SET UP AND CODE --- # Number of NeoPixels. This will always match the number of breakouts and # therefore the number of key pins listed. NUM_PIXELS = len(KEY_PINS) # Create NeoPixel object. pixels = neopixel.NeoPixel(PIXEL_PIN, NUM_PIXELS, brightness=BRIGHTNESS) # Create keypad object. keys = keypad.Keys(KEY_PINS, value_when_pressed=False, pull=True) while True: # Begin getting key events. event = keys.events.get() # If there is a key press event, run this block. if event and event.pressed: # Print the key number of the pressed key. print(f"Key {event.key_number} pressed!") # Light up the corresponding NeoPixel to a random color. pixels[event.key_number] = colorwheel(random.randint(0, 255))
Ensure you have everything copied to your CIRCUITPY drive. Once that is complete, try pressing each key to see the NeoPixel light up a random color!
Customisations
Each of the examples on this page have code at the beginning that includes the things that you can customise. There are three items that are present in all of the demos.
NeoPixel Brightness
Here you can customise the brightness of the NeoPixel LED. The value must be a float or integer between 0.0 and 1.0, where 0 is off, and 1 is maximum brightness. It defaults to 0.3
because NeoPixels at max are very bright!
BRIGHTNESS = 0.3
If you followed the CircuitPython Microcontroller Wiring or Python Computer Wiring diagrams above, you will not need to make any changes to this section of code. However, if you changed any of the connected pins, you will need to update this to match.
Raspberry Pi Pins
If you made changes to the wiring on a Raspberry Pi, you will need to update the first set of pins, nested under if "CE0" and "CE1" in dir(board):
.
If you moved the NeoPixel IN connection to another pin on your Pi, you would update PIXEL_PIN
to the Pi pin to which you connected the left breakout I pin.
If you moved either breakout A connection, you would update KEY_PINS
to match.
Microcontroller Pins
If you made changes to the wiring on a microcontroller, you will need to update the second set of pins, nested under else:
.
If you moved the NeoPixel IN connection to another pin on your microcontroller, you would change PIXEL_PIN
to the microcontroller pin to which you connected the left breakout I pin.
If you moved either breakout A connection, you would update KEY_PINS
to match.
if "CE0" and "CE1" in dir(board): PIXEL_PIN = board.D18 KEY_PINS = ( board.D4, board.D17, ) else: PIXEL_PIN = board.A3 KEY_PINS = ( board.A1, board.A2, )
Set Up
Each of the examples on this page include set up code. The code snippets below are included in all three demos.
Number of NeoPixels
The number of NeoPixels will always be equal to the number of breakouts, and therefore, to the number of key pins. To make this example extensible to more breakouts, NUM_PIXELS
is set to the number of key pins. You will not need to update this if you add more NeoKey breakouts.
NUM_PIXELS = len(KEY_PINS)
NeoPixel and keypad Objects
Next you create the NeoPixel and keypad objects to enable access to the LEDs and the keys.
pixels = neopixel.NeoPixel(PIXEL_PIN, NUM_PIXELS, brightness=BRIGHTNESS) keys = keypad.Keys(KEY_PINS, value_when_pressed=False, pull=True)
Loop
Inside the loop, you first begin getting the key events. This allows you to complete actions based on a specific key event.
event = keys.events.get()
If a key press event happens, two thing will occur.
The code prints the number of the key pressed to the serial console. Remember, Python begins counting at 0!
Finally, it sets the LED associated with the key that you pressed to a random color. colorwheel
expects a color value between 0 and 255, which covers the entire rainbow. Using the built-in random
module, you can set the color to a random value within that range.
if event and event.pressed: print(f"Key {event.key_number} pressed!") pixels[event.key_number] = colorwheel(random.randint(0, 255))
Key Press NeoPixel Rainbow Demo
Click the Download Project Bundle button to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the code.py file to your CIRCUITPY drive.
Your CIRCUITPY/lib folder should contain the following files:
- adafruit_pixelbuf.mpy
- neopixel.mpy

# SPDX-FileCopyrightText: 2023 Kattni Rembor for Adafruit Industries # SPDX-FileCopyrightText: 2023 Dan Halbert for Adafruit Industries # # SPDX-License-Identifier: MIT """NeoKey Breakout NeoPixel Rainbow Cycle Demo""" import time import board import keypad import neopixel from rainbowio import colorwheel # --- CONFIGURATION --- # NeoPixel brightness. Must be a float or integer between 0.0 and 1.0, where 0 is off and # 1 is maximum brightness. Defaults to 0.3. BRIGHTNESS = 0.3 # NeoPixel and key switch pins. If using different pins, update to match your wiring setup. # pylint: disable=simplifiable-condition # Check to see if a Raspberry Pi is present, and set the appropriate pins. if "CE0" and "CE1" in dir(board): # These pins are Pi-specific. PIXEL_PIN = board.D18 KEY_PINS = ( board.D4, board.D17, ) # Otherwise, assume a microcontroller, and set the appropriate pins. else: PIXEL_PIN = board.A3 KEY_PINS = ( board.A1, board.A2, ) # --- SETUP AND CODE --- # Number of NeoPixels. This will always match the number of breakouts and # therefore the number of key pins listed. NUM_PIXELS = len(KEY_PINS) # Create NeoPixel object. pixels = neopixel.NeoPixel(PIXEL_PIN, NUM_PIXELS, brightness=BRIGHTNESS) # Create keypad object. keys = keypad.Keys(KEY_PINS, value_when_pressed=False, pull=True) # Create two lists. # The `pressed` list is used to track the key press state. pressed = [False] * NUM_PIXELS # The `color_value` list is used to track the current color value for a specific NeoPixel. color_value = [0] * NUM_PIXELS while True: # Begin getting key events. event = keys.events.get() if event: # Remember the last state of the key when pressed. pressed[event.key_number] = event.pressed # Advance the rainbow for the key that is currently pressed. for index in range(NUM_PIXELS): if pressed[index]: # Increase the color value by 1. color_value[index] += 1 # Set the pixel color to the current color value. pixels[index] = colorwheel(color_value[index]) time.sleep(0.01)
Ensure you have everything copied to your CIRCUITPY drive. Once that is complete, try pressing each key to see the NeoPixel light up in a rainbow cycle while the key is pressed! Try releasing the key to stop the rainbow cycle.
Customisations
See the Customisations section above for details.
Set Up
For the first part of the set up in this demo, see the Set Up section above for details.
Create Two Lists
The final part of the code set up creates two lists.
The pressed
list is used to track the key press state.
The color_value
list is used to track the current color for a specific NeoPixel.
pressed = [False] * NUM_PIXELS color_value = [0] * NUM_PIXELS
Loop
Inside the loop, you first begin getting the key events. This allows you to complete actions based on a specific key event.
event = keys.events.get()
If there is a key event, used the pressed
list to remember the state of each key when pressed.
if event: pressed[event.key_number] = event.pressed
Rainbow Cycle
This code block advances the rainbow for the key that is currently pressed. Each time a specific key is pressed, the color_value
is increased by 1 for that NeoPixel LED, and then the associated pixel is set to the color using colorwheel
.
The last line in the file is a time.sleep()
to keep things running smoothly.
for index in range(NUM_PIXELS): if pressed[index]: color_value[index] += 1 pixels[index] = colorwheel(color_value[index]) time.sleep(0.01)
Click the Download Project Bundle button to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the code.py file to your CIRCUITPY drive.
# SPDX-FileCopyrightText: 2023 Kattni Rembor for Adafruit Industries # # SPDX-License-Identifier: MIT """ NeoKey Breakout HID Demo WILL NOT WORK ON RASPBERRY PI """ import time import board import keypad import usb_hid import neopixel from adafruit_hid.keyboard import Keyboard from adafruit_hid.keycode import Keycode # --- CONFIGURATION --- # Keycode to send on key press. SEND_ON_PRESS = ( Keycode.B, Keycode.THREE, ) # NeoPixel colors for each key when pressed. COLORS = ( (255, 255, 0), # Yellow (0, 255, 255), # Cyan ) # NeoPixel brightness. Must be a float or integer between 0.0 and 1.0, where 0 is off and # 1 is maximum brightness. Defaults to 0.3. BRIGHTNESS = 0.3 # NeoPixel and key switch pins. Update to match your wiring setup. PIXEL_PIN = board.A3 KEY_PINS = ( board.A1, board.A2, ) # --- SETUP AND CODE --- # Number of NeoPixels. This will always match the number of breakouts and # therefore the number of key pins listed. NUM_PIXELS = len(KEY_PINS) # Create NeoPixel object. pixels = neopixel.NeoPixel(PIXEL_PIN, NUM_PIXELS, brightness=BRIGHTNESS) # Create keypad object. keys = keypad.Keys(KEY_PINS, value_when_pressed=False, pull=True) # Create keyboard object. time.sleep(1) # Delay to avoid a race condition on some systems. keyboard = Keyboard(usb_hid.devices) while True: # Begin getting key events. event = keys.events.get() # If there is a key press event, run this block. if event and event.pressed: # Save the number of the key pressed to `key_number` to use in multiple places. key_number = event.key_number # Light up the corresponding NeoPixel to the appropriate color in the `COLORS` tuple. pixels[key_number] = COLORS[key_number] # Send the appropriate `Keycode` as identified in the `SEND_ON_PRESS` tuple. keyboard.press(SEND_ON_PRESS[key_number]) # If there is a key released event, run this block. if event and event.released: # Turn off the LEDs. pixels[event.key_number] = (0, 0, 0) # Report that the key switch has been released. keyboard.release_all()
Your CIRCUITPY/lib folder should contain the following folder and files:
- adafruit_hid/
- adafruit_pixelbuf.mpy
- neopixel.mpy

Ensure everything is copied to your CIRCUITPY drive. Once that is complete, open up a text editor. Press the left breakout key switch to type b and see the LED light up yellow. Press the right breakout key switch to type 3 and see the LED light up cyan.
Customisations
There are two customisable tuples at the beginning of this demo.
The first contains the keycodes to assign to each key, and is saved to SEND_ON_PRESS
. You can update what each key sends by changing either member of this tuple to a different keycode.
The second contains the colors to light up each LED when the key is pressed, and is saved to COLORS
. You can make the LEDs light up different colors by changing either of the color tuples.
SEND_ON_PRESS = ( Keycode.B, Keycode.THREE, ) COLORS = ( (255, 255, 0), (0, 255, 255), )
For the last two options in this code, see the Customisations section above for details.
Set Up
For the first part of the set up in this demo, see the Set Up section above for details.
The final set up is to create the keyboard object. It includes a delay to avoid a race condition on some systems.
time.sleep(1) keyboard = Keyboard(usb_hid.devices)
Loop
Inside the loop, you first begin getting the key events. This allows you to complete actions based on a specific key event.
event = keys.events.get()
The Key Press Event
If a key is pressed, get the key number and save it to key_number
as it is used multiple times in the rest of this block. Light up the NeoPixel associated with the key to the color associated with that switch's pixel from the COLORS
list. Finally, send the keycode associated with that key from the SEND_ON_PRESS
list.
if event and event.pressed: key_number = event.key_number pixels[key_number] = COLORS[key_number] keyboard.press(SEND_ON_PRESS[key_number])
The Key Release Event
If a key is released, turn off the LED associated with that key, and report that the key switch has been released.
if event and event.released: pixels[event.key_number] = (0, 0, 0) keyboard.release_all()
Page last edited January 21, 2025
Text editor powered by tinymce.