Raspberry Pi Pico
Neokey x 4 Mini Macropad

Adafruit came up with the Neokey. It combines a hot swappable socket for a mechanical keyboard switch with a neopixel for the LED. The x4 board has 4 of them on a board and is controllable over I2C.

In this photograph, I am using the stemma QT socket on the board to connect to the breadboard. I have an adapter that does that. I have soldered some headers to the board but I am just using the second breadboard for stability. With some creativity, this would be quite quick and easy to mount inside some sort of box or tin.

Pico Circuit

The connections I made were,

  • Power to 3V3
  • GND to GND
  • SDA to GP2
  • SCL to GP3

This project needs some libraries to be downloaded and added to the libs folder on the Pico. The following links are correct at the time of publishing. Using the latest version of CircuitPython, download the zip for the .mpy version of the library. When you unzip that, you will find a folder with the library name. Copy it to the libs folder on your Pico.

This program does everything that the LED Button Keypad did, just with mechanical switches and neopixels for the LEDs.

import board 
import busio 
import time 
import usb_hid 
 
from adafruit_neokey.neokey1x4 import NeoKey1x4 
 
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 
 
kbd = Keyboard(usb_hid.devices) 
layout = KeyboardLayoutUS(kbd) 
cc = ConsumerControl(usb_hid.devices) 
 
# specify I2C pins 
i2c_bus = busio.I2C(board.GP3, board.GP2) 
 
# Create a NeoKey object 
neokey = NeoKey1x4(i2c_bus, addr=0x30) 
 
held = [0]* 4 
 
while True: 
    if neokey[0]: 
        neokey.pixels[0] = 0xFF0000 
        if not held[0]: 
            # writing text and timing 
            layout.write("A message.\n") 
            time.sleep(1) 
            for c in "This is a message for you.": 
                layout.write(c) 
                time.sleep(0.2) 
            layout.write("\n") 
            held[0] = 1 
    elif neokey[1]: 
        neokey.pixels[1] = 0x00FF00 
        if not held[1]: 
            # send a load of key strokes 
            kbd.send(*[Keycode.SHIFT, Keycode.M, Keycode.ENTER]) 
            held[1] = 1 
    elif neokey[2]: 
        neokey.pixels[2] = 0x0000FF 
        if not held[2]: 
            cc.send(ConsumerControlCode.VOLUME_INCREMENT) 
            held[2] = 1 
    elif neokey[3]: 
        neokey.pixels[3] = 0xFFFF00 
        if not held[3]: 
            cc.send(ConsumerControlCode.VOLUME_DECREMENT) 
            held[3] = 1 
    else: 
        # mark the buttons as not pressed 
        held = [0] * 4 
        # clear the colours 
        for i in range(4): 
            neokey.pixels[i] = 0x0 
        # wait a little bit 
        time.sleep(0.1)