Raspberry Pi Pico Macro Pad

Introduction

Homebuilt mechanical keyboards and macro pads are nothing new, usually powered by a teensy or an Arduino Pro Micro because of their HID device capabilities. These hand wired boards are programmed in C or via a key mapping program such as QMK.

There is a new contender to the Teensy and Pro Micro – the Raspberry Pi Pico. The Pico has several obvious benefits including the Price, amount of GPIO and the fact that it can be programmed in CircuitPython. There is a lack of QMK support although this appears to be being worked on!

I plan to design, build and open source a 60% 3D printed hand wired Mechanical Keyboard in the near future and I needed to get some practice with the Pico. I decided to build a 9 key Macro Pad using a design from V0id on thingiverse. Lets take a look at the VOID9.

Void9 Macropad

Void9 Macro pad
Void9 Macropad – Image source: https://victorlucachi.ro/showcase/void9/

The void9 is a 3d printed macro pad designed by Victor Lucachi. Designed to take 9x Cherry MX style switches and key caps.

Originally designed to use an Arduino pro micro or clone although the Raspberry Pi Pico fits almost perfectly! I printed this on my £55 EasyThreed X1 3d Printer in flashforge black filament.

The design is clean and easy to print requiring no supports or rafts.

Assembling the Raspberry Pi Pico Macropad

Assembling the Raspberry Pi Pico Macro pad was actually pretty easy! Down to the vast amount of GPIO on the Raspberry Pi Pico I didn’t bother with a matrix meaning less parts as no diodes are required.

I started by snapping the MX style switches into the macro pad, these can be hot glued down if needed but mine were very tight!

Raspberry Pi Pico Void9 Macro pad

I used left over switches from previous projects so it is a little miss matched with vintage cherry blacks for the bottom row and outemu blue switches on the top two rows.

Raspberry Pi Pico Macro pad wiring
Void9 Raspberry Pi Pico Macro Pad diagram

The (badly drawn) diagram above shows how I wired the macro pad, a common ground is used across all switches which goes to the first ground pin on the Pico. Each switch then goes to its own GPIO pin – starting from 0.

This is about as simple as it gets in terms of wiring a macro pad!

Here is the completed wired pad:

Raspberry Pi Pico Macro Pad Wiring

I simply held the Pico in with a few plastic welds through the lower mounting holes using a 3d pen.

I then assembled both parts using 4x m3 screws.

Assembled Raspberry Pi Pico Macro Pad
The fully assembled Raspberry Pi Pico Macro Pad

Coding the Pico Macro Pad using Circuit Python

Using an example from Adafruit I modified it to suit the 3×3 layout of the void9 macro pad.

This file was edited using Mu.

# SPDX-FileCopyrightText: 2021 John Park for Adafruit Industries
# SPDX-License-Identifier: MIT
# RaspberryPi Pico RP2040 Mechanical Keyboard
 
import time
import board
from digitalio import DigitalInOut, Direction, Pull
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.consumer_control import ConsumerControl
from adafruit_hid.consumer_control_code import ConsumerControlCode
 
print("---Pico Pad Keyboard---")
 
led = DigitalInOut(board.LED)
led.direction = Direction.OUTPUT
led.value = True
 
kbd = Keyboard(usb_hid.devices)
cc = ConsumerControl(usb_hid.devices)
 
# list of pins to use (skipping GP15 on Pico because it's funky)
pins = [
    board.GP0,
    board.GP1,
    board.GP2,
    board.GP3,
    board.GP4,
    board.GP5,
    board.GP6,
    board.GP7,
    board.GP8,
]
 
MEDIA = 1
KEY = 2
 
keymap = {
    (0): (KEY, [Keycode.ONE]),
    (1): (KEY, [Keycode.UP_ARROW]),
    (2): (KEY, [Keycode.THREE]),
    (3): (KEY, [Keycode.LEFT_ARROW]),
    (4): (KEY, [Keycode.FIVE]),
    (5): (KEY, [Keycode.RIGHT_ARROW]),
    (6): (KEY, [Keycode.SEVEN]),
    (7): (KEY, [Keycode.DOWN_ARROW]),
    (8): (KEY, [Keycode.NINE]),

}
switches = [0, 1, 2, 3, 4, 5, 6,
            7, 8]
 
for i in range(9):
    switches[i] = DigitalInOut(pins[i])
    switches[i].direction = Direction.INPUT
    switches[i].pull = Pull.UP
 
switch_state = [0, 0, 0, 0, 0, 0, 0, 0, 0]
 
while True:
    for button in range(9):
        if switch_state[button] == 0:
            if not switches[button].value:
                try:
                    if keymap[button][0] == KEY:
                        kbd.press(*keymap[button][1])
                    else:
                        cc.send(keymap[button][1])
                except ValueError:  # deals w six key limit
                    pass
                switch_state[button] = 1
 
        if switch_state[button] == 1:
            if switches[button].value:
                try:
                    if keymap[button][0] == KEY:
                        kbd.release(*keymap[button][1])
 
                except ValueError:
                    pass
                switch_state[button] = 0
 
    time.sleep(0.01)  # debounce

The above snippet was stolen and lightly modified from here.

The pico needs to be flashed with the micro python bootloader. Instructions on how to do this can be found here.

I then saved the above code as code.py and copied it to the root of the mounted Pico block device.

You will also need to create a directory called ‘lib’ and add the Adafruit hid library to it which can be found here.

The code above will simply type each GPIO pin number that the switch is connected to. For building Macros and editing the layout there is a great guide here.

Conclusion

Building a Raspberry Pi Pico Macro pad was surprisingly easy. This was mainly down to the fantastic examples by Adafruit and a credit to the void9 design. Watch this space for the 60% keyboard build that will be coming soon!

For more of my Raspberry Pi projects take a look here.

Leave a comment

Your email address will not be published. Required fields are marked *