KBD-150 Build Workbook
← Guides  /  Hypertech Industries · KBD-150 · Draft 1, Oct 29 2026

KBD-150 Build Workbook

Build a 12 × 5 hand-wired keyboard from a printed test coupon to a working module. Tick each step as you go. Your ticks stay on this computer.

0%
0

Before you start

Parts, tools and rules

  1. Gather the parts

  2. Gather the tools

  3. Read the soldering rules togetherTogether

    • Iron at about 330 to 350 °C. The tip is hot for several minutes after unplugging.
    • Iron goes back in the stand every time you put it down. Never lay it on the table.
    • Hair tied back, glasses on, fan on. Wash hands after soldering, especially if the solder contains lead.
    • Hold wires and diodes with tweezers or a clamp, never with a finger next to the joint.
    • A good joint is shiny and shaped like a small cone. A dull blob means reheat and add a touch of flux.
  4. Learn the colour code

    Every picture and diagram uses the same colours.

    Orange = row wiresBlue = column wiresBlack stripe on a diode = cathode, always pointing at the row wire

    When you flip the plate over to solder, left and right swap. Column 0 is the key on the left when you look at the keys, and it is on the right when you look at the wiring side. The diagrams say which view they use.

1

Test coupon

Print, fit and wire 9 keys

  1. Print the coupon plate and the jig rails

    The coupon is a 3 × 3 piece of the real plate. It tests the hole size, practises the wiring, and later becomes your permanent test fixture. The two rails hold the plate off the table while you solder.

    Drag to rotate, scroll to zoom

    Settings to start with

    • PETG, 0.2 mm layers, 3 walls, 20% infill, no supports.
    • Plate: print flat as it sits in the file. The 1.5 mm plate is the whole part.
    • Rails: print both as they sit.
    • Clean the switch holes with a craft knife if the first layer flared.

    The three hole sizes

    • Column with 1 small hole near the edge: 14.00 mm
    • Column with 2 small holes: 14.15 mm
    • Column with 3 small holes: 14.30 mm

    PLACEHOLDER test values. Printers shrink holes a little, so the right size is whichever grips best.

    Plate, rails and a short README.
  2. Press a switch into each columnTogether

    Hold the switch with the stem facing you and the label upright. The two metal contacts on the back sit above the centre, toward the top edge. Press it into the hole until both side clips snap.

    • Which column holds a switch firmly without bulging the plate? Tug it gently.
    • If a switch will not go in, use the next larger hole. If it falls out, use the smaller one.
    Tell Claude this and the full plate gets the matching hole size.
  3. Set the plate on the railsTogether

    Lay the rails parallel, about 5 cm apart. Put the plate on them keys-down, so the back of every switch faces up at you. The switches hang between the rails. This is the wiring side.

    Coupon plate with nine switches resting on two rails
    All nine switches pressed in, seen from the wiring side. The plate rests on two rails.
  4. Practise three jointsGrown-up job

    Before touching a switch, solder a diode lead to a scrap wire three times. Touch the iron to both parts for 2 to 3 seconds, then feed solder into the joint, not onto the iron. Let it cool without moving.

  5. Solder one diode to one switchGrown-up job

    A: diode anode (no stripe)Stripe = cathode, faces the rowCathode lead joins the ROW wireB: column wireCOLUMN wire (blue)ROWWhere the blue and orange wirescross, both stay insulated.post
    1. Tin both metal contacts with a little solder.
    2. Bend the diode lead without the stripe into a small hook. This is the anode.
    3. Hook it over contact A (the right-hand contact on the wiring side) and solder it.
    4. Point the striped end straight down toward the bottom edge of the switch. Trim the lead so it ends just past the row wire position.
    5. Leave contact B for the column wire.
    Close-up of diodes soldered to switch contacts
    Close-up: the diode stands off contact A with its stripe at the bottom.
  6. Do the other eight diodesTogether

    Same direction every time. Stripe toward the bottom edge, anode on contact A. Do the whole coupon, then look along each row to check every stripe points the same way.

    Nine diodes soldered, stripes facing the same way
    All nine diodes in place. Every stripe points toward the bottom.
  7. Solder the row wires (orange)Grown-up job

    Strip 3 mm from each end of a short orange wire. Solder it between the cathode leads of neighbouring diodes so each row is one connected line. The easy way is one short segment from diode to diode. Leave the last diode of each row with a longer tail wire for the board later.

    Rows run left to right on the wiring side. Keep row wires clear of the blue column contacts.

    Row wires soldered across the coupon
    Orange row wires join the diode cathodes along each row.
  8. Solder the column wires (blue)Grown-up job

    Solder a blue wire to contact B of each switch in a column, running straight down the column. Where a blue wire crosses an orange wire, both stay insulated. A small strip of Kapton tape on the crossing keeps them apart for good.

    Column wires soldered down each column
    Blue column wires touch only contact B. They cross over the orange rows without touching.
  9. Check the wiring before it goes anywhereTogether

    Do these in order.

    1. Look for stray wire strands or solder blobs that bridge two joints.
    2. With a multimeter in diode mode, put the red probe on a column wire and the black probe on a row wire. Press that key. You should read about 0.5 to 0.7. Swap the probes and it should read OL (open).
    3. No key pressed: every row and column pair should read open in both directions.
2

Program the board

CircuitPython and KMK

  1. Connect the RP2040-Zero in bootloader modeTogether

    Hold the BOOT button, plug the USB-C cable into the board and the computer, then let go. A drive named RPI-RP2 appears. If it does not, the cable is probably charge-only.

    No board in hand yet? Do this chapter as soon as it arrives. Nothing here needs the coupon.

  2. Install CircuitPythonTogether

    On circuitpython.org, open the Downloads page and choose Waveshare RP2040-Zero. Download the latest stable .uf2 file and drag it onto the RPI-RP2 drive. The drive disappears and a new one named CIRCUITPY appears within a few seconds.

  3. Install KMKTogether

    KMK is the keyboard firmware. It is plain Python files, so there is nothing to compile.

    1. On github.com, open KMKfw/kmk_firmware, choose Code, then Download ZIP.
    2. Unzip it and copy the whole kmk folder onto the CIRCUITPY drive.
  4. Load the coupon programTogether

    Save this as code.py on the CIRCUITPY drive. The board restarts by itself when you save. It scans 3 columns and 3 rows and types a to i.

    code.py (coupon)
    import board
    from kmk.kmk_keyboard import KMKKeyboard
    from kmk.keys import KC
    from kmk.scanners import DiodeOrientation
    
    keyboard = KMKKeyboard()
    
    # 3 columns on GP0-GP2, 3 rows on GP29-GP27 (same pins the full board will use)
    keyboard.col_pins = (board.GP0, board.GP1, board.GP2)
    keyboard.row_pins = (board.GP29, board.GP28, board.GP27)
    keyboard.diode_orientation = DiodeOrientation.COL2ROW
    
    keyboard.keymap = [[
        KC.A, KC.B, KC.C,
        KC.D, KC.E, KC.F,
        KC.G, KC.H, KC.I,
    ]]
    
    if __name__ == '__main__':
        keyboard.go()
    
  5. Test the board before any wiringTogether

    Open a text editor. Use a bent paperclip or a jumper to touch pin GP0 and pin GP29 at the same moment. You should see the letter a. Touch GP1 and GP29 for b, and GP0 and GP28 for d.

3

Wire up the coupon

Board, test and fix

  1. Cut and strip six leadsHelper job

    Cut three orange and three blue wires, each about 12 cm. Strip 3 mm from both ends. Tape a small paper flag on each one: R0 R1 R2 and C0 C1 C2.

  2. Solder the leads to the boardGrown-up job

    R0 to GP29R1 to GP28R2 to GP27C0GP0C1GP1C2GP2Wiring side. Left and right are mirrored from the keys side.
    LeadGoes to
    R0 (top row)GP29
    R1GP28
    R2 (bottom row)GP27
    C0 (left column from the keys side)GP0
    C1GP1
    C2GP2
    Coupon wired to the RP2040-Zero board
    The finished coupon: three blue columns into the top of the board, three orange rows into the side.

    If your board came with pin headers, push the leads into a breadboard or use jumper wires instead of soldering. Either works for the test.

  3. Plug in and typeTogether

    Open a text editor and press the switches in order, top row first, left to right as you look at the keys.

    ABC
    DEF
    GHI

    You should see abcdefghi.

  4. If a key is wrongTogether

    • Nothing types at all: check the board shows CIRCUITPY, and that code.py is in the top folder. Check one diode stripe is not backwards.
    • One key dead: reheat both of its joints and look at its diode direction.
    • A whole row or column dead: the lead to the board, or a joint between two neighbours.
    • Letters in the wrong places: two leads are swapped. Swap the pin names in code.py instead of resoldering.
    • Every key dead and all diodes are the same way: change COL2ROW to ROW2COL in code.py and save.
  5. Keep the coupon

    This is now your bench test fixture. Take a photo of the wiring for reference, and copy code.py to a safe folder on your computer. The full board uses the same first three columns and rows, so what you learned carries over.

4

The full keyboard

60 keys to a working module

  1. Where the full-board design stands

    Slab docked in the MC-150 well
    Docked in the MC-150
    Slab lifting out of the riser
    Slab lifting out of the riser
    Riser and slab on a desk
    Riser and slab together
  2. The parts you will print

    PartWhat it isSize (PLACEHOLDER)STL
    SlabPlate, shell and controller space in one body, 5° top233.4 × 100.05 mm, about 33 mm front and 41 mm backNot modelled yet
    RiserSolid KPD-150 shaped block with a pocket for the slab257 × 113 mm, 55 to 65 mm tallNot modelled yet
    Wiring jigRails that hold the plate off the desk while you solderto match the real plateNot modelled yet
    Magnets4 discs, 5 × 2 mmPLACEHOLDERBuy later
  3. Study the wiring planTogether

    The full board is 12 columns by 5 rows, 60 switches and 60 diodes. It uses the same pin pattern as the coupon: the first three columns and rows match exactly.

    C0GP0C1GP1C2GP2C3GP3C4GP4C5GP5C6GP6C7GP7C8GP8C9GP9C10GP10C11GP11R0GP29`1234567890BkspR1GP28TabQWERTYUIOP\R2GP27EscASDFGHJKL;'R3GP26ShiftZXCVBNM,./EnterR4GP15CtrlWinAltFnSpcSpcSpcSpc←↓↑→
    USB-C5VGND3V3GP29GP28GP27GP26GP15GP14GP0GP1GP2GP3GP4GP5GP6GP7GP8GP13GP12GP11GP10GP9orange: rowsGP29, 28, 27, 26, 15blue: columnsGP0 to GP11grey: spareGP12, 13, 14

    Keys are drawn as seen from the top. Pin names match the labels printed on the RP2040-Zero. Positions are drawn from the Waveshare pinout, so check them against your board.

  4. Press in all 60 switchesTogether

    Same orientation as the coupon, contacts toward the top edge. Use the hole size from the coupon test. Press every switch in, then check from the front that each one is square and seated.

  5. Solder the 60 diodes, one row at a timeGrown-up job

    • Do row 0, then wire and test it before starting row 1. Mistakes are cheap while only one row exists.
    • Stripe toward the row wire on every diode. Look along each row before moving on.
    • Use short row segments between neighbouring diodes. A row is about 230 mm long and one long wire is hard to keep tidy.
    • The corner keys sit close to the slab chamfer. Keep their leads short and low.
  6. Solder the 12 column wiresGrown-up job

    Five switches per column, each wired to contact B. Run the column wires in one direction and bring all twelve out toward the controller at the back of the slab. Cover every crossing with a strip of tape.

  7. Mount the controller and solder the 17 leadsGrown-up job

    Row leads go to GP29, GP28, GP27, GP26 and GP15. Column leads go to GP0 through GP11. Tape a flag on each lead before soldering. Add a dab of hot glue or Kapton over the joints for strain relief. The USB-C port faces the rear of the slab.

  8. Load the full keyboard programTogether

    Replace code.py on the CIRCUITPY drive with this one. It has a typing layer and a function layer on the Fn key.

    code.py (full keyboard)
    import board
    from kmk.kmk_keyboard import KMKKeyboard
    from kmk.keys import KC
    from kmk.scanners import DiodeOrientation
    from kmk.modules.layers import Layers
    
    keyboard = KMKKeyboard()
    keyboard.modules.append(Layers())
    
    # 12 columns on GP0-GP11, 5 rows on GP29, GP28, GP27, GP26, GP15
    keyboard.col_pins = (
        board.GP0, board.GP1, board.GP2, board.GP3, board.GP4, board.GP5,
        board.GP6, board.GP7, board.GP8, board.GP9, board.GP10, board.GP11,
    )
    keyboard.row_pins = (board.GP29, board.GP28, board.GP27, board.GP26, board.GP15)
    keyboard.diode_orientation = DiodeOrientation.COL2ROW
    
    FN = KC.MO(1)
    _ = KC.TRNS
    
    keyboard.keymap = [
        [  # layer 0: typing
            KC.GRV,  KC.N1, KC.N2, KC.N3, KC.N4, KC.N5, KC.N6, KC.N7, KC.N8, KC.N9, KC.N0,   KC.BSPC,
            KC.TAB,  KC.Q,  KC.W,  KC.E,  KC.R,  KC.T,  KC.Y,  KC.U,  KC.I,  KC.O,  KC.P,    KC.BSLS,
            KC.ESC,  KC.A,  KC.S,  KC.D,  KC.F,  KC.G,  KC.H,  KC.J,  KC.K,  KC.L,  KC.SCLN, KC.QUOT,
            KC.LSFT, KC.Z,  KC.X,  KC.C,  KC.V,  KC.B,  KC.N,  KC.M,  KC.COMM, KC.DOT, KC.SLSH, KC.ENT,
            KC.LCTL, KC.LGUI, KC.LALT, FN, KC.SPC, KC.SPC, KC.SPC, KC.SPC, KC.LEFT, KC.DOWN, KC.UP, KC.RGHT,
        ],
        [  # layer 1: hold FN for F-keys
            KC.F1, KC.F2, KC.F3, KC.F4, KC.F5, KC.F6, KC.F7, KC.F8, KC.F9, KC.F10, KC.F11, KC.F12,
            _, _, _, _, _, _, _, _, _, _, _, _,
            _, _, _, _, _, _, _, _, _, _, _, _,
            _, _, _, _, _, _, _, _, _, _, _, _,
            _, _, _, _, _, _, _, _, _, _, _, _,
        ],
    ]
    
    if __name__ == '__main__':
        keyboard.go()
    
    Coupon and full keyboard.
  9. Test all 60 keys before closing the slabTogether

    Open a keyboard tester page or a text editor and press every key, row by row. Hold Fn and press the top row to check F1 to F12. Fix any dead key now, while everything is still easy to reach.

  10. Install the keycapsTogether

    Press each XDA cap straight down onto its stem until it stops. Measure the real cap height and tell Claude, because it changes the standalone typing height of the slab.

  11. Dock it and try it three waysTogether

    1. Slab on a desk, plugged into your computer.
    2. Slab dropped into the riser, with the riser cable plugged in.
    3. Riser seated in the MC-150 well, plugged into the rear socket.

    If it types the same in all three, the keyboard module is done.

5

Troubleshooting

When it will not work

  1. Quick troubleshooting

    What you seeTry this
    No RPI-RP2 driveHold BOOT before and while plugging in. Try a different cable.
    No CIRCUITPY driveThe UF2 did not finish copying. Redo it with the board in bootloader mode.
    Code does nothingIs the kmk folder on the drive? Is the file called exactly code.py?
    One key deadReheat both joints. Check the diode direction.
    A key types twice or two keys fire togetherA solder bridge or touching bare wires. Look near that key.
    A row or column deadA broken wire or a missed joint, or the lead at the board.
    Every key deadDiodes all reversed, or wrong pin names. Try ROW2COL.
    Keys feel loose in the plateUse the smaller hole size and reprint the plate.
  2. After it works

    • Change the keymap in code.py. It is just a list of keys.
    • Add layers, shortcuts or the onboard RGB LED.
    • The same RP2040-Zero boards can run GP2040-CE for the GPD-201 to 203 gamepads.
    • Want Vial or QMK later? The wiring does not change, only the firmware.