Tweaking The Value Mechanical Keyboard With QMK


The mysterious 60% mechanical keyboard returns. I had attempted to flash the firmware of several other keyboards in the hopes of enabling more functionality, and had varying degrees of success before finally finding a method for flashing QMK.

Since getting QMK on the keyboard, i've modified the configuration extensively for my own personal use. This write-up will serve as a point-in-time walkthrough of my configuration, as well as the methodology behind it.

A public release of my QMK configuration can be found at niallr/qmk-firmware-public.

A photo of the DK61 keyboard with custom keycaps.

Keyboard Aspirations

Configuration Items

Reset To Bootloader shortcut

RESET is used to put your keyboard into DFU mode so you can flash firmware without physically pressing the reset button usually found in the underside of the keyboard / grounding the BOOT pin.

Space Cadet Shift

I type parentheses ("(" & ")") frequently, and holding Shift while moving my right hand to the correct keys can reduce WPM. Space Cadet Shift is a useful function for adding additional functionality to the 2 Shift keys. Tapping Left Shift gives an open parenthesis. If the key is held and another key is then pressed, the Shift key works as usual and gives a capital letter. Right Shift functions the same way, but with a closing parenthesis. I can then use my pinky fingers to tap the Shift keys when required.

Layers

QMK enables the definition of multiple key layers. As my keyboard is 60%, it makes sense to at least have the arrow and functional keys available on another layer, as well as any macros that I have coded. The modifiers for the different layers are Fn, Caps Lock hold and Tab hold.

Mouse Keys (config.h)

I added mouse keys to the Tab hold layer so that I could easily use my left pinky finger to hold the key. I adopted the mouse key configuration from the Miryoku QMK layout with no changes. I then bound the following: - Mouse movement to WASD - Scroll up/down to Q/E - Mouse clicks to JKL (left, middle, right)

Arrow Keys

I added arrow keys to the Caps Lock hold layer so that I could easily use my left pinky finger to hold the key. I then bound the arrow keys to WASD.

Enabling Granular RGB Matrix Control

Alongside OPENRGB_ENABLE = yes in rules.mk (see my previous write-up regarding OpenRGB), I added RGB_MATRIX_ENABLE = yes and RGB_MATRIX_DRIVER = SN32F24xB for granular control of the RGB matrix within functions.

Random Number Generation

There is a built-in function that can send a random character to the host device, though my requirement was to be able to dynamically generate a random number which can then be used in another function (i.e. a macro or to then map that number to a alphabetic character). I also wanted to be able to provide a range for the generation too.

My approach was to utilise the srand() function, which takes a seed number to generate pseudorandom numbers. I used a timer value as the seed number to make the generation as "random" as possible. I finally wrapped this with upper and lower bound range parameters, and used a nifty formula to constrain the pseudorandom number to the given range.

Random Number Generation Applications In Macros

Random Alphabetic Character Generation

I used the "random number in range" function to create a "random letter" function by constraining the generated number to upper bound of 26. I can then use register_code (KC_A + number) and unregister_code (KC_A + number) to send a pseudorandom alphabetic character.

Random Delays in Macros

I used the "random number in range" function as an input for a while loop that checks for timer_elapsed(some_timer) to reach the given number input and waits 10ms if not met. In combination with the "random number in range" function, random delays can be then be added between macro steps (i.e. between key presses and for defining key hold duration).

Press Multiple Keys Simultaneously

Typically you can use register_code(key) commands in series for each key to be held, then unregister_code(key) afterwards to release, so 2 lines of code per key hold. The small utility function reduces these scenarios to one line regardless of the number of keys.

String Macro

I used SEND_STRING to send characters for a given string on keypress, such as my email address.

Customising RGB

I wrote an override for rgb_matrix_indicators_user() with a switch statement on get_highest_layer(layer_state) to check when each layer was active. I then set the modifier key for the active layer to glow green.

Conclusion & Future Work

QMK is a fantastic addition to any keyboard. With the additions listed above, my keyboard aspirations have been mostly fulfiled at a budget pricepoint. I will continue to refine this configuration as I use it more.