Skip to the content
PCBKitNew board
2 layers71.4 × 57.2 mmPico Display Keypad, the printed circuit board in 3D

CircuitPython-based RGB Macro Keypad + Screen

Size
71.4 × 57.2 mm
Copper layers
2
Thickness
1.6 mm
Parts
3
Nets
98
Pads
250
Tracks, vias
96, 3
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
16 Jan 2023
Updated
14 Aug 2026

Overview

Pico Display Keypad is an open-source printed circuit board by YvanDroid, from the YvanDroid/Pico-Display-Keypad repository on GitHub. It is a 2-layer board of 71.4 × 57.2 mm with 3 parts on 98 nets, routed with 96 tracks and 3 vias.

It belongs with the lEDs and displays and keyboards and input boards and the RP2040 boards of this library.

README

README.md

Pico Display Keypad

This is my current setup for using a Rasberry Pi Pico / Pico W with a Pimoroni RGB Keypad Base and their Pico Display Pack 2.0. This code includes a few modifications to the following libraries so that it is able to communicate with both devices at once:

  • the PMK.platform.rgbkeypadbase module

    • The GPIO pins have been changed but the defaults are still in the code if needed, just uncomment the lines and comment the ones not used.
    • There is now an original arrangement for the LED that is an alternative to the Reversed arrangement. It can be changed from there as well to suit your needs.

The Display Pack 2.0 is the main pack connected to the Pico as it requires more pins than the RGB Keypad Base so it's easier to wire up.

Installation

Hardware Connections

To facilitate the use of a Pimoroni Base and a Pack at the same time, I used a headerless Pico and soldered stackable pins with the pins facing down. This allows for connecting the pins to the Display Pack 2.0 directly and the RGB Keypad Base using jumper wires.

GPIO Pin assignment

  • The Display Pack 2.0 uses the default pin layout, so just plug the Pico into the Display Pack 2.0
  • The RGB Keypad Base changes the following pins, going from Keypad Base to Pico:
    • KB_MOSI - Pin 25 (GPIO19) -> Pin 34 (GPIO28)
    • KB_SCLK - Pin 24 (GPIO18) -> Pin 32 (GPIO27)
    • KB_CS - Pin 22 (GPIO17) -> Pin 31 (GPIO26)
  • All other pins are the same on the Keypad Base

PCB Design

A simple PCB design mapping all pins to a board is also present in the Pico-Display-Keypad folder. It can be used as an easier reference for the wiring.

Software

  • Clone this repo
  • Copy the contents of the "pico" folder into your Raspberry Pi Pico / W with CircuitPython 9.2.7 installed

Features

  • Ability to display descriptors for assigned buttons on the screen
  • Able to send key combos when pressing a button
  • Switchable layouts using a modifier key
  • Ability to set colours for each layer
  • Support for Keyboard, Mouse and ConsumerControl Keycodes
  • Turbo Key mode for repetitive key pressing

Details

Currently, each layer definition is stored in a series of mapped dictionary objects. These can be translated into a serialised JSON format and deserialised at runtime. This allows the layouts to be stored in a separate file and the possibility of being edited on a separate device (app in progress) .

Layers

Each layer is made from a dictionary of all the populated layers with each key containing the following:

  • A layer title (layer_title)
  • A default colour for each key that is assigned (layer_colour)
  • A nested dictionary containing information on assigned keys (layer_data)

The anatomy of a layer's data is as follows:

python
layer_titles = {
        1: {                 # The key in the layer to be used. Cannot be 0 as it is the modifier key to switch layers.
        "codes": ConsumerControlCode.VOLUME_DECREMENT, # The keycodes to send. 
                                                       # Refer to adafruit_hid's KeyboardLayoutUS or ConsumerControlCodes for codes
        "title": "Vol -",                              # The key description to be displayed on the screen when layer is active
        "device": "consumer_control",                  # The USB_HID device used to send the input.
        "colours": (255, 255, 0),                      # Optional: Custom colour for the key if you want to differentiate.
    }, ...                                             # Repeat for other keys.
}

The same applies to keyboard inputs, however mouse inputs are a bit different.

python
mouse_layer = {
    1: {
    "buttons": Mouse.LEFT_BUTTON,           # Use buttons for mouse buttons
                                            # Use adafruit_hid's Mouse for codes.
    "wheel" : 3                             # Wheel refers to the mouse wheel, +ive num = up, -ive = down
    "x" : 50                                # X is the direction to move the cursor, + = right, - = left
    "y" : -50                               # Y is the same as X, - = up, + = down.
    "title": "Left Mouse",                  # Title and device are the same
    "device": "mouse"
    },
}

Keyboard Outputs

For single keys, codes: Keycode.KEY_NAME works.

For key combos, you need to use a set so that the code knows to send all keys at the same time.

python
7: {
    "codes": {Keycode.CONTROL, Keycode.SHIFT, Keycode.Z},
    "title": "Stop Sharing",
    "device": "keyboard",
}

Macros can be a combination of integers and sets so that you can send a string of keys in quick succession. A current limitation of this setup is that delays are not supported yet, which means that you won't be able to make macros that require delayed presses. They use the tuple class to differentiate between combos and single keys.

Below is an example of a macro used to make selected text red in Excel. Uncommenting the commented parts also makes it bold.

python
    10: {
        "codes": (
            # {Keycode.CONTROL, Keycode.B},
            Keycode.ALT,
            Keycode.H,
            Keycode.F,
            Keycode.C,
            Keycode.DOWN_ARROW,
            Keycode.DOWN_ARROW,
            Keycode.DOWN_ARROW,
            Keycode.DOWN_ARROW,
            Keycode.DOWN_ARROW,
            Keycode.DOWN_ARROW,
            Keycode.DOWN_ARROW,
            Keycode.RIGHT_ARROW,
            Keycode.ENTER,
        ),
        "title": "Change to red",  # and bold",
        "device": "keyboard",
    },

A list of macros are there already in lib/layers.py. This is also where all of the layers and their keys are stored.

Consumer Control Codes

NOTE: ConsumerControl HID Devices do not support combos or macros, as the module only supports single keystroke.

Consumer control codes only support one button at this time due to the circuitpython library only supporting single buttons. Their layout is largely unchanged from the keyboard

python
media_keys = {
1:{
"codes": ConsumerControlCode.VOLUME_DECREMENT,

"title": "Vol -",

"device": "consumer_control",

"colours": (255, 255, 0),

},
...
}

MIDI

Currently, it only supports single button presses, with a note value being assigned. This was used for pressing buttons to trigger sound effects on a soundboard application, which supported using MIDI in place of keyboard shortcuts.

python
soundboard = {
...
4: {"note": 4, 
	"title": "Fake Discord Ping", 
	"device": "midi"},
...
}

Serialising JSON

The JSON format is used as it has a built-in circuitpython module. This format also closely matches the dictionary format used in python as well, allowing for a quick translation between both formats.

A limitation present in the JSON format is that it does not maintain a distinction between a set and a tuple. Both are converted to a list format when serialising, deleting information about whether a nested list of keys are pressed at the same time or not. To counteract this, the serialiser adds a string at the end of each list to differentiate between a combo or a macro.

Below is an example case

JSON
"9": {
	"codes": [
		[
			224,
			30,
			"combo"
		],
		[
			226,
			5,
			"combo"
		],
		40,
		"macro"
	],
	"device": "keyboard",
	"title": "Change Format"
},

Is derived from the following code

python
9: {
	"codes": (
		{Keycode.CONTROL, Keycode.ONE},
		{Keycode.ALT, Keycode.B},
		Keycode.ENTER,
	),
	"title": "Change Format",
	"device": "keyboard",
},

The encoded values are integers representing the keycodes programmed. If one is aware of the HID spec for Keyboards, you can also edit these values to change it. The adafruit_hid library has a handy set of constants one can use to easily encode the keys instead.

Parts

3
QtyValueFootprintReferences
1Display Pack 2.0 LandingMCU_RaspberryPi_and_Boards:RPi_Pico_SMD_THDisplay 2.0
1Keypad Base LandingMCU_RaspberryPi_and_Boards:RPi_Pico_SMD_THKeypad Base
1PicoMCU_RaspberryPi_and_Boards:RPi_Pico_SMD_THU1

Questions

How big is the Pico Display Keypad PCB?

It measures 71.4 × 57.2 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Pico Display Keypad use?

3 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Pico Display Keypad KiCad files?

From the YvanDroid/Pico-Display-Keypad repository on GitHub, at the commit this page was made from: the board is Pico-Display-Keypad/Pico-Display-Keypad.kicad_pcb and its schematic Pico-Display-Keypad/Pico-Display-Keypad.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Pico Display Keypad design in my own project?

Its repository states no licence, so its author keeps all rights: ask YvanDroid before reusing the design.

Similar boards

  • 2 layers40 × 30 mmBlinky, the printed circuit board in 3D

    Blinky

    earthtojake/text-to-cad

    Design physical products with AI

    3 parts26kMIT
  • 2 layers51.9 × 16 mmPassive2-rpi non standard adapter, the printed circuit board in 3D

    Passive2-rpi non standard adapter

    hzeller/rpi-rgb-led-matrix

    Controlling up to three chains of 64x64, 32x32, 16x32 or similar RGB LED displays using Raspberry Pi GPIO

    3 parts4.4kGPL-2.0
  • 2 layers16.3 × 16.3 mmSensor, the printed circuit board in 3D

    Sensor

    scottbez1/splitflap

    DIY split-flap display

    3 parts4.2k
  • 2 layersSub, the printed circuit board in 3D

    Sub

    atopile/atopile

    Design circuit boards with code! ✨ Get software-like design reuse 🚀, validation, version control and collaboration in hardware; starting with electronics ⚡️

    3 parts4kMIT
  • 2 layers85 × 30 mmDual stomp, the printed circuit board in 3D

    Dual stomp

    torvalds/GuitarPedal

    Linus learns analog circuits

    3 parts2.5kGPL-2.0
  • 2 layers124.5 × 33.7 mm172319-1 connector, the printed circuit board in 3D

    172319-1 connector

    rusefi/rusefi

    rusefi - GPL internal combustion engine control unit

    3 parts1.2k
  • 2 layers10.5 × 83 mmProgrammingAdapter, the printed circuit board in 3D

    ProgrammingAdapter

    stuartpittaway/diyBMSv4

    Version 4 of the diyBMS

    3 parts1.1k
  • 2 layers21.2 × 51.3 mmPico reset, the printed circuit board in 3D

    Pico reset

    hackclub/sprig

    🍃 Learn to code by making games in a JavaScript web-based game editor.

    3 parts1.1kMIT