The short version: The Keychron V5 mechanical keyboard is fully capable of macros, including mouse operations (e.g., right-click). This is enabled by the use of QMK and the length of macros is only limited by the available flash memory in the keyboard’s microcontroller (unlike the Cooler Master ‘CK550 V2’). A showstopper may be that there isn’t any easy way of cancelling macros in progress (a missing feature of all QMK-based keyboards). It is possible to cancel macros in QMK, but it isn’t standard and requires significant programming effort (or maybe it already exists somewhere?).
As a 96% keyboard, it is also crippled by the missing PgUp, PgDn and context menu key keys; a workaround is presented here.
Another showstopper may be that very bright RGB light bleeds to the sides (from the so-called south-facing LEDs). This makes the RGB lighting almost useless: In order to see the legends on the keys (e.g., in darkness or in a low-light conditions), the brightness must be fairly high. But at the normal viewing angle, this bleeds so much light to the side (towards your eyes) that it blinds you. The only way to use it is to lower the brightness, so that the legends are very subtly visible, with the stray light not blinding too much. Or perhaps to make a modification to the keyboard to stop the stray light (this hasn’t been tried yet).
Introduction
The Keychron keyboards (Q and V series only, not the more common K series) are the only QMK-capable commercial keyboards which are widely distributed, that is, are possible to buy locally. There are a lot of specialised QMK keyboards (but getting them involves more hassle, higher cost, long waiting times, and credit card risks), and/or they are crippled by not being full-size keyboards.
QMK enables full programmability, incl. macros, keymapping, any keyboard layout you can imagine or dream up (e.g., Colemak), and full control of the RGB lighting. This can be done by raw C coding or by a number of solutions that hides/abstract it (at the cost of sacrificing some of the flexibility). For instance, there are web sites where you can design the keymap and get a firmware file as the result, without touching a single line of code (but the macro capability is completely absent). The only remaining step is then to get the firmware onto the keyboard. There are tools to hide that process as well, though it is as simple as a single command line to flash the firmware (e.g., using AVRDUDE (is installed with the Arduino IDE) for AVR-based keyboards or dfu-util for keyboards with ARM (like the V5 described here)).
The Keychron V5 is much more reasonably priced, and the assembled version is the way to go. Doing this piecemeal by getting an overpriced Q-series PCB-only keyboard and sourcing the switches and keycaps on your own is both expensive and troublesome. The selection of switches may or may not be limited anyway (only available from Keychron?).
Like most of the Keychron keyboards, the switches are hot-swappable.
Macros
Macros are not really a part of QMK. It is more like a convention enabled by the ability to override (in function process_record_user()) the processing of key presses and key releases. That is, there isn’t any explicit support for macros in QMK (except for some predefined C macros to make it a little bit easier).
Mouse actions, e.g. right click
The action part of a QMK macro to open the link under the mouse cursor in a new tab in Firefox (right-click and select “Open Link in New Tab” by pressing “T”):
SEND_STRING(SS_TAP(X_MS_BTN2)); SEND_STRING(SS_DELAY(400)); // Wait... This is crucial // for this to work. SEND_STRING(SS_TAP(X_T));
Using Via to prototype macros
Via enables a very quick turn-around for developing macros: Macros can be recorded, the timings between key presses and key releases changed, and they are applied immediately (if a keymapping has been created). But it can not be used for any serious use of macros, only for prototyping.
Drawbacks:
- Mouse actions (e.g., right-click) in macros are not supported. Only single mouse actions in keymappings are supported (e.g., a single right-click)
- Definitions must be restored after every flash (e.g., from stored JSON files with the Via definitions). They are stored in (emulated) EEPROM and thus often wiped out.
- There is a maximum of 16 macros (M0 – M15, both inclusive). It is possible to increase, though. This is not mentioned anywhere, let alone documented. For example, to increase the number of macros from 16 to 42, add a line with “#define DYNAMIC_KEYMAP_MACRO_COUNT 42” in a config.h file, e.g. to keychron/v6/iso_encoder/config.h
- By default, there is very little memory for macros (as the default configuration is emulating traditional EEPROM memory with only 1 or 2 KB of memory). There is only space for about 150 key actions in total (both key presses, key releases, and modifier keys (both key presses and key releases) count). Though it can be changed to be essentially unlimited.
- The macros don’t have names, only numbers (“M0”, “M1”, … “M15”). And there isn’t any way to annotate them, e.g., to document their purpose. This must be done by some external means (e.g., in some (text) document)
- On some Keychron keyboards with wireless support (e.g., K10 Pro. Bluetooth), the Via macros are completely broken when the keyboard is used in wireless mode.
Note: Via runs just fine standalone. It does not require a web browser (in particular, Google Chrome)
Note: The content of an existing macro is wiped out without warning if “RECORD KEYSTROKES” is pressed (it doesn’t append the new recording (or respect the user’s time defining the original macros)). But it is possible to append (or prepend) a new recording by this technique:
- First save off the source for the macro: Click on the “</>” icon and copy/paste the content.
- Go back to the original view by clicking on the icon to the left.
- Record. Stop recording. Save changes.
- Click on the “</>” icon and paste the saved content from step 1, e.g., prepending or appending. Press Save.
- Go back to the original view by clicking on the icon to the left.
Use Vial to upgrade from Via’s deficiencies
Vial repairs on most of the serious Via drawbacks: Mouse actions are supported in Vial macros, and it is possible to increase the number of macros from 16 (e.g., to 40 by adding “#define DYNAMIC_KEYMAP_MACRO_COUNT 40” in config.h).
Though Vial also comes with increased complexity, for example, requirement for special versions of the firmware that is not the official QMK firmware. And the build steps are different from QMK’s.
As for Via, it is also possible to increase the total number key actions for Vial macros (e.g., 6000 bytes (about 650 key actions) by adding “#define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE 6000” in config.h)
Crippled by not being a full-size keyboard
I would recommend getting the full-size keyboard Keychron V6 instead, but availability may be a problem (e.g., a long wait time). This is a general statement about 96% (and less) keyboards, not just this one. The small-form-factor cult never mentions the compromises and drawbacks.
The numbering scheme for the Keychron V series is confusing, but here is an overview (see also the content of the dropdown “Custom Keyboards” (third item) on the top of this page (click to expand). Or the feature matrix):
- V4: 60% Has two Fn keys, Fn and Fn1.
- V2: 65%. Has two Fn keys, Fn1 and Fn2.
- V8: 65% (Alice Layout, a la Microsoft Natural Keyboard). Has two Fn keys, Fn1 and Fn2.
- V7: 70%. Has two Fn keys, Fn1 and Fn2.
- V1: 75%
- V10: 75% (Alice Layout) with five dedicated macro keys on the left
- V3: 80% (TKL (tenkeyless))
- V5: 96% (“1800”). Covered in this blog post. Includes a knob.
- V6: 104%. 108 keys (4 extra keys above the numeric keypad). Includes a knob.
There isn’t any less confusion by the numbering scheme being completely different for the K Pro series (all wireless (Bluetooth) and with QMK capability, unlike the original K series):
- K12 Pro: 60%
- K9 Pro: 60% (slim/low profile).
- K6 Pro: 65%
- K7 Pro: 65% (slim/low profile)
- K11 Pro: 65% (Alice Layout, a la Microsoft Natural Keyboard. Slim/low profile)
- K14 Pro: 70%
- K2 Pro: 75%
- K3 Pro: 75% (slim/low profile)
- K15 Pro: 75% (Alice Layout. And with five macro keys on the left, M1-M5. And with a knob)
- K8 Pro: 80% (TKL (tenkeyless))
- K1 Pro: 80% (TKL (tenkeyless). Slim/low profile)
- K13 Pro: 85%??? (“numpad TKL”. Slim/low profile)
- K4 Pro: 96% (“1800”)
- K17 Pro: 96% (“1800”). (Slim/low profile)
- K10 Pro: 104%. 108 keys (4 extra keys above the numeric keypad). Does not include a knob.
- K5 Pro: 104% (slim/low profile). 108 keys (4 extra keys above the numeric keypad). Does not include a knob.
The numbering scheme for the original “Q” series (not to be confused with the later “Q Pro” series (wireless and with a knob)) seems to follow the “V” series:
- Q5: 96% (“1800”). Does not include a knob.
- Q6: 104%. 108 keys (4 extra keys above the numeric keypad). Does not include a knob.
Similar for the the later “Q Pro” series (wireless and with a knob)):
- Q5 Pro: 98%. 102 keys. Includes a knob.
- Q6 Pro: 104%. 108 keys (4 extra keys above the numeric keypad). Includes a knob.
But there is some order in the numbering madness: For the K series and K Pro series, the odd numbered models are low profile / slim (e.g., K5 Pro), whereas the even numbered models are normal profile (e.g., K10 Pro).
But at least the Keychron V5, being fully programmable, enables providing workarounds.
Missing PgUp/PgDn keys
PgUp and PgDn are very commonly used and must be available as dedicated keys. Having to use a modifier key is not acceptable.
I already had most keys on the numeric keypad part used for macro keys, but as a workaround/compromise, I used these:
- Numeric keypad ‘3’: PgUp
- Numeric keypad ‘.’: PgDn
This was first prototyped by key assignments in Via and then later put into QMK proper by changing the keymap.
A further compromise is moving the lesser-used macros to the Fn layer. But it is not ideal. The whole point of macros is to save unnecessary keypresses, in particular modifier keys for the shorter key sequences.
Missing context menu key
To the right of the space bar, there is the extra Fn key, but as there are only three keys, the context menu key is missing. This is also heavily used. Other keyboards with an Fn key has four keys and the right Windows key can be used as the context menu key instead.
As a compromise, I repurposed the Num Lock key on the numeric keypad as the context menu key. I don’t use the numbers on the numeric keypad (I repurpose it as a macro pad), but a workaround for the now missing Num Lock is to use the Num Lock key on some other keyboard, e.g. a cheap wireless separate numeric keypad. Or an old (rubber dome) keyboard. For the former, it can be used as dedicated numeric keypad (though the keys may not be that great or the ones with mechanical switches are extremely expensive).
Blues setting up the default RGB lighting configuration in QMK
The factory RGB lighting defaults are very irritating: An animation. Like all other keyboards, the factory default RGB lighting settings ought to be a static / steady lighting mode with some acceptable colour, like green, blue, or white.
Manually changing the RGB lighting settings
Setting mode, colour, and brightness to get a steady green of not too high brightness:
- 18 times Fn + Q to get to a static mode (it is 10 times in the original version of the firmware). There are 23 lighting modes (the official version 1.1 (2023-05) of the firmware) in total (13 in the original version of the firmware). See Appendix C for details.
- 10 times Fn + E (hue) for a green colour. The saturation can be changed with Fn + R / F (lower value is towards white).
- Change brightness by Fn + knob (or Fn + W/S)
Changing the default settings in QMK
Changing the QMK firmware to use the proper RGB lighting settings is the only long-term solution. Having to set them every time the firmware is updated, is too cumbersome.
However, this does not work by following the official documentation (overriding eeconfig_init_kb() and making the appropriate calls to change the (persistent) settings). It seems enabling Via (at compile time) interferes: Any (or most) changes to RGB settings seems to be overwritten. That is, using eeconfig_init_kb() does not have any effect (but it is actually called (see appendix B)).
The fix
It is probably due to some bug in QMK (when Via support is enabled), but I found a workaround that works: Defer changing the RGB settings to function keyboard_post_init_user(). This function is called once per powerup, but use a custom (persistent) setting to set a flag in function eeconfig_init_kb() (so changing the RGB settings is only executed right after flashing, at the first powerup). Using this fix, these four calls enables the default settings of RGB lighting to be with a dim steady green colour:
rgblight_mode(0); // <https://docs.qmk.fm/#/feature_rgb_matrix?id=rgb-matrix-effects> rgblight_sethsv_noeeprom(85, 255, 60); // Enable RGB lighting by default rgblight_toggle(); rgb_matrix_toggle();
This is described in detail in Appendix B, incl. some techniques for debugging at startup time (where it seems the output of the printf function is not possible to capture).
Cancelling macros in progress
QMK, and thus this keyboard, does not come with a mechanism to cancel macros in progress, but with a sufficient amount of programming, it is possible. Though only for custom macros; it is probably practically infeasible for Via macros.
Appendix A: Detailed information about the Keychron V5 keyboard
Documentation
- Manual (PDF. 17 MB)
- List of user guides
- Product page
Switches
Keychron K Pro, for example, brown. Pre-lubed. Hot-swappable. MX stem compatible.
The PCB accepts 5-pin Cherry MX switches: “The Cherry MX switches are fully compatible with our Keychron keyboard mechanical (hot-swappable) versions”
Disclaimer: The information about compatible switches has not been confirmed. Buy at your own risk!
Some compatible switches: Gateron G Pro 2.0 (lubed), Gateron Phantom (not lubed), and Gateron Ink V2. For example, Gateron G Pro 2.0 Black (linear. 60 g), Gateron G Pro 2.0 Yellow (linear. 60 g), and Gateron Phantom Yellow (linear. 50 g).
May or may not be somewhat compatible (the RBG light may not be compatible): Cherry MX Silver (linear. 45 g).
Note that the LEDs are mounted on the PCB and are south-facing.
Keycaps
Material: Unknown. The product page says ABS and some resellers claim it is PBT.
Other features
Has a volume knob. Holding the Fn key, while using it, changes the brightness of the RGB light. It can be repurposed for other things, using QMK.
USB
Vendor ID: 0x3434 (hexadecimal)
Product ID: 0x0353 (hexadecimal)
Firmware
Official firmware (despite the misleading title. See near “Download the V5 firmware”). The latest is firmware version 1.1 (2023-05-01).
Source code (qmk_firmware/keyboards/keychron/v5). In the official QMK repository, and in that repository, in Git branch “master” (the default).
Microcontroller
STM32L432 (source (near “Cortex”)). Datasheet.
128 KB flash memory. 64 KB RAM.
There isn’t any EEPROM memory (for storing persistent settings, like the Via configuration, incl. the macro definitions) on chip. It may or may not use a serial external EEPROM chip (using I²C to communicate), but QMK probably emulates EEPROM in flash memory.
Appendix B: Debugging the RGB lighting settings blues, likely caused by Via
Main debugging technique: As print debugging doesn’t appear to be working at startup time (at least not without having physical access to the microcontroller’s serial port I/O pins), this can be used instead:
A (calibrated) blocking busy wait (three nested for loops, each with less than a 65535 loop count) is used to get out the required information. We use the fact that the RGB lights come on after the startup has completed. If RGB lights are not on (but they are with the default firmware), we can instead tap a key very fast and time when it starts registering (presumably at the end of the startup period).
Or in other words, we insert delays of known length into functions to deduce whether they are actually called or not (e.g., depending on whether it is the very first powerup after flashing or subsequent powerups). The two functions eeconfig_init_kb() and keyboard_post_init_user are call-back functions (called by QMK) that we don’t have control over. eeconfig_init_kb() is supposed to be called only once, right after flashing and keyboard_post_init_user is supposed to be called for every powerup (both right after flashing and subsequent powerups).
For instance, if we insert a delay of 31 seconds in eeconfig_init_kb() and 7 seconds in keyboard_post_init_user, we expect the first startup to last 31 + 7 = 38 seconds and subsequent startups 7 seconds.
This can also be used to verify that eeconfig_init_kb() is only called once after flashing; in all subsequent powerups, QMK is only supposed to call keyboard_post_init_user(), not eeconfig_init_kb().
Strangeness observed: eeconfig_init_kb() seems to be called two times, based on an observed startup time after flashing of 31 + 31 + 7 = 69 seconds instead of the expected 38 seconds (depending on the calls it contained)! This behaviour may or may not also depend on whether Via is enabled at compile time.
Appendix C: List of lighting modes
Note: There are 23 RGB lighting modes in the newer versions of the firmware. The firmware in the purchased unit may only have 13 lighting modes (10 less), because it uses an older version of the firmware or is configured differently at compile time. This is only the default set; there are currently 51 different ones to choose from.
For normal use of the keyboard (past the demo phase), only RGB lighting mode “Solid colour” is needed.
- None
- Solid colour
- Breathing
- Band spiral (is rotating)
- Cycle all
- Cycle left right
- Cycle up down
- Rainbow moving
- Cycle out in
- Cycle out dual
- Cycle pinwheel (is rotating)
- Cycle spiral (is rotating)
- Cycle beacon
- Rainbow beacon (is rotating)
- Jellybean raindrops
- Pixel rain
- Typing heatmap
- Digital rain
- Reactive simple (is reactive)
- Reactive multiwide (is reactive)
- Reactive multi Nexus (is reactive)
- Splash (is reactive)
- Solid splash (is reactive)
Here is a demo of all the 44 different RGB lighting modes (at that time): 1. “Solid Colour”, 2. “Alpha+Mods”, 3. “Gradient (Up/Down)”, 4. “Gradient (Left/Right)”, 5. “Breathing”, 6. “Band (Saturation)”, 7. “Band (Value/Brightness)”, 8. “Band Pinwheel (Saturation)”, 9. “Band Pinwheel (Value/Brightness)”, 10. “Band Spiral (Saturation)”, 11. “Band Spiral (Value/Brightness)”, 12. “Cycle All”, 13. “Cycle Left/Right”, 14. “Cycle Up/Down”, 15. “Rainbow Moving Chevron”, 16. “Cycle Out/In”, 17. “Cycle Out/In Dual”, 18. “Cycle Pinwheel”, 19. “Cycle Spiral”, 20. “Dual Beacon”, 21. “Rainbow Beacon”, 22. “Rainbow Pinwheels”, 23. “Raindrops”, 24. “Jellybean Raindrops”, 25. “Hue Breathing”, 26. “Hue Pendulum”, 27. “Hue Wave”, 28. “Pixel Rain”, 29. “Pixel Fractal”, 30. “Solid Reactive (Simple)”, 31. “Solid Reactive”, 32. “Solid Reactive Wide”, 33. “Solid Reactive Multiwide” (04 min 19 secs), 34. “Solid Reactive Cross”, 35. “Solid Reactive Multicross”, 36. “Solid Reactive Nexus” (04 min 45 secs), 37. “Splash”, 38. “Multisplash”, 39. “Solid Splash”, 40. “Solid Multisplash”, 41. “Solid Colour”, 42. “Alpha+Mods”, 43. “Gradient (Up/Down)”, and 44. “Gradient (Left/Right).
The first reactive mode is “Solid Reactive (Simple)”, at 03 min 48 secs.
There are timestamps for all the modes in the video’s description.
Note: “Cycle beacon” is not in the demo. Or it may be a synonym (or have been renamed).