How to build your first Mechanical Keyboard

I built my first mechanical keyboard from scratch! Learn how I did it.

Advertisements

Creating the CAD models

The process of creating our CAD models is relatively straightforward, but could require more advanced skills for more complex layouts. We need a keyboard layout which we’ll then convert into CAD models. After the models have been created, we will clean them up a bit and convert them to a format that the laser cutter can handle.

Keyboard Layout

To begin, we’ll need to decide on a layout. I used the very handy Keyboard Layout Editor tool, which allows users to create, share, and save keyboard layouts, and even has a number of examples. Let’s grab the default numpad layout, and save it as a .json.

downloadjson.PNG
Download JSON and you’re on your way

While we’re at it, let’s create a project folder to organize everything under, including our new layout file. We’re now ready to create the CAD files, but first we’re going to need the software.

Required CAD Software

To generate CAD files, we’ll use the following pieces of software:

  1. OpenSCAD
    1. CAD software that focuses on programmatic design
  2. InkScape
    1. Also requires this extension
    2. Reads in OpenSCAD output to make simple modifications
    3. Exports a format for the laser cutter
  3. BoardBuilder
    1. Python module which does the dirty work of converting a layout .json to SCAD
    2. Setting up and installing a Python environment is out of this guide’s scope
      1. Sorry! I have to stop with the details somewhere

Now that we have our software installed, and a Python environment ready with the BoardBuilder module, we can get started on generating our CAD files – the top (or faceplate), the middle (where the wires and microcontroller will go), and the bottom, which keeps everything together.

Creating the OpenSCAD files

We’ll use a fairly straightforward Python script to generate the CAD models using the BoardBuilder module. Here is the full python source code, which is also available (and possibly updated) in the GitHub for the project linked previously:

#Set up some parameters
#Most are in mm
import os
from BoardBuilder.BoardBuilder import BoardBuilder

#Get the current directory and files
file_directory = os.path.dirname(os.path.realpath(__file__))
layout_name = “numpad-layout.json”
layout_path = os.path.join(file_directory, layout_name)
output_dir = ‘./out/’

#Set up the parameters
stabilizers = “costar”
horizontal_padding = ’12’
vertical_padding = ‘35,12’
corner_radius = 6
screw_count = 6
screw_diameter = 5
screw_padding = 6
screw_side_count = 6

#Build the board
board = BoardBuilder(layout_path, horizontal_padding, vertical_padding, corner_radius, screw_count, screw_diameter, False, stabilizers, screw_padding, screw_side_count)
board.render_mid_layers(output_dir)

#The top and bottom have different holes for the screws
screw_diameter_face_bottom = 3
screw_side_count_face_bottom = -1
board = BoardBuilder(layout_path, horizontal_padding, vertical_padding, corner_radius, screw_count, screw_diameter_face_bottom, False, stabilizers, screw_padding, screw_side_count_face_bottom)
board.render_top_plate(output_dir)
board.render_bottom_plate(output_dir)

Whew! That’s a lot to look at all at once. It’s OK, I’ll break it down into pieces.

Imports

#Set up some parameters
#Most are in mm
import os
from BoardBuilder.BoardBuilder import BoardBuilder

This is very simple. We import our os library, which is useful for file paths. We also import the BoardBuilder module, which is located in the BoardBuilder folder/file.

File Paths

#Get the current directory and files
file_directory = os.path.dirname(os.path.realpath(__file__))
layout_name = "numpad-layout.json"
layout_path = os.path.join(file_directory, layout_name)
output_dir = './out/'

Now we get all of our file paths sorted out. We get the current directory we’re running the script in, and build the paths to the layout file which is in the same directory. We also specify that the output should be in a folder named ‘out’.

Board Parameters

#Set up the parameters
stabilizers = "costar"
horizontal_padding = '12'
vertical_padding = '35,12'
corner_radius = 6
screw_count = 6
screw_diameter = 5
screw_padding = 6
screw_side_count = 6

This is where we define the parameters used to generate the CAD. You’ll notice simple things like the corner radius and how many screws we want, but also more advanced parameters such as the padding on each side, as well as how many sides the ‘screws’ have. You can see that 6 sides are specified, which will produce a 6-sided (hexagonal) hole. You’ll see why later.

The Middle Layer

#Build the board
board = BoardBuilder(layout_path, horizontal_padding, vertical_padding, corner_radius, screw_count, screw_diameter, False, stabilizers, screw_padding, screw_side_count)
board.render_mid_layers(output_dir)

Here we create our board builder with the above parameters, and have it render the middle layer to our output directory. This creates our OpenSCAD file for the middle layer.

The Top and Bottom Layers

#The top and bottom have different holes for the screws
screw_diameter_face_bottom = 3
screw_side_count_face_bottom = -1
board = BoardBuilder(layout_path, horizontal_padding, vertical_padding, corner_radius, screw_count, screw_diameter_face_bottom, False, stabilizers, screw_padding, screw_side_count_face_bottom)
board.render_top_plate(output_dir)
board.render_bottom_plate(output_dir)

Finally we make the faceplate and the bottom. However, we want the screw diameters to be smaller, so we can countersink the screws into the layers, and circular holes. And that’s it – the Python script sets things up by importing modules and setting variables, and then creates a middle layer with larger hex holes, the faceplate and bottom layers with circular smaller holes we’ll countersink later.

Let’s open each SCAD file to take a look:

openscad.PNG
Press the Render, Zoom, and Top-View buttons (highlighted)

Converting OpenSCAD to Vector

You now have your very own CAD files, however these are not something that a laser cutter can use yet. We’ll need to convert them into a format that your laser cutter can actually do something with. Now, the exact format will depend on the machine’s firmware, but in my case I need a .lyz file. To create this, we’ll output our CAD files as a vector format that InkScape can read.

To do this in OpenSCAD, export the model as a .dfx.

exportDFX.PNG
OpenSCAD already does all the hard work

You’re done with OpenSCAD. Now, if you’re CAD savvy you can use these models and do your own custom modifications, but this will work for the case of this tutorial.

Converting with InkScape

We’ve got our .dfx files, which InkScape can utilize. However, this particular laser cutter requires a .lyx file. Since OpenSCAD couldn’t do this automatically we’re going to use InkScape to handle it. Before we export, we’re going to make a slight modification: a hole for the cable! When we generated the CAD model, it didn’t have a spot for the USB cable to exit – we could have added this into the model but we’re going to do it now! You can use the files in GitHub for guidance.

inkscape.PNG
Wire hole and the hexagonal mounting holes (circled)

We have our layers ready to go – you shouldn’t have to touch the faceplate and the bottom but it doesn’t hurt to take a look! For my case, the lines needed to be red to mark a cut – blue and black lines implied a raster fill and were not what I wanted, so double check any color requirements. To export, hit File->Save As, and change the output type to .lyz.

exportLYZ.PNG
This option is only available if you installed the plugin

And we’re ready to cut! At this point, we’ve taken all the required steps for generating the CAD models; now we can get to the fun part!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s