Deep-Dive Series // 6 Steps

Building the MonkiiPad3x3

Build your own 9-key handwired macropad and a great first soldering project

Difficulty

Beginner

Time

2–3 hours

Steps

6 stages

Every file for this build is up on GitHub, the plates, the case and the firmware

Our GitHub

Watch It Get Built

Prefer to see it happen? Here is the full walkthrough of this build and how the finished board actually works. Follow along with the written steps below.

Before You Build

Gather everything below before you start and the whole build goes a lot smoother. The printable parts are on GitHub, so you only need to buy the hardware.

No Case // The Sandwich

There is no case in this build. Our boards are a sandwich, a 3D printed top plate and a 3D printed bottom plate with the whole handwired matrix pressed in between, held together by screws at the corners. That is deliberate. Handwiring goes wrong in ways a beginner or a STEM maker cannot always predict, and a sealed case turns every loose joint into an afternoon of surgery. Undo the screws, lift the top plate, and the entire matrix is in front of you, ready to fix and bolt back together.

Component Manifest

Component Qty Specification
MX-compatible switches 9 Any MX switch works
Pro Micro ATmega32U4 1 Programmed via Arduino IDE
Hookup wire (24 AWG) ~2m Two colors recommended
3D Printed Plates (STLs provided) 2 Top + bottom, PLA, 0.2mm layer height
Keycaps (1u × 9) 9 Any MX-compatible keycaps
M2 screws (4mm) 4 Clamp the two plates together
Soldering iron + solder 1 set Any soldering iron works for this build

Tools Required

01

Soldering iron

02

Solder

03

Wire strippers

04

Flush cutters

05

Tweezers

06

Computer with Arduino IDE installed

Build Steps

Work through these in order. Anything you need to download along the way, the plates, the case and the firmware, is already waiting for you on GitHub.

01

Step 1 of 6

Print the Plate

The MonkiiPad3x3 STL files are on GitHub, so grab the top and bottom plates there and print them both in PLA. Use 0.2mm layer height, 20% infill. No supports needed. The top plate has nine switch cutouts in a perfect 3×3 grid; the bottom plate screws on underneath to close the sandwich.

Print the Plate
Step 1, Print the Plate

02

Step 2 of 6

Mount the Switches

Snap all 9 switches into the plate, they should click in firmly with no wobble. The MonkiiPad3x3 is a diodeless matrix, so there are no diodes to add, each switch wires straight into the row/column grid.

Pro Tip

Check that no switch pins are bent before pressing them in, because bent pins cause hard to trace matrix issues.

Mount the Switches
Step 2, Mount the Switches

03

Step 3 of 6

Wire the Rows

Run a wire across each of the 3 rows, soldering directly to one pin of each switch in that row. Strip a small window at each joint, solder, and move to the next. Three rows = three wires.

Pro Tip

Use one color for row wires and another for column wires to avoid confusion.

Wire the Rows
Step 3, Wire the Rows

04

Step 4 of 6

Wire the Columns

Run a wire down each of the 3 columns, soldering to the top pin of each switch. Three columns = three wires. These must never touch the row wires.

Wire the Columns
Step 4, Wire the Columns

05

Step 5 of 6

Connect to Pro Micro & Assemble

Connect each of the 3 row wires and 3 column wires to GPIO pins on the Pro Micro. The reference firmware uses rows on pins 7, 8, 9 and columns on 4, 5, 6. Note down every connection, tuck the wiring neatly, lay the bottom plate over the back of the assembly, and secure the sandwich with M2 screws. Press keycaps onto the switches.

Connect to Pro Micro & Assemble
Step 5, Connect to Pro Micro & Assemble

06

Step 6 of 6

Flash Arduino Firmware & Test

The MonkiiPad3x3 sketch is on GitHub, or printed in full further down this page. Open it in the Arduino IDE, set the rowPins and colPins arrays to match your wiring, then upload to the Pro Micro. Open a keyboard tester and all 9 keys should register. Hold key 1 for ~1.5s to toggle between number mode and macro mode (arrows, copy/paste, delete). Want a different layout? The Keymap Editor will build the sketch for you.

Pro Tip

Install the Arduino keyboard HID library before compiling, the sketch depends on it. The exact includes are at the top of the sketch on GitHub.

Flash Arduino Firmware & Test
Step 6, Flash Arduino Firmware & Test

Firmware

The full Arduino sketch for this build. Open it in the Arduino IDE, match the pins to your wiring, and upload. There is no need to copy it off this page, the same sketch is sitting on GitHub with the rest of the repo.

MonkiiPad3x3.ino
#include <Keyboard.h>

const int colPins[3] = {4, 5, 6};
const int rowPins[3] = {7, 8, 9};

bool macroMode = false;

unsigned long pressStart = 0;
const unsigned long holdTime = 1500;

void setup() {

  for (int c = 0; c < 3; c++) {
    pinMode(colPins[c], INPUT_PULLUP);
  }

  for (int r = 0; r < 3; r++) {
    pinMode(rowPins[r], OUTPUT);
    digitalWrite(rowPins[r], HIGH);
  }

  Keyboard.begin();
}

void loop() {

  for (int r = 0; r < 3; r++) {

    digitalWrite(rowPins[r], LOW);
    delayMicroseconds(30);

    for (int c = 0; c < 3; c++) {

      if (digitalRead(colPins[c]) == LOW) {

        // SPECIAL LOGIC FOR KEY 1
        if (r == 0 && c == 0) {

          pressStart = millis();

          while (digitalRead(colPins[c]) == LOW) {

            if (millis() - pressStart > holdTime) {

              macroMode = !macroMode;

              while (digitalRead(colPins[c]) == LOW);
              delay(200);
              goto skipKey;
            }
          }

          // short press
          Keyboard.write('1');
          delay(20);
          goto skipKey;
        }

        // NORMAL MODE
        if (!macroMode) {

          char numbers[3][3] = {
            {'1','2','3'},
            {'4','5','6'},
            {'7','8','9'}
          };

          Keyboard.write(numbers[r][c]);
        }

        // MACRO MODE
        else {

          if (r == 0 && c == 1) Keyboard.write(KEY_UP_ARROW);

          else if (r == 1 && c == 0) Keyboard.write(KEY_LEFT_ARROW);

          else if (r == 1 && c == 1) Keyboard.write(KEY_DOWN_ARROW);

          else if (r == 1 && c == 2) Keyboard.write(KEY_RIGHT_ARROW);

          else if (r == 2 && c == 0) {  // Ctrl+C
            Keyboard.press(KEY_LEFT_CTRL);
            Keyboard.press('z');
            delay(10);
            Keyboard.releaseAll();
          }

          else if (r == 2 && c == 1) {  // Ctrl+V
            Keyboard.press(KEY_LEFT_CTRL);
            Keyboard.press('y');
            delay(10);
            Keyboard.releaseAll();
          }

          else if (r == 2 && c == 2) {  // Delete
            Keyboard.write(KEY_DELETE);
          }

          else {
            Keyboard.write('1');
          }
        }

        while (digitalRead(colPins[c]) == LOW);
        delay(20);

        skipKey:;
      }
    }

    digitalWrite(rowPins[r], HIGH);
  }
}

Want a different keymap?

Lay out your own keys, layers and macros in the browser, then download a sketch already wired for this board. No editing C by hand.

Open Keymap Editor →

Everything is on GitHub

Every 3D printing file, every firmware sketch and every build guide we have written lives in one repository, and all of it is free to download and free to change however you like. The plate and case files are there, so is the Arduino code for each board, the wiring diagrams and the PCB designs.

View on GitHub

Join the Discussion

Stuck on a step, got a tip, or just finished your build? Drop it in our form. We read every single one and it helps us make the guide better.

Leave a Comment →