Mechanical Keyboard Prototype With V-USB & QMK

Mechanical Keyboard Prototypes

This is a relatively complete guide on how to build a mechanical keyboard prototype and get it functioning with QMK. Two different microcontrollers will be demonstrated (ATMegs32A, ATMega328P) and it should provide a solid starting point for anyone wishing to build a keyboard from the ground up. This is going to the the base I build on with an aim to designing, testing and producing a selection of full keyboards.

Required Hardware

The hardware you will require for this project is as follows

  1. A ATMega32A or ATMega328P AVR microcontroller, either will do for this test, the 32A may be preferred if you plan to build a larger keyboard as it has more available lines.
  2. Something to program a bootloader on the microcontroller, I use a Pro Micro for this task, you can use a Raspberry Pi.
  3. An old USB cable or a USB header, something to get the connection from your pc to the microcontroller. I used a handmade cable for one setup and a USB-C header board for another. It makes no difference what you use, you just require VCC / GND / D+ / D – from a USB port to your project.
  4. A 16Mhz crystal, part of the clock circuit.
  5. 2 x 22pF ceramic capacitors, part of the clock circuit.
  6. 2 x 68R resistors for the USB data lines.
  7. A 4.7uF electrolytic capacitor to smooth the USB power lines.
  8. A 1.5k resistor, part of the USB data line voltage drop circuit (level adjustment).
  9. 2 mechanical keyboard switches, any at all will do (actually any momentary switch).
  10. 4 x 1N4148 diodes two for the keyboard matrix and two to drop the USB data lines to the correct voltage (technically these should be 3.6v zener diodes like these but 1N4148 have worked for me and I had them already, and it should be ok for testing).
  11. A selection of solid cable to make up jumper wires or pre-made jumper cables.
  12. A breadboard to plug all the parts into.
  13. A two pin header or dip switch or a jumper wire, something to short two pins to force the microcontroller into bootloader mode.
  14. Soldering iron, snips, etc

Software Required

I do all of my work on Macs so the software will be presented as if the reader is using this platform, I believe all the tools are cross platform but I cannot comment on their use or setup on Windows or Linux as they are not platforms I have used them on.

  1. QMK Toolbox, this is used for flashing firmware at various points in the process.
  2. Pro Micro ISP Programmer firmware, to flash on to the Pro Micro (will not be needed if you are using different programmer hardware).
  3. A working standard build environment.
  4. A working QMK build environment.
  5. USBaspLoader source files.
  6. The relevant files from my dev_scarlet build of QMK that contains the keyboard.

References To Guides

It is only fair that I reference the guides that helped me with this project, they may be helpful for people reading my guide for use as additional points of reference.

One of the primary sources that I was able to find to initially get me going was a Reddit post by oldoverholt. This linked onto a very high level guide to setting this kind of project up with an ATMega328P.

I also used the Discipline keyboard project as another source of reference for both QMK code. design ideas and an overview of how this should work. The Discipline keyboard uses a ATMega32A microcontroller.


Throughout the construction I will primarily refer to the ATMega32A process but will give examples wherever it would deviate if you are using an ATMega328P. I will also provide two overview finished schematics for both microprocessors.

Flashing a bootloader and setting fuses

The first stage to the project will be flashing a bootloader on the microprocessor of choice, the process will be exactly the same regardless witch of the two chips you use (but fuse settings will be different). To flash a bootloader you will require a device to do the loading (a programmer), I chose to use a Pro Micro board as I have a few available, you could use a Raspberry PI or a Teensy. For this guide I will discuss using a Pro Micro and leave other options to the reader.

Preparing the programmer

First must flash a specific firmware to the Pro Micro, the firmware in question is mentioned above and is derived from the QMK ISP Flashing Guide. Download the firmware and QMK toolbox, install QMK toolbox and connect your Pro Micro.

You should open QMK toolbox and see that it has detected the Pro Micro, it should say something similar to the following.

*** Caterina device connected
    Found port: /dev/cu.usbmodem14501

At the top of the page, click open and locate the firmware file you downloaded. Then make sure that the MCU is set to ‘atmega32u4’ (this is only if you are using a Pro Micro, otherwise the MCU will be different).

When ready click flash and you should see an output similar to the following (click for large version), you will also see at the end I have disconnected and reconnected the Pro Micro and it how reads as an AVRISP device, this confirms it is correctly configured and ready to program other microcontrollers.

Mechanical Keyboard Prototype - Flash Pro Micro With ISP Firmware
Mechanical Keyboard Prototype – Flash Pro Micro With ISP Firmware

Preparing the microcontroller and wiring the programmer

You will need to layout the microprocessor on a breadboard, provide power and ground lines and wire up the crystal (including two capacitors) to provide a clock signal. You will then need to connect the relevant pins from the programmer to the breadboard. I have produced a simple Fritzing diagram of the required wiring for both microprocessors. Please do not connect an external power source to the breadboard, connect the VCC and GND lines from the programmer as shown (click for large version).

Mechanical Keyboard Prototype - ATMega32A Flash Bootloader Circuit
Mechanical Keyboard Prototype – ATMega32A Flash Bootloader Circuit
Mechanical Keyboard Prototype - ATMega328P Flash Bootloader Circuit
Mechanical Keyboard Prototype – ATMega328P Flash Bootloader Circuit

Configuring, compiling and flashing the bootloader

Now we have our programmer wired and ready to go we need to configure the bootloader before we flash it onto the microcontroller.

I am going to assume you have a working build environment and have downloaded (and setup) QMK source and the USBaspLoader, if not please set this up now.

We need to make some changes to the bootloader config to reflect what microcontroller we are using and to also configure the default USB pins (QMK uses PD2 and PD3 for USB to make life easier we will use the same).

In the root directory of USBaspLoader make the following changes to the file, make sure you set the correct microcontroller.

F_CPU = 16000000
# this will either be atmega32 or atmega328p depending on the 
# microcontroller you are using
DEVICE = atmega32


# you will need to update the port (part after -P) to reflect the name of your
# usb port, or completely change this command if you are not using a Pro Micro
PROGRAMMER = -c avrisp -P /dev/cu.usbmodem123451

In the folder ‘firmware’ make the following changes to the bootloaderconfig.h file.

#define USB_CFG_DMINUS_BIT     3 
#define JUMPER_BIT           6 

With these changes complete we can now compile the bootloader. From the root directory of USBaspLoader run the following commands.

make clean
make firmware

We are now ready to flash, but before we do we are going to check we can see the microcontroller and set some fuses on it.

Execute the following command from a terminal window, adjusting the -p atmega32 to -p atmega328p if you are using the 328p and changing -P to the correct usb port.

avrdude -c avrisp -p m32 -P /dev/cu.usbmodem123451 -v

You should get a return detailing the programmer and attached microprocessor, you should see it read ok and return normally as per the following image. If not check your wiring and make sure the programmer flashed successfully.

Mechanical Keyboard Prototype - AVR ISP Read
Mechanical Keyboard Prototype – AVR ISP Read

The final stage before flashing the bootloader is to set the fuses. Fuses are persistent settings that are written to a specific area of the microcontroller, they control such things as clock speed, debug interfaces and various other options, caution must be taken when setting as incorrect values can brick the microcontroller (more detail on fuses can be found in a video here).

Our purpose here is to set the microcontroller to use the external 16mhz clock and to ensure that brownout detection is off. Fuse settings are derived from the fuse calculator.

There are different fuse settings for the two different microcontrollers, but they are set using a similar method, execute the following commands depending on which microcontroller you are using.

#ATMega32A Fuses
avrdude -c avrisp -p m32 -P /dev/cu.usbmodem123451 -v -u -U lfuse:w:0x1F:m
avrdude -c avrisp -p m32 -P /dev/cu.usbmodem123451 -v -u -U hfuse:w:0xC0:m
#ATMega328P Fuses
avrdude -c avrisp -p m328p -P /dev/cu.usbmodem123451 -v -u -U lfuse:w:0xFF:m
avrdude -c avrisp -p m328p -P /dev/cu.usbmodem123451 -v -u -U hfuse:w:0xD8:m
avrdude -c avrisp -p m328p -P /dev/cu.usbmodem123451 -v -u -U efuse:w:0xFF:m

Assuming these fuses were set correctly we can finally move on to flashing the bootloader.

From the root directory of USBaspLoader run the following command.

make flash

This should now flash the bootloader and you should get an output similar to the following, you have now successfully flashed the bootloader.

Mechanical Keyboard Prototype - AVR ISP Flash Bootloader
Mechanical Keyboard Prototype – AVR ISP Flash Bootloader

Wiring The USB Interface & Keyboard Matrix

As the circuit starts to add complexity in regards to layout I am going to move to schematic diagrams rather than Fritzing ones. This is due to the fact it is very difficult to scale component sizes and make them fit in Fritzing.

I have produced two different schematics for wiring the two different microcontrollers. Feel free to construct the physical layout of the circuits as you see fit but ensure the correct pins are used on the microcontrollers otherwise they will not function correctly. Click on the images to see the full SVG version of the schematics.

ATMega32A Schematic
Mechanical Keyboard Prototype – ATMega32A Schematic
ATMega328P Schematic
Mechanical Keyboard Prototype – ATMega328P Schematic

The above schematics outline how to wire the rest of the components used in the project, please follow them closely and check your wiring, also shown is how to wire a very basic keyboard matrix using two keys and two diodes (if you would like some further background on keyboard matrices and how to hand wire them please take a look at my hand wiring post).

Net Ports (the little labels like ROW1, COL1, SCK etc) are used to indicate how the different circuits are wired together without having to run wires, just match up the names.

Whilst the schematics show the programmer and how it is wired please feel free to disconnect this as it will not be required as the bootloader is already programmed. If you do not disconnect this please make sure it is not still plugged into your pc.

Flashing QMK

Now everything is wired we can proceed to configuring and flashing QMK on the keyboard, once this is done you will have a functional prototype.

I am going to assume you have configured a working QMK build environment, if you have not yet done so please do this now before proceeding.

Copy the relevant files from my dev_scarlet build of QMK into the keyboards/ghostseven/scarlet folder in your QMK environment.

Depending on what microprocessor you are using change the keyboards/ghostseven/scarlet/ file accordingly.

#Both ATmega328P and ATmega32A have been tested and work with USBasp, please ensure you configure the right one.
#MCU = atmega328p
MCU = atmega32a

Issue the following command from the QMK root folder to compile the QMK firmware.

qmk compile -kb ghostseven/scarlet -km default 

This should compile and produce an output similar to the following, you should end up with a ghostseven_scarlet_default.hex file in the QMK root folder, this is the firmware.

QMK Compile Firmware
Mechanical Keyboard Prototype – QMK Compile Firmware

We now need to connect the circuit via the USB port (or cable) that has been wired to the microprocessor (do not connect the programmer USB). Before we do this we need to make sure we have attached the bootloader jumper or shorted pin PD6 to GND.

Plug the circuit in and open QMK Toolbox, you should see USBAsp device connected. If this does not appear double check your circuit wiring and make sure you have shorted PD6 to GND.

Select the firmware you created in the previous step and make sure the MCU is set to the correct microcontroller (ATMega32A or ATMega328P), then click flash. You should see a positive output similar to the following.

QMK Toolbox Flash Firmware
Mechanical Keyboard Prototype – QMK Toolbox Flash Firmware

Unplug the circuit and disconnect the bootloader jumper (or wire between PD6 and GND). Reconnect the USB and you now have a working two button keyboard prototype!

Testing The Keyboard

By default the two buttons should present the letters s and d, if they do all is working fine!


Whilst in this form the keyboard is not really that useful or practical, it should give you a good grounding on how to build a larger or full size keyboard from scratch. I hope that you found this helpful and informative and it has give you the knowledge to take this further.

I want to add a few reference documents in this section that may be of use for anyone working on this project.

3D Printed Hand Wired 40% Keyboard

3D Printed, Hand Wired 40% Keyboard

The subject of this blog is a build log, that will cover my build of a 3D printed hand wired 40% keyboard. It will include basic details on 3D printing, hand wiring, general assembly and software programming with QMK along with references to the guides I used.

About a month or so ago I was looking around for a new project (as I frequently do) and I stumbled upon a mechanical keyboard sub-reddit. This ended with me in fairly short order, purchasing the parts to build my first keyboard. Skip forward to today and I have just finished building my third full keyboard and three macro-boards. Clearly this hobby is going to be a money sink!

Required Hardware

The hardware you will require for this project is as follows

The required hardware list is a little more daunting than usual as it will require access to specialist equipment (a 3D printer). You could always buy a case and plate to use instead of printing one and then adjust accordingly.

  1. A 3D printer with a build plate that is at least 220mm x 220mm, or alternatively buying a suitable keyboard plate and case.
  2. 47 x MX type mechanical keyboard switches, I used Gateron Blues.
  3. 48 x 1N4148 diodes for the keyboard matrix.
  4. A EC-11 rotary encoder, for the volume control.
  5. A Pro Micro controller board.
  6. 6 x M3 6-10mm screws to hold the case together (assuming you are using the 3D printed one).
  7. A suitable set of keycaps for a 40% ortholinear keyboard.
  8. A grippy knob…
  9. Suitable wire for building the keyboard matrix, I used a combination of old network cable wire (solid core) and some 26 AWG solid core cable I had from other projects. Any insulated wire will work but solid core is a little easier.
  10. Line wire to go between the microcontroller and the keyboard matrix, you can use whatever wire you like but I highly recommend using ribbon cable as it is flat and easy to work with.
  11. Soldering iron, snips, glue gun etc
3D printer, printing a keyboard case
3D Printed Hand Wired 40% Keyboard – Printing The Case

References To Guides

It is only fair that I reference the guides that helped me make this keyboard. They may be helpful for people reading my guide for use as additional points of reference.

A modern handwiring guide – stronger, cleaner, easier

A Complete Guide To Building a Hand-Wired Keyboard

Printing A Case

I wanted as make where possible all the components for the keyboard, ideally 3D printing where I could. I searched around for different 3D printed cases and was originally going to do a split ortholinear keyboard based on the lets split case. However once it was printed I realised there was not a lot of room to hand wire as it was designed for a PCB. After a bit more hunting I found the Void 40 a 40% keyboard case and plate that was designed for hand wiring. It really is an excellent case design, by Victor Lucachi who rightly deserves credit for releasing it freely for everyone to use and build on.

You will need to print this case or have it printed for you, additional you will need to also print one of these EC-11 to MX switch plate adapters. This will allow you to easily pop a rotary encoder into the top left switch socket (or any other socket should you desire).

Once you have these printed, you can socket all of your switches and the rotary encoder.

3D printed case with mx switches inserted
3D Printed Hand Wired 40% Keyboard – Socketed with Gateron blue switches.

Wiring The Keyboard

Basic principles: Keyboard matrix

To save us from having to wire directly to each switch, which would be laborious and honestly not practical in any way, a keyboard matrix is used instead. This wiring pattern allows us to only need one wire for each row and one wire for each column, dramatically reducing the wiring that needs to go back to a microcontroller.

However there is a trade off, having independently wired switches means that it is easy to know what switches are pressed at the same time without any false positives or unregistered keys (called ghosting). When a keyboard matrix is used we need to add diodes to each key to prevent the black flow of electricity connecting circuits that are not intended. In practice this means a little bit more fiddly soldering but a far more manageable keyboard build. To read more about keyboard matrices and the ghosting effect I have found the following article very easy to understand and clearly written.

Keyboard ghosting
3D Printed Hand Wired 40% Keyboard – Ghosting 🙂

Wiring the diodes

We need to add a diode to each switch, we will be wiring to the top left of each switch (my pictures show the keyboard rotated 180 degrees as it was easier to work on).

The diode must be wired so the anode ( + ) is closest to the switch and the cathode ( – ) is furthest away, it is easy to work out which is which on a diode as the cathode has black bar on it.

To make life a little easier and as is recommanded in all the guides I read, you should create a small loop at the anode end and then pop this over the switch connector. The loop helps create a strong connection and makes positioning somewhat easier. You will want to point the tail of the cathode so it runs straight up away from the switch so that you can loop it around the joining row wire you will add later. For example;

3D Printed Hand Wired 40% Keyboard – Adding diodes

Once you have looped all your diodes around the switches make sure you solder and check their connections, also make sure you have soldered a diode to the rotary encoder as well, it needs to be added to the two pin side in the same way as the switches.

3D Printed Hand Wired 40% Keyboard - Ghosting :)
3D Printed Hand Wired 40% Keyboard – All diodes soldered to the switches.

Adding the row wires

We now need to add the row wires, these are single wires that will run along each row and be soldered to the end of the diodes we just added.

I used insulated solid core wire for this and lined each wire up marking out where it would be in contact with the diode and cutting out the insulation at with a sharp craft knife.

Once you have your wire prepared you can then start soldering it to the diodes in each row, I recommend wrapping the tail wire of the diode around the row wire then soldering, once done you can trim any excess on each diode with wire cutters.

You should start to build up like this.

Partially wired row wires
3D Printed Hand Wired 40% Keyboard – Partial row wiring.

Once you are done your rows should look like this.

Full row wiring
3D Printed Hand Wired 40% Keyboard – Full row wiring.

Adding the column wires

This is a very similar process to adding the row wiring, we need to run wires down each column joining all second connectors on each switch in that column. For this I used old solid core network cable wires.

Once again measure and trim the insulation at the correct points and to aid with alignment I suggest you create a loop at one end and solder this to the first switch, then run down and solder to the remaining three in each column.

Once done it should look like this.

All rows and column wires added and soldered.
3D Printed Hand Wired 40% Keyboard – Full row and column matrix

Wiring the microcontroller

The major wiring work is now over, all we need to now do is run a wire to each column and each row on the keyboard (plus three to the rotary encoder). These wires will go back to the microcontroller and later be configured in QMK to drive the keyboard.

I used ribbon cable and I highly recommend this, it is flat and easy to run. I did this in strips of four as that fitted nicely in the gaps between rows and columns.

For each row you need to solder a wire to the cathode side (black bar) of the diode (where it joins the row wire) in any one of those rows. For each column you need to solder a wire to any one of the switches (on the non diode connector) in that column. The following picture should make it a little clearer

3D Printed Hand Wired 40% Keyboard – Link wire routing

I ended up with a wiring diagram that links back the following Pro Micro microcontroller pins.

Pro Micro PinRow
C61 – Top row (QWER)
D42 – Second row (ASDF)
D03 – Third row (ZXCV)
D14 – Forth row (Ctl Alt)
3D Printed Hand Wired 40% Keyboard – Row wiring table
Pro Micro PinColumn (Left To Right)
3D Printed Hand Wired 40% Keyboard – Column wiring table
Pro Micro PinRotary Encoder Pin
D2Right most pin of three
GNDCenter pin of three
D3Left most pin of three
3D Printed Hand Wired 40% Keyboard – Rotary encoder wiring table

One you have these all wired up I would recommend you do not fix the microcontroller in place and you do your programming and testing with a bare keyboard. Better to do it this way than assemble it all and then find a problem.

A 3D printed keyboard that has been hand wired with rainbow coloured wires and is open showing the wiring.

Configuring Firmware & Flashing QMK

I am not going to put a detailed guide on how to configure QMK here, you will need a QMK build environment. I suggest you follow this guide.

Once you have an environment together you can download the following files from my github page, these will need to be extracted into the qmk_firmware/keyboard/handwired directory. These files contain a fork of the code used by the Void40 by Victor Lucachi, this keyboard is not currently in the standard QMK base but I have reached out to Victor and it will soon be submitted (once it is live I will update this post to reflect it). The changes from the standard firmware are related to pin assignments and keymaps.

To build the firmware issue the following command

qmk compile -kb handwired/void40/ghostseven -km ghostseven

The resulting hex file should be flashed to the keyboard using QMK Toolbox. You will need to short the pins between RST and GND on the pro micro to put it in firmware update mode.

The keyboard will have the following layout if you used the above command.

QMK Keyboard 40% Layout GhostSeven

Please ensure you test all the keys and make sure they work, if you have changed the wiring to the controller in any way you will need to edit the config.h file in the ghostseven folder and match this to your wiring layout.

#define MATRIX_ROW_PINS { C6, D4, D0, D1 }
#define MATRIX_COL_PINS { E6, D7, B5, B4, F6, F7, F4, F5, B1, B3, B2, B6 }

 * Rotary Encoder Support
#define ENCODERS_PAD_A { D2 }
#define ENCODERS_PAD_B { D3 }

Keycaps & Securing The Case

Once you are happy that your keyboard is working and that the wiring is correct you can clip the pro micro into position on the case bottom. You may require a little hot glue to hold it in place. Once you have the two halves of the case together secure the plate to the case bottom with 4 m3 screws. Once these are in place, flip the case over and use four more m3 screws in the corners to tighten the case up. Be careful to not over tighten and split the plastic.

Finally add your keycaps and get clacking.