Close

First the PTH version with Pi Pico

A project log for DIY 4x4 Macropad with Pi Pico and QMK

Building a custom 4x4 macropad from scratch using a custom PCB, Pi Pico and QMK. My first version with direct solder PTH switches.

dailyduinoDailyDuino 05/10/2026 at 11:520 Comments

A few days ago, I was recommended a video by Moby Pixel on YouTube where he built a custom MIDI macropad for music composition. It looked like a pretty cool project, and I immediately wanted to build one for myself but not for music, but to automate a couple of on-demand tasks for my day job as a software developer.

I know there are plenty of great, fairly priced macropads available on AliExpress, Tindie, and Lectronz. However, I want to get back into PCB design, as it has been eight years since I last designed a professional board.

I’m also a huge Halo fan. I want my desk setup to feature a Master Chief color scheme, and I want this new macropad to perfectly match my Master Chief controller holder.

While I loved the simplicity of Moby Pixel’s design, I couldn’t find a cheap 4×4 mechanical switch PCB to use for prototyping. That inspired me to build my own.

With this project, I have a few specific goals:

Through these iterations, I will be packing more components onto a 2-layer PCB, evolving the project from a basic USB HID macropad into a fully featured version with Bluetooth, HID, and LED support. Finally, I will be stepping away from Eagle to use EasyEDA for the design to see how it performs.

The Design

There are a couple of key differences between Moby Pixel's project and mine. First, he uses a dedicated GPIO pin for every switch, whereas I will be using a keypad matrix. Second, his design integrates both the switches and the microcontroller onto a single PCB. In my version, I will design a separate PCB for the microcontroller. This modular approach will allow me to easily swap out microcontrollers to experiment with different firmwares.

Schematic

In the key matrix i added external pull-ups and switch the rows and columns. this is how the schematic looks.

The bill of materials is pretty simple

ComponentCount
1N4148 Diode (SOD-123)16
Mechanical Switch of your choice16
10K Resistor (0603) (optional)4
10 Pin 0.1″ Header Pins1

PCB Layout

The PCB is 82.8mm x 82.8mm and i want to keep the distance between the switchers small so that it will ergonomic and low profile.

Finally, I was happy with my design. It took me a whole of 2 hours to design it and now i have to send it for fabrication. It was pretty easy to order PCBs from easyEDA. I just had to click one button and the PCB design was sent to JLCPCB.com and form there it was very easy and cheap to order the PCBs. I was not sponsored by JLCPCB. *cough *cough please sponsor thanks.

Assembly

I soldered the diodes using a soldering iron and it took me 10 minutes to do that. I soldered on the resistor for pull ups but later removed them because i wanted to use the internal pull ups of the RP2040.

Now for the mounting plate. I designed it using fusion360 and printed it on my 3D printer. The choice of color on this is not so great.

Next, I snapped the mechanical blue switches into place on the mounting plate and it snapped perfectly into place. Nice.

Finally I mounted and soldered the PCB in the top mounting plate with the switches.

Okay, here's where I messed up. I should have also ordered the bottom PCB with a microcontroller but I had to work with what I had on hand for testing the prototype. So, I soldered the Pi Pico i had which has the RP2040 microcontroller.

I connected the macropad to pi pico using the following pin configuration

Macro Pad PinsRP2040 GPIO
1 (COL1)GP9
2 (COL2)GP8
3 (COL3)GP7
4 (COL4)GP6
5 (ROW1)GP5
6 (ROW2)GP4
7 (ROW3)GP3
8 (ROW4)GP2
9 (VCC)
10 (VCC)

Now that i have connected everything, I plugged in the Pi Pico to my PC and it showed up as a mass storage device.

Software

I had the sweet temptation of writing the software using AI but i had to resist it hard because there were much more mature projects like QMK (Quantum Mechanical Keyboard ) and ZMK (Zephyr Mechanical Keyboard). For this project i'm using QMK.

I cloned the firmware source from QMK's GitHub repo and then I followed QMK's Setup Guide to setup the development environment. I tried searching for an existing config which would work with my Macropad PCB but i could only find some which were partially compatible. So, I added my own device definition by just adding 2 files and couple of folders. First I created a folder "dailyduino_4x4" in "qmk_firmware/keyboards/handwired" folder then i created a "keyboard.json" file and added the following content and then i saved it.

 {    "manufacturer": "DailyDuino",    "keyboard_name": "DailyDuino 4x4",    "maintainer": "DailyDuino",    "bootloader": "rp2040",    "processor": "RP2040",    "diode_direction": "COL2ROW",    "matrix_pins": {        "cols": ["GP6", "GP7", "GP8", "GP9"],        "rows": ["GP2", "GP3", "GP4", "GP5"]    },    "usb": {        "vid": "0xFEED",        "pid": "0x4C34",        "device_version": "1.0.0"    },    "features": {        "bootmagic": true,        "extrakey": true,        "mousekey": true,        "nkro": true    },    "community_layouts": ["ortho_4x4"],    "layouts": {        "LAYOUT_ortho_4x4": {            "layout": [                {"matrix": [0, 0], "x": 0, "y": 0},                {"matrix": [0, 1], "x": 1, "y": 0},                {"matrix": [0, 2], "x": 2, "y": 0},                {"matrix": [0, 3], "x": 3, "y": 0},                {"matrix": [1, 0], "x": 0, "y": 1},                {"matrix": [1, 1], "x": 1, "y": 1},                {"matrix": [1, 2], "x": 2, "y": 1},                {"matrix": [1, 3], "x": 3, "y": 1},                {"matrix": [2, 0], "x": 0, "y": 2},                {"matrix": [2, 1], "x": 1, "y": 2},                {"matrix": [2, 2], "x": 2, "y": 2},                {"matrix": [2, 3], "x": 3, "y": 2},                {"matrix": [3, 0], "x": 0, "y": 3},                {"matrix": [3, 1], "x": 1, "y": 3},                {"matrix": [3, 2], "x": 2, "y": 3},                {"matrix": [3, 3], "x": 3, "y": 3}            ]        }    }
}

After saving the JSON file i created a folder inside the dailyduino_4x4 folder dailyduino_4x4/keymaps/default and the i created a file "keymap.c" inside the default folder and i pasted the following content and saved the file.

// Copyright 2024 QMK
// SPDX-License-Identifier: GPL-2.0-or-later

#include QMK_KEYBOARD_H

enum custom_keycodes {    M_STR1 = SAFE_RANGE,    M_STR2,    M_STR3,    M_STR4,    M_TERM,
};

bool process_record_user(uint16_t keycode, keyrecord_t *record) {    if (record->event.pressed) {        switch (keycode) {            case M_STR1: SEND_STRING("Hello, World!"); return false;            case M_STR2: SEND_STRING("your@email.com"); return false;            case M_STR3: SEND_STRING("some other string"); return false;            case M_STR4: SEND_STRING("another string"); return false;            case M_TERM: SEND_STRING(SS_LGUI(" ") SS_DELAY(300) "terminal" SS_TAP(X_ENT)); return false;        }    }    return true;
}

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {    [0] = LAYOUT_ortho_4x4(        M_STR1,  M_STR2,  M_STR3,  M_STR4,        M_TERM,  KC_6,    KC_7,    KC_8,        KC_9,    KC_0,    KC_MINS, KC_EQL,        KC_BSPC, KC_TAB,  KC_ENT,  MO(1)    ),    [1] = LAYOUT_ortho_4x4(        KC_F1,   KC_F2,   KC_F3,   KC_F4,        KC_F5,   KC_F6,   KC_F7,   KC_F8,        KC_F9,   KC_F10,  KC_F11,  KC_F12,        QK_BOOT, _______, _______, _______    )
};

Finally i ran the command "qmk flash -kb handwired/dailyduino_4x4 -km default" and the code compiled and uploaded to the Raspberry Pi Pico which was showing as a mass storage device. Now the Raspberry Pi Pico shows as a USB HID Keyboard.

Success!! It works

The Macro Pad works really well and it is very responsive. Now, for the final touches I have to design the case and print it.

Finishing Touches

I went back to fusion360 to design the case. I really wanted to make it low profile but the wires I soldered need some slack so that i can screw in the Pi Pico and so i made it a bit thick.

I assembled the case with the top PCB and it looks good for a prototype and works great.

Parts and Links

I have few PCBs left and i have put them up on Tindie and Lectronz.

PartQuantityLink
Blue Mechanical Switches16Aliexpress
Blank Purple XDA Keycaps16Aliexpress
M2 x 4mm Screw4
M2 x 8mm Screw4
Raspberry Pi Pico1Aliexpress
3D Printed enclosures1Thingiverse
4×4 Macropad PTH PCB1Tindie Lectronz

PTH Switches and Beyond

My next post will be about the socketed PCB with LED backlight and also about the 2 versions of base board i designed with two different microcontrollers RP2040 and nRF52840 and maybe in future i will make a ESP32-S6 Base board. I will also be comparing QMK and ZMK firmware and finally i might be writing my own firmware and configurator. The next version will be following the master chief color scheme and i will be one step closer to my halo themed desk setup. Thank you very much for reading my ramblings I hope you have gained something useful from my post. Thanks again. 

P.S. Please check out my website dailyduino.com thanks.

https://www.dailyduino.com/index.php/2026/05/08/diy-4x4-macro-pad-with-pi-pico-and-qmk-pth-version/

Discussions