Custom Ortholinear 60-ish Percent Mechanical Keyboard

Similar projects worth following
Many of you keyboard enthusiasts have probably already built a keyboard of your own. The 60% form factor seems to be one of the most popular choices. For ergonomic reasons, you might want to try an ortholinear keyboard, which has columns aligned in straight lines.

Lattice60 makes the shift to those matrix keyboards easy as it allows you to reuse many parts from your existing keyboards. The custom plate and case is designed to accommodate off-the-shelf keycaps with various profiles (ASA in my case). This is opposed to existing ortholinear keyboards (e.g. the Planck) which require 1u-only keycaps with row-independent profiles (e.g. DSA).

In the upcoming weeks I will be posting Logs about various issues I run into during the build process and how I overcame them. And maybe you can apply some of that to your own projects. I will also publish the design files once they are ready. So follow the project to receive updates.

Lattice60 uses hand-wired switches and a Sparkfun Pro Micro running QMK.

All files will be uploaded to the Github repository on the left side.


Model to test stringing on 3D printer.

3mf - 30.31 kB - 05/30/2022 at 13:29


  • 1 × Sparkfun Pro Micro Micro controller and Micro USB cable with data transfer capabilities ;-)

  • 3D Printer Bed Levelling and First Layer Adhesion

    Daniel07/29/2022 at 01:02 0 comments

    The plate of the keyboard is printed flat on the print bed. And because of its size, I have to position it diagonally within my 300×300 mm print area. While I never had problems with bed levelling when printing smaller parts, this one turned out to be quite a challenge. It made me check printer settings I've never thought of before.

    Straighten Printer Assembly

    The initial assembly of the printer mainly involved mounting the gantry to the base frame. But since test prints at that time looked fine, I didn't pay much more attention to the assembly accuracy.

    The fine-tuning for the plate print started with the levelling of the X-axis. I followed Method 1 of the official service tutorial. But before tightening the eccentric nuts along the vertical tracks, I also ensured that the two Z-axes run in parallel. After measuring the distance between the two vertical gantry posts near the top, I brought the extruder to its maximum height. The same distance was then set near the bottom, before bolting it down to the base frame again. Contrary to the Creality troubleshooting tutorial (part 1), I tightened the eccentric nuts quite firmly, so they can barely be turned by hand. The same goes for the eccentric nuts on the X-axis, since the auto bed levelling relies on all axes being rigid.

    For the Y-axis, I roughly followed a video and first loosened the middle pulleys under the print bed on both sides. The two outer nuts on the right side should then be tightened to remove any play of the print bed. Ensure that there is no wiggle over the whole range of motion of the Y-axis. After that, I tightened the middle pulleys on both sides to the same degree as the other four, so each of them touches the rails at all times. Lastly, I also tried to straighten out the rails by loosening the middle bolts as suggested in the video. But since my extrusions don't seem to actually be straight, I had to forcefully bent them outwards and holt them in place using the bolts in the middle.

    Z-Axis Compensation

    After successfully levelling the print bed, I faced another problem. While printing the first layer, ripples formed as if the extruded filament is pushed around by the nozzle.

    A helpful forum post confirmed my suspicion that the nozzle is too close to the print bed. The problem was resolved by increasing the Initial Layer Height and therefore the clearance of the nozzle. I didn't make any changes to this parameter.

    The post also mentioned the friction of the levelling card, which corresponds to the Z-Axis Compensation on the printer. That is a fixed offset for the nozzle height. The dilemma: increasing it will get rid of the ripples, but might lead to bad adhesion of the filament to the bed. The best solution for me is to

    1. Take a piece of paper and lower the Z-axis until there is some drag
    2. Move the print head to confirm that there is only small amount of drag at different points within the print area (increase offset if necessary)
    3. Increase Z-axis compensation by an additional 0.04 mm

    Applying glue stick to the print area helped to hold the first extrusion lines in place. In the slicer, the Printing Temperature Initial Layer can also be increased by 5 deg for better adhesion.

  • Read Keystrokes using Matrix Scanning

    Daniel05/27/2022 at 00:17 0 comments

    In a previous log I have setup a breadboard with a Pro Micro and some diodes and switches to test the firmware. I was interested how the microcontroller (MCU) actually finds out if a switch is pressed and at what speed it does that. Recall that the keys are arranged in a matrix, where switches of each row and column are connected to one another. Each row and column also get assigned a pin on the MCU.

    Due to the limited number of connections to the MCU, not all switches can be read at once. Instead, matrix scanning is applied. In the case of QMK, rows are read in a time-multiplexed manner, one at a time. This can be visualized by hooking up the two channels of an oscilloscope to the two rows of my 2x2 test keyboard (green cables).

    The image below shows the signal captured by the scope. The upper plot belongs to row 1 and the lower one to row 2. We can observe that the signal is high by default. The pulses, which occur at a fixed rate, indicate that the respective row is being read.

    The row pins are outputs of the MCU, since the pulses are present regardless of the switches being pressed or not. Accordingly, the column pins are configured as inputs. They are connected to an MCU-internal pull-up resistor. That means their input signal is high by default, except if the line is pulled to ground. And that only happens if the following two conditions are true:

    1. A row pin has been pulled low and outputs a zero
    2. A switch between this low row signal and the column input has been pressed

    A schematic of the 2x2 keyboard should make that clearer. In the below example, switch (1,1) is pressed. When row 1 is scanned (by pulling the line to zero), the inputs read 0 and 1 for the two columns, respectively. For row 2, both inputs are pulled high by the resistor since no switches are pressed. This way, the controller can work out the coordinates of the pressed switches.

    But how fast is this whole procedure? Using the cursors on the oscilloscope, we can determine the time difference between subsequent pulses on a row. You can see that keys are read every 210 us or more than 4000x per second. Pretty fast! So, it's unlikely that keyboard will every miss a keystroke. The overall latency until the input is recognized by your computer is obviously much longer since it needs to be processed by the Pro Micro and the computer hardware first.

  • Avoid Stringing on Creality CR-10 Smart 3D Printer

    Daniel05/22/2022 at 07:49 0 comments

    In order to stabilize and prevent switches from moving when being pressed, each of them sits in a socket. And mounting of the keyboard plate requires studs which hold the screws. While 3D printing, the nozzle travels between all those protrusions at every layer. That sort of geometry frequently causes stringing, where material oozes out from nozzle, when it shouldn't: during travel moves. Same goes for the USB connector, where stringing appeared in the hole.

    EDIT: Stringing is highly dependent on the quality of your filament. Below tests were conducted using Creality's PLA which came with the printer. Presumably, the filament also contained moisture at the time of printing. I ended up printing the case with eSun PLA+ and smaller Retraction Distance/Speed as recommended by eSun. I also disabled Combing completely to reduce print time. Almost no stringing occurred. Refer to below table for the final values.

    Initial Results

    I use the Creality Slicer, which is a fork of Cura. To optimize the printer settings, I have created a small test setup, which completes printing in around 15 minutes. You can see that the original print settings are pretty bad:

    Optimized Settings

    ParameterDefault ValueCreality PLAeSun PLA+
    Retraction Distance5 mm10 mm4 mm
    Retraction Speed60 mm/s50 mm/s
    Combing ModeNot in SkinOff
    Outer Wall Wipe Distance0.0 mm0.5 mm
    Travel Speed120 mm/s200 mm/s

    The first thing to adjust were the retraction settings. Before every travel move, the filament is pulled back by the extruder to relieve the pressure in the hot-end and prevent it from oozing. The default Retraction Distance was set to only 5 mm. Increasing that to 10 mm made a big difference. I have also experimented with different Retraction Speed, but the effect was not visible in the test prints, so I just used the default.

    I left the Combing Mode set at the default "Not in Skin", which adjusts the travel paths such that the nozzle moves over already printed objects as much as possible. This way, the leaking material is spread across the printed surfaces instead of building strings.

    Another setting to adjust was the Outer Wall Wipe Distance. Before each travel, the nozzle loops over the just printed geometry to "wipe off" the excess material. From my experiments, the impact is almost negligible. My final setting is 0.5 mm.

    Increasing the Travel Speed minimizes the duration of travel moves. In theory, quicker travel should reduce the volume of oozing material. I increased the speed to 200 mm/s, but the difference in the end result is small.

    Those settings resulted in the print below. There is a visible improvement. However, light stringing does still occur at the edges of the sockets. Please also note that wet filament can lead to stringing.

    Irrelevant Parameters

    Coasting was mentioned multiple times when I searched the internet for solutions against stringing. Before a travel move, it stops the extrusion early to use a certain volume of oozing filament as build material. But in my experiments, enabling this setting and trying different volumes led to identical prints. Coasting is currently marked as an experimental feature.

    If the Printing Temperature of the hot-end is lower, the viscosity of the filament increases. That should make it less likely to drip out from the nozzle. I reduced the temperature to the minimum of 195 C for my PLA. But the results were the same to the 200 C I had used initially.

    Excessive Retraction

    Retraction had by far the largest influence on the print quality. But pushing it too far, is not a good idea as well. Below is a print with 15 mm retraction, which shows almost no stringing. What isn't visible in the pictures is that the dimensions are way off. The diameter of the sockets is not wide enough for the switches to slide inside easily.

    Always check your dimensions after you have done adjustments to your print settings.

  • Flashing QMK Firmware onto Sparkfun Pro Micro

    Daniel05/13/2022 at 14:43 0 comments

    There are many tutorials, which tell you how to flash the QMK firmware onto a Sparkfun Pro Micro. The official QMK tutorial and their documentation on flashing are great starting points. Nevertheless, I've been running into problems along the way, causing the whole process to take much longer than I have hoped for. In this guide, I will explain the steps I took to finally get the firmware running and how I resolved the issues I faced along the way.

    The things you need

    On the hardware side, you need the Pro Micro and a Micro USB cable. I have used the original from Sparkfun, but there exist plenty of clones as well. Just take not that the behaviour might differ from the original one.

    The cable was the cause of my first frustration. The Pro Micro was not detected by my PC. There wasn't even this sound you would typically hear when plugging in a USB device. Turns out, the majority of Micro USB cables I possess are charging cables and do not actually transfer data. Only after my fourth or so attempt the microcontroller (MCU) was finally detected. Lesson learned: Don't use just any random cable you can find and make sure it supports data transfer.

    I flashed the firmware from a Windows 10 computer. There is no need to install additional drivers. Multiple utilities exist, which can write .hex files into the MCU memory, the most popular being QMK Toolbox and AVRDUDESS. As you will see below, they did not work me. I succeeded when compiling and flashing using the QMK command line interface (CLI).

    Reset to enter the bootloader

    To make the MCU programmable and appear as a serial device at a COM port in your device manager, it needs to enter the bootloader. Following the official Sparkfun Hookup Guide, this is done by connecting quickly (within 750 ms) the RST and GND pins twice. You are then given 8 seconds to flash the firmware.

    The reset for Pro Micro clones might deviate. Try using this alternative procedure.

    Unsuccessful attempts

    .hex files can be conveniently generated online, for example with kbfirmware, where you can explicitly select the MCU in use (ATmega32U4 in our case). However, flashing with QMK Toolbox resulted in Windows not recognizing the device:

    In the device manager, the Pro Micro pops up with as "Unknown USB Device (Device Descriptor Request Failed)":

    And this is despite the .hex file being successfully written into the MCU. No error or warning during flashing occurred. Verification of the written firmware passed:

    avrdude.exe: verifying ...
    avrdude.exe: 13120 bytes of flash verified

    In some situations, however, the device was not even able to be programmed. Then QMK Toolbox returned the errors below.

    > avrdude.exe: ser_drain(): read error: The I/O operation has been aborted because of either a thread exit or an application request.
    > avrdude.exe: butterfly_recv(): programmer is not responding
    > avrdude.exe: error: programmer did not respond to command: exit bootloader


    The Sparkfun Pro Micro comes in two versions: 5 V running at 16 MHz and 3.3 V running at 8 MHz. What version is used in indicated on the backside of the circuit board. QMK tools seem to assume that the 5 V version is in use, while I use 3.3 V.

    In order to indicate the reduced clock frequency, a compilation of the firmware from source was required using the QMK CLI. Refer to the next section for more details. The source files for each keyboard/keymap include the file. To set the correct clock frequency, add this line (Reference):

    F_CPU = 8000000

    After flashing, the Pro Micro got finally recognized as a HID controller.

    Testing the firmware

    Before soldering the whole keyboard matrix, I wanted to make sure that both the firmware and the hand-wiring works as intended. Therefore, I've set up a minimal test on the breadboard with three switches wired as a 2x2 matrix. Yellow cables mark the matrix columns, while green...

    Read more »

View all 4 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates