Keyboard

Study Source:

Choosing Keyboard Switch

Choosing Keyboard Switch

Here is a short and important introduction to choices of components in mechanic keyboard. And here is a Building an O-Ring 60% Keyboard out of Acrylic Series and it will give you intuition of the manufacture. There is no PCB making and firmware design in the above videos. You can watch How we designed a mechanical keyboard PCB! (Series) for those.

Parts of Mechanical Keyboard

Parts of Mechanical Keyboard

Different Switch Properties: Based on Structure and Sense

Tactile Clicky Linear
Feel 1 1 0
Hear 0 1 0

The following contents are summary of Mechanical Keyboard Knowledge Series, but excluding QKT5 - Keycaps, QKT6 - Protocol, QKT7 - Cleaning, QKT8 - Layout

For more switch options, check out this blog

Tactile Switch

Tactile Switch Family

Tactile Switch Family

Tactile Switch: No noisy sound.

Rubber Domes Keyboard

Made of rubber, common in laptops. Need to push all the way in to register key press. Short distance. Cheap to make.

Rubber Domes is based on Resistor and Touch Down: 通过按压键帽从而使上下薄膜导通,且按键回弹慢,幅度小;制作成本、手感、寿命均远不如机械键盘. Mechanics Keyboard is based on Resistor and Touch Point: 通过按下机械开关,触发其下的物理开关,从而传输信号,随后按键能够快速回弹至原始位置,且坚固耐用

Capacitive Switch

Capacitive Switch: 通过程序设置阀值判定是否接通,因不存在接触点,手感酥软,灵敏度、耐用性非常高,非常受码字或对灵敏度有高要求的人群喜欢

Capacitive Keyboard Structure

Capacitive Keyboard Structure

There isn't real advantage to Electrostatic Capacitive Keyboard except it wears out slower with less physical feeling.

Clicky Switch

Clicky Switch Family

Clicky Switch Family

Clicky Switch: Special clicky mechanism on top of tactile switch to make noise.

Note that clicky switch make noise at the time of registering click, unlike tactile switch that only make noise when you press hard and bottom out. Therefore, clicky switch will generate noise even if you press unusually slow. Also for fast typing, tactile switch do produce noise.

Linear Switch

Linear Switch

Linear Switch

Linear Switch: no tactile of clicky noise feedback. They just get progressingly stiffer. Gamer like because they think feedback distract them while typers don't like them because they need feedback.

Different Switch Manufacturer

Common Manufacture: Cherry, Alps, Matias, IBM, Topre

Cherry Switch

Cherry Switch

Cherry Switch

Cherry Structure

Cherry Structure

Cherry is still in manufacture and readily avaliable. The manufacture isn't very good. Many clones of MX switches start appear in market (like Gateron)

Cherry Parameter

Cherry Parameter

青轴:段落感最明显,敲击声也最大,是机械键盘的代表轴。适合打字使用,但声音较大,需注意
黑轴:直上直下,没有明显的段落感,噪音也较小。适合游戏使用,推荐手劲大的同学使用
茶轴:各方面都比较均衡的轴,轻微段落感,噪音较小。兼顾游戏和打字
红轴:最年轻的主流轴,手感类似黑轴,但压力更小。兼顾游戏和打字
银轴:可参考红轴参数,除非专用于游戏需求,否则新手建议购买红轴
静音红:红轴升级版,价格更贵,但手感更好、更静音,游戏、码字的体验更佳
静音黑:对比黑轴,声音降低30%,但手感并没有变好,带有细微的橡胶手感
矮红:手感类似笔记本电脑的键盘手感,键程短,轴体高度也比较矮
矮银:触发行程比矮红轴更短,打字灵敏

Cherry Switch is the most compatible switch

Kailh (凯华: 东莞市凯华电子有限公司)

Kailh Structure

Kailh Structure

Kailh Parameter

Kailh Parameter

BOX白:对标cherry MX青,有着类似圆珠笔的按压手感,喜欢青轴手感的同学更推荐
BOX红:对标cherry MX红,直上直下的手感,减小了压力克数,手感较为轻盈
BOX静音红:采用圆形挡墙设计,更静音,更轻,适合办公室人群
BOX茶:对标cherry MX茶,但是增加了压力克数,手感较为的厚实,声音较小
BOX静音茶:除了触感力以及行程有点的差别外,无明显的区别,手感上,BOX静音茶比起BOX茶会更硬且更静音一点
BOX黑:对标cherry MX黑,采用圆形挡墙设计,减少了压力克数,更加的适合我们的手感,是游戏的首选

重力轴系列
Navy(海军蓝):采用大压力克数、大段落的设计,加粗扭簧增强响声,段落感更明显,声音更大,手感更带感
Jade(翡翠绿):与Navy相比,压力、声音稍小,段落感有所停顿,回弹稍慢,带有细微的阻力感

TTC (惠州创联电子有限公司)

TTC Parameter

TTC Parameter

金粉轴:TTC代表轴,手感轻盈顺滑,快速触发,±5gf弹力公差,手感一致性高
金茶轴:按钮优化设计,段落感更佳,干脆利落,有很好的输入反馈
金红轴:压力比金粉较重,适合打字时惯用力的同学
快银轴:官方介绍比某银轴导通还要快10%,想必会非常适合忠实的游戏玩家
月白轴:分段式长弹簧,压力稳定均衡,触底快速回弹,段落清晰,触感降噪
静音月白轴:双保险消音结构设计,静音效果明显,按压顺畅无肉感,是段落轴爱好者的福音
爱心轴:独特的乐高式机械轴,每颗轴芯都有一颗甜蜜的爱心,别的不说,送男女朋友肯定合适
烈焰红轴:相较于普通红轴,烈焰红轴的导通力和导通行程一致,但是触底力要小10gf,回弹力则是大了10gf
          搭配24.5mm的超长弹簧,手感更加Q弹,更有劲道
兄弟轴(金兰轴):采用触底消音件降噪,消除触底撞击产生的杂音,降噪明显;
                  凸显特别调校过的按钮机构,声音纯净,清脆悦耳;
                  段落力差是cherry MX青轴的2倍,段落动作转换干脆利落,二次触发效率提高50%

Gateron (惠州盖特龙电子科技有限公司)

是价格昂贵的cherry轴的最好替代轴体之一 (出厂自润,无需再自行润滑,轴座兼容性好,卡扣结构稳定,透明上盖对RGB兼容性也有提升,杂音控制不错,较cherry轴声音更安静)

Gateron Parameter

Gateron Parameter

G银Pro:售价1.5元/颗,提供单端/双段弹簧选择,单段顺滑,双端跟手
G白Pro:售价1.6元/颗,手感偏轻柔,颜值出众,做工精细,提供单端/双段弹簧选择,单段顺滑,双端跟手
G黄Pro1/2:售价均为1.2元/颗,出厂自润、轴体金触点工艺升级,提供三脚/五脚版本
G红Pro1/2:售价均为1.2元/颗,出厂自润、轴体金触点工艺升级,提供三脚/五脚版本

Alps

Alps Switch

Alps Switch

They do no longer being made. Generally considered better feeling. They are prone to dust and easily get sticky.

Matias

Matias Switch

Matias Switch

Matias is small keyboard manufacture making Alps switch (but not as good as original Alps). They can do backlit easily because they are transparent.

IBM

IBM Switch

IBM Switch

Generally make Buckling Spring switch, loud but sounds fine.

Topre

Topre Switch

Topre Switch

Very advanced tactile switch, but very very expensive.

Keyboard Controll

Rollover: how many keys you can press simultaneously to register event at the very least.

Ghosting: key detected when not being pressed

Ghosting "Z" when pressed "A", "S", "X" simultaneously

Ghosting "Z" when pressed "A", "S", "X" simultaneously

When pressing "A" and "S", only those two keys are detected because controller can work out the math. However, when "X" is pressed in addition to those two keys, the controller cannot tell whether "Z" or "X" or both is pressed. Therefore, controller blocks (blocking) the signal of both "Z" and "X" because we don't want to register a key we never pressed.

N-key Rollover: where the issue of ghosting and blocking don't exists, every key combination can be registered.

Achieve n-key rollover with diode for each key

Achieve n-key rollover with diode for each key

Or to make keyboard that doesn't use conduction.

Capacitor

Capacitor

Magnetic Valve

Magnetic Valve

Keycap

Keycap Sizes

Keycap Sizes

Main Material

There are two main keycap material: ABS (丙烯腈丁二烯苯乙烯) and PBT (聚对苯二甲酸丁二醇酯).

ABS键帽: 因为其质地柔软,给人贴近类肤的触感,同时由于材质本身具有成本低,强度高,韧性好,加工方便等优点,在低端价位的键盘里非常的常见,当然ABS除了易沾油之外,还会有泛黄的可能性,所以大家需要注意,想要保证键盘的寿命以及手感保持完美状态,定期的清洁键盘是非常有必要的

PBT键帽: PBT相比ABS则更加的坚固,耐用,且造价也更加的昂贵,因为表面颗粒感明显,所以抗油性更强,且并不会随着时间而变黄。而且个人认为PBT材质的键帽在开始的时候虽然会比较的硬,但是在长时间的使用,磨合后,手感还是会比ABS的要好很多的

Cherry Keycap Profile

Cherry Keycap Profile

由上可知,cherry以及OEM高度的键帽是最受欢迎的键帽高度,但无论我们选择哪种键帽高度,我们在购买前都必须确保我们的键帽与当前轴体兼容。

如何确定键帽是否与我们的轴体兼容? 最简单的方法就是通过我们键盘的尺寸及键位布局,确定我们所需的键帽尺寸,值得一提的是大多数键帽都与 Cherry MX 轴由良好的兼容性,如果你用给也是这类轴,那么到也无需过多的担心了 如果想要兼容RGB,那么还得考虑键帽的透光性

Letter Prints

小小键帽上的字符也由很大的讲究,不好的字符工艺容易造成长时间的使用后,字符脱落。常见的字符工艺:激光镭雕、丝网印刷、热升华、镂空字体以及双色注塑

激光镭雕: 使用激光将所需的字母刻录到键帽中,主要用于白色键帽或灰色键帽 丝网印刷: 键盘字母将被镂空在特制的编织网中,刷油漆时,油漆会填充空心部分并在键帽上打印字母。 热升华: 一种利用热量使染料浸渍材料的过程,成本高,且不适用于打印白色字符或在黑色键帽上打印 镂空字体: 常用于制作透明按键——透明塑料上覆盖有一些涂层,激光烧掉涂层,使透明塑料露出所需字符的形状 双色注塑: 将两种不同颜色,不同材料融合形成双层键帽,双色注塑能够保证字符永不磨灭,且字符颜色不受键帽颜色所影响,是最好的键帽类型

至于选择哪种?就看自己的喜好以及预算了,预算高的可以选择热升华、镭雕、双色注塑的键帽,从实用性角度出发,个人觉得双色注塑会是最好的选择

平衡杆 卫星轴

平衡杆, 卫星轴

平衡杆, 卫星轴

平衡杆的作用是使得键盘在打字过程中保持稳定,使得手感更加的舒服,但由于其装配难度较大,所以并不太适用于量产的机械键盘,所以我们很难在量产的机械键盘看到它。

大多数的客制化键盘都会采用卫星轴,因为卫星轴的设计更加的方便拆卸和安装。虽然相对会牺牲点手感上的舒适度,但是换来了防止我们在拆卸键帽时把卡扣拆断的可能性

Hot-Reload (Hot Swap)

Most keyboard switches are soldered into PCB, hot-reload allows to switch switches without breaking or re-solder PCB.

Key Mount PCB

Key Mount PCB

Most switch has 1 central mounting point and 2 peripheral mounting point and 2 pins for signal. Hot swap is not designed for compability, but rather designed for ability to try different switches for different feeling without re-solder. Here is how hot swap switches are made.

Keyboard with Trackpoint Solution

If you want to use trackpoint with existing driver library, zmk does not support trackpoint and therefore you have to use qmk.

From https://xkcd.com/243/

From https://xkcd.com/243/

There are many people who have created keyboards with trackpoints:

However, none of above mentions how exactly the Thinkpad Trackpoints are wired. Here is the documentation for all trackpoints and pin definitions. According to QMK document trackpoint (and touchpads) uses PS/2 communication just like old PS/2 mouses. The clock pin and data pin should connect to a pull-up resistor of 4.7 k\Omega as below.

          DATA ----------+--------- PIN
                         |
                        4.7K
                         |
MODULE    5+  --------+--+--------- PWR   CONTROLLER
                      |
                     4.7K
                      |
          CLK   ------+------------ PIN

There are three available modes for hooking up PS/2 devices: USART (best), interrupts (better) or busywait (not recommended).

Firmware

Although you can use STM32CubeIDE to write firmware, but QMK is a matured product and won't be re-invent the wheel. Alternatively, if you don't want to write C or C++, many people choose to write Rust: awesome-rust-keyboard-firmware

Debouncing: A mechanical switch isn't physically perfect and when the switch is pressed the contact inside the switch can "bounce" back and forth a few times which would cause multiple keypresses. Debouncing is a software solution to this effect.

Dynamic reprogramming: you can change the keymap on the board without having to flash a different firmware. On QMK boards this is done using VIA. It's a GUI tool that works similar to those programs that most people know from Corsair or Razer.

QMK

To install QMK, simply pip install qmk.

(qmk) ➜  firmware qmk setup -H /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware kokecacao/qmk_firmware
Ψ Found qmk_firmware at /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware.
Would you like to set /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware as your QMK home? [y/n] y
Ψ Wrote configuration to /home/koke_cacao/.config/qmk/qmk.ini
Ψ QMK Doctor is checking your environment.
Ψ CLI version: 1.1.0
Ψ QMK home: /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware
Ψ Detected Linux.
⚠ Missing or outdated udev rules for 'atmel-dfu' boards. Run 'sudo cp /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware/util/udev/50-qmk.rules /etc/udev/rules.d/'.
⚠ Missing or outdated udev rules for 'kiibohd' boards. Run 'sudo cp /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware/util/udev/50-qmk.rules /etc/udev/rules.d/'.
⚠ Missing or outdated udev rules for 'stm32' boards. Run 'sudo cp /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware/util/udev/50-qmk.rules /etc/udev/rules.d/'.
⚠ Missing or outdated udev rules for 'bootloadhid' boards. Run 'sudo cp /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware/util/udev/50-qmk.rules /etc/udev/rules.d/'.
⚠ Missing or outdated udev rules for 'usbasploader' boards. Run 'sudo cp /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware/util/udev/50-qmk.rules /etc/udev/rules.d/'.
⚠ Missing or outdated udev rules for 'massdrop' boards. Run 'sudo cp /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware/util/udev/50-qmk.rules /etc/udev/rules.d/'.
⚠ Detected ModemManager without the necessary udev rules. Please either disable it or set the appropriate udev rules if you are using a Pro Micro.
⚠ Missing or outdated udev rules for 'caterina' boards. Run 'sudo cp /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware/util/udev/50-qmk.rules /etc/udev/rules.d/'.
⚠ Missing or outdated udev rules for 'hid-bootloader' boards. Run 'sudo cp /home/koke_cacao/Documents/Koke_Cacao/CAD/Workspace/kokipad/firmware/qmk_firmware/util/udev/50-qmk.rules /etc/udev/rules.d/'.
Ψ Git branch: master
Ψ Repo version: 0.17.5
⚠ The official repository does not seem to be configured as git remote "upstream".
☒ Can't find arm-none-eabi-gcc in your path.
☒ Can't find avr-gcc in your path.
☒ Can't find avrdude in your path.
☒ Can't find dfu-programmer in your path.
☒ Can't find dfu-util in your path.
Would you like to install dependencies? [Y/n] y

Choosing MCU for QMK

According to this guide, we can see all supported MCU in QMK's ChibiOS fork. For example, this file with #if defined(STM32F072xB) || defined(STM32F078xx) show support for STM32F072xB Chip. Although I am using STM32F072x8 (which is a low flash memory version), the two shares the same documentation, so it is also supported.

This documentation shows every option to configure QMK.

QMK Code Structure

You can think of QMK as no different from any other computer program., the entry point is a main() function in quantum/main.c. The main() initialize hardware such as USB and it runs platform_setup() and protocol_setup() depending on which platform it is compilled on. (although most of code is disabled by #define). After this, the while(true) main loop is entered.

The main loop will call protocol_task(), which in turn will call keyboard_task() in quantum/keyboard.c. This is where all the keyboard specific functionality is dispatched, and it is responsible for detecting changes in the matrix and turning status LEDs on and off.

Within keyboard_task() you'll find code to handle: - Matrix Scanning: detect key press (99% CPU time) - Key Mapping: mapping binary matrix to keycode defined in LAYOUT() - Keycode Assignment: map keycode to symbols. - Process Record: after we know the key we pressed, we run utility functions defined by client - Mouse Handling - Keyboard status LEDs (Caps Lock, Num Lock, Scroll Lock)

Configure QMK for Manufacturer

There are two main types of configuration files in QMK, config.h and rules.mk. These files exist at various levels in QMK and all files of the same type are combined to build the final configuration. The levels, from lowest priority to highest priority, are:

config.h: This is where you use define to set hardware options such as pin definitions and enable or disable options

The config.h file shouldn’t be including other config.h files, or anything besides config_common.h

rules.mk: This is a make file that is included by the top-level Makefile. It is used to set some information about the MCU that we will be compiling for as well as enabling and disabling certain features. This is important for further customization since you can include more libraries in the compiling process.

info.json: Historically QMK has been configured through a combination of two mechanisms, rules.mk and config.h. While this worked well when QMK was only a handful of keyboards we’ve grown to encompass nearly 1500 supported keyboards. That extrapolates out to 6000 configuration files under keyboards/ alone! The freeform nature of these files and the unique patterns people have used to avoid duplication have made ongoing maintenance a challenge, and a large number of our keyboards follow patterns that are outdated and sometimes harder to understand. So info.json is there to generate rules.mk and config.h.

Additional QMK Driver

QMK Hardware Drivers enables additional hardware other than key presses.

QMK is used on a lot of different hardware. While support for the most common MCU’s and matrix configurations is built-in there are a number of drivers that can be added to a keyboard to support additional hardware. Examples include mice and other pointing devices, i/o expanders for split keyboards, bluetooth modules, and LCD, OLED, and TFT screens.

Matrix Scanning

Matrix scanning produce a binary matrix where 0 indicates non-press and 1 indicates press.

{{0,0,0,0},
 {0,0,0,0},
 {0,0,0,0},
 {0,0,0,0},
 {0,0,0,0}}

This is a matrix of 9 pins.

Key Mapping
#define LAYOUT( \
    k00, k01, k02, k03, \
    k10, k11, k12, k13, \
    k20, k21, k22, \
    k30, k31, k32, k33, \
    k40,      k42 \
) { \
    { k00, k01,   k02, k03   }, \
    { k10, k11,   k12, k13   }, \
    { k20, k21,   k22, KC_NO }, \
    { k30, k31,   k32, k33   }, \
    { k40, KC_NO, k42, KC_NO } \
}

Note that the second block of LAYOUT() should match matrix scanning. However, if you look at a 17 key numpad you'll notice that it has 3 places where the matrix could have a switch but doesn't, due to larger keys. We have populated those spaces with KC_NO. (Since not KC_NO will never be triggered because no switch is connect to that specific column and row number.)

Here is an example of unusual keyboard layout mapping.

Keycode Assignment

Keycode Assignment maps physical location of key to meaningful output symbols.

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [0] = LAYOUT(
        KC_NUM,  KC_PSLS, KC_PAST, KC_PMNS,
        KC_P7,   KC_P8,   KC_P9,   KC_PPLS,
        KC_P4,   KC_P5,   KC_P6,
        KC_P1,   KC_P2,   KC_P3,   KC_PENT,
        KC_P0,            KC_PDOT
    )
}

Notice how all of these arguments match up with the first half of the LAYOUT() macro from the last section? This is how we take a keycode and map it to our Matrix Scan from earlier.

Keymap has maximum of 32 layers in const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]. This is so that we can override key definition and enable function keys such as Shift, Ctrl, Fn, Opt, ...

For trivial key definitions, the higher 8 bits of the action code are all 0 and the lower 8 bits holds the USB HID usage code generated by the key as keycode.

Respective layers can be validated simultaneously. Layers are indexed with 0 to 31 and higher layer has precedence.

Keymap: 32 Layers                   Layer: action code matrix
-----------------                   ---------------------
stack of layers                     array_of_action_code[row][column]
       ____________ precedence               _______________________
      /           / | high                  / ESC / F1  / F2  / F3   ....
  31 /___________// |                      /-----/-----/-----/-----
  30 /___________// |                     / TAB /  Q  /  W  /  E   ....
  29 /___________/  |                    /-----/-----/-----/-----
   :   _:_:_:_:_:__ |               :   /LCtrl/  A  /  S  /  D   ....
   :  / : : : : : / |               :  /  :     :     :     :
   2 /___________// |               2 `--------------------------
   1 /___________// |               1 `--------------------------
   0 /___________/  V low           0 `--------------------------

For more about keymap, read on this link and all avaliable keycodes.

QMK Support Keyboard

The compiler can read both config.h and rules.mk as well as info.json. Therefore you can choose to write things in info.json and ignore about any configurations in config.h and rules.mk (ie. leave them blank). Reading info.json instead is called data-driven config

What you need to do:

  1. fork qmk_firmware
  2. make a directory in qmk_firmware/keyboards/<keyboard_name>/. You need to read directory structure
  3. touch a qmk_firmware/keyboards/<keyboard_name>/<keyboard_name>.h and put your #pragma once and #include "quantum.h" in it.
  4. Also put #define LAYOUT() in there if you like to write layout manually. Otherwise, convert your layout.json to info.json with QMK KLE-JSON Converter and put it in qmk_firmware/keyboards/<keyboard_name>/info.json and fill out matrix property for each key. This is your physical layout of buttons.
  5. Fill out other parameters in info.json. These can be found here.
  6. Note that for matrix_pins, if you use direct, you need to fill out every entry in the column with some value (can be null) to avoid errors.
  7. Create config.h with #pragma once and #include "config_common.h" in it.
  8. Create <keyboard_name>.c with #pragma once and #include "keyboard_name.h" in it. You can also include custom functions in it with GPIO Control
  9. Create a directory qmk_firmware/keyboards/<keyboard_name>/keymaps/ and qmk_firmware/keyboards/<keyboard_name>/keymaps/default, touch a keymap.c in it. Write your keymap like the following. (info.json DOES NOT generate keymaps. Only the QMK Configuratior generates keymap.)
  10. Run command qmk compile -kb kokipad -km default. The compiler error will guide your process of filling info.js.
  11. Double check your info.js has the correct processor and correct code.

If you are flashing for the first time, you might not be able to use USB because there is not DFU program loaded.

Below is an example of keymap.c.

#include QMK_KEYBOARD_H

#define FIRST_LAYER 0
#define SECOND_LAYER 1

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [FIRST_LAYER] = LAYOUT(
      KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM,
      KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM,
      KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM,
      KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM,
      KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM, KC_NUM,
      KC_NUM, KC_NUM, KC_NUM, KC_NUM
  )
};

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  return true;
}

When doing USB configurations, read this guide to choose a appropriate vendor id and product id. (Set vid=0xFEED and pid=<unique_per_keyboard>> is a good choice). Use Clueboard as an example.

Keyboard Cases

Below from 鍵盤往事 introduce ways to make keyboard cases.

Tray Mount

Tray Mount

Tray Mount

Good:

Bad:

Case Mount

There isn't a standard for case mount, but usually no screw needed in PCB.

Top Frame Mount

Top Frame Mount

Top Frame Mount

Bottom Mount

Bottom Mount

Bottom Mount

Sandwich Mount

Sandwich Mount

Sandwich Mount

Integrated Mount

Integrated Mount

Integrated Mount

Gasket Mount

Gasket Mount

Gasket Mount

Plateless Mount

Plateless Mount

Plateless Mount

Keyboard PCB

See my github repository

Plate-mount vs PCB-mount switches

Plate-mount vs PCB-mount switches

Also, here are PCB mount holes. Here is a 3D model of the switch.

Table of Content