{"id":4536,"date":"2023-10-02T15:20:13","date_gmt":"2023-10-02T14:20:13","guid":{"rendered":"https:\/\/pmortensen.eu\/world2\/?p=4536"},"modified":"2026-08-06T11:05:48","modified_gmt":"2026-08-06T10:05:48","slug":"setting-rgb-colour-for-individual-keys-in-qmk","status":"publish","type":"post","link":"https:\/\/pmortensen.eu\/world2\/2023\/10\/02\/setting-rgb-colour-for-individual-keys-in-qmk\/","title":{"rendered":"Setting RGB colour for individual keys in QMK (per-key RGB colour)"},"content":{"rendered":"<p>The short version: in function <a href=\"https:\/\/docs.qmk.fm\/features\/rgb_matrix#api-rgb-matrix-indicators-kb\"><em>rgb_matrix_indicators_kb()<\/em><\/a> in file <em>keymap.c<\/em>, use function <em><a href=\"https:\/\/github.com\/qmk\/qmk_firmware\/blob\/master\/docs\/features\/rgb_matrix.md#void-rgb_matrix_set_coloruint8_t-index-uint8_t-r-uint8_t-g-uint8_t-b-api-rgb-matrix-set-color\">rgb_matrix_set_color()<\/a><\/em>. For example, to set a blue colour on key <a href=\"https:\/\/en.wikipedia.org\/wiki\/Function_key#History\">F7<\/a> on a <a href=\"https:\/\/pmortensen.eu\/world2\/2023\/06\/19\/keychron-v5-a-reasonably-priced-fully-macro-capable-qmk-based-mechanical-keyboard\/\">Keychron V5<\/a>:<\/p>\n<pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">\r\n    rgb_matrix_set_color(7, 31, 13, 200);\r\n<\/pre>\n<p>That is for a V series Keychron keyboard (and presumably for all keyboards in the main QMK repository that are physically capable of it). <\/p>\n<p>It is more complicated for some later Keychron models, e.g., the <a href=\"https:\/\/www.keychron.uk\/products\/keychron-k10-pro-qmk-via-wireless-mechanical-keyboard-iso-layout-collection\">K Pro series<\/a>, where <em>rgb_matrix_indicators_user()<\/em> is hijacked in <a href=\"https:\/\/github.com\/Keychron\/qmk_firmware\/blob\/wireless_playground\/keyboards\/keychron\/common\/wireless\/indicator.c#L136\">common\/wireless\/indicator.c<\/a> in function led_matrix_indicators_bt(). Note that the hijacking depends on the version of the source code and does not appear to be present in later versions. One solution is to use a different name, for example, <em>rgb_matrix_indicators_user2()<\/em> and call <em>rgb_matrix_indicators_user2()<\/em> in the beginning of function <em>rgb_matrix_indicators_user()<\/em> in file &#8216;common\/wireless\/indicator.c&#8217;.<\/p>\n<h2>Introduction<\/h2>\n<p>It isn&#8217;t well advertised in the QMK documentation or any examples you may find elsewhere (there is too much emphasis on animations, which are really only for demos and are completely useless for any real work), but it is entirely possible to set the colour <strong><em>individually<\/em><\/strong> for each key, not just the same colour for all keys (if the keyboard is physically capable of doing it and the hardware for doing so is supported in QMK). And for the commercial QMK keyboards and for the keyboards where the animations already work, everything has already been set up.<\/p>\n<h2 id=\"Confusing_QMK_terminology\">Confusing QMK terminology<\/h2>\n<p><a href=\"https:\/\/github.com\/qmk\/qmk_firmware\/blob\/master\/docs\/features\/rgblight.md\">RGB lighting<\/a>: This has <strong><em>nothing<\/em><\/strong> to do with the LEDs on each individual key&#8230; The magic word for that is &#8220;matrix&#8221; and the combination &#8220;<a href=\"https:\/\/github.com\/qmk\/qmk_firmware\/blob\/master\/docs\/features\/rgb_matrix.md\">RGB matrix<\/a>&#8221; lighting. &#8220;RGB lighting&#8221; and &#8220;RGB matrix&#8221; are two completely different things. And there are two more: &#8220;<a href=\"https:\/\/github.com\/qmk\/qmk_firmware\/blob\/master\/docs\/features\/led_matrix.md\">LED matrix lighting<\/a>&#8221; and <a href=\"https:\/\/github.com\/qmk\/qmk_firmware\/blob\/master\/docs\/features\/backlight.md\">back lighting<\/a> (the latter using PWM capable I\/O pins on the microcontroller to control the brightness)<\/p>\n<h2>Unnecessary or even detrimental: BACKLIGHT_ENABLE and RGBLIGHT_ENABLE<\/h2>\n<p>As for compile-time configuration, <strong><em>only<\/em><\/strong> RGB_MATRIX_ENABLE is required and it is <strong><em>already set up<\/em><\/strong> if the RGB animations work. Thus it isn&#8217;t required to change any compile-time setting if RGB animations work. For instance, that is the case for the default Keychron V5 QMK part.<\/p>\n<p>For instance, for Keychron V5, the (hardware) definitions are already set up in <a href=\"https:\/\/github.com\/qmk\/qmk_firmware\/blob\/master\/keyboards\/keychron\/v5\/iso_encoder\/iso_encoder.c\">qmk_firmware\/keyboards\/keychron\/v5\/iso_encoder\/iso_encoder.c<\/a>. And it is also enabled by default in <a href=\"https:\/\/github.com\/qmk\/qmk_firmware\/blob\/master\/keyboards\/keychron\/v5\/iso_encoder\/rules.mk\">rules.mk<\/a>:<\/p>\n<pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">\r\nRGB_MATRIX_ENABLE = yes\r\n<\/pre>\n<p>Note that BACKLIGHT_ENABLE and RGBLIGHT_ENABLE should stay as they are for this purpose (<strong><em>= no<\/em><\/strong>):<\/p>\n<pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">\r\nBACKLIGHT_ENABLE = no  # Enable keyboard backlight functionality\r\nRGBLIGHT_ENABLE = no   # Enable keyboard RGB underglow\r\n<\/pre>\n<p>Despite similar sounding &#8220;RGB&#8221;, &#8220;light&#8221;, and &#8220;backlight&#8221; they have <strong><em>nothing<\/em><\/strong> to do with setting RGB colour for individual keys; the LEDs in that case are <strong><em>some other LEDs<\/em><\/strong>, separated from the individual LEDs for keys\/switches. The confusion comes from <a href=\"https:\/\/pmortensen.eu\/world2\/2023\/10\/02\/setting-rgb-colour-for-individual-keys-in-qmk\/#Confusing_QMK_terminology\">the weird QMK lingo<\/a>.<\/p>\n<p><!--\nXXX and XXX in qmk_firmware\/keyboards\/keychron\/v5\/iso_encoder\/rules.mk:\n\nNote that it is <strong><em>not<\/em><\/strong> necessary:\n\nDespite XXX, they have nothing to do with setting RGB colour for individual keys.\n--><\/p>\n<h2>Ill-defined key numbers<\/h2>\n<p>It isn&#8217;t clear if the key numbering for RGB includes the rotary knob (if any) or not.<\/p>\n<p>For the V5, the knob <strong><em>is<\/em><\/strong> counted. Thus, these keynumbers are valid (V5 ISO knob variant):<\/p>\n<pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">\r\nenum kNumberCodes\r\n{\r\n    k_Esc = 0,\r\n    k_F1 = 1,\r\n    k_F2 = 2,\r\n    k_F3 = 3,\r\n    k_F4 = 4,\r\n    k_F5 = 5,\r\n    k_F6 = 6,\r\n    k_F7 = 7,\r\n    k_F8 = 8,\r\n    k_F9 = 9,\r\n    k_F10 = 10,\r\n    k_F11 = 11,\r\n    k_F12 = 12,\r\n    k_Del = 13,\r\n    k_Home = 14,\r\n    k_End = 15,\r\n    k_KNOB = 16,\r\n    k_Para = 17,\r\n    k_1 = 18,\r\n    k_2 = 19,\r\n    k_3 = 20,\r\n    k_4 = 21,\r\n    k_5 = 22,\r\n    k_6 = 23,\r\n    k_7 = 24,\r\n    k_8 = 25,\r\n    k_9 = 26,\r\n    k_0 = 27,\r\n    k_plus = 28,\r\n    k_accent = 29,\r\n    k_Backsp = 30,\r\n    k_Num = 31,\r\n    k_slash_KP = 32,\r\n    k_aster_KP = 33,\r\n    k_minus_KP = 34,\r\n    k_Tab = 35,\r\n    k_Q = 36,\r\n    k_W = 37,\r\n    k_E = 38,\r\n    k_R = 39,\r\n    k_T = 40,\r\n    k_Y = 41,\r\n    k_U = 42,\r\n    k_I = 43,\r\n    k_O = 44,\r\n    k_P = 45,\r\n    k_AA = 46,\r\n    k_hat = 47,\r\n    k_7_KP = 48,\r\n    k_8_KP = 49,\r\n    k_9_KP = 50,\r\n    k_CapLck = 51,\r\n    k_A = 52,\r\n    k_S = 53,\r\n    k_D = 54,\r\n    k_F = 55,\r\n    k_G = 56,\r\n    k_H = 57,\r\n    k_J = 58,\r\n    k_K = 59,\r\n    k_L = 60,\r\n    k_AE = 61,\r\n    k_OE = 62,\r\n    k_snglQuote = 63,\r\n    k_Return = 64,\r\n    k_4_KP = 65,\r\n    k_5_KP = 66,\r\n    k_6_KP = 67,\r\n    k_plus_KP = 68,\r\n    k_ShiftL = 69,\r\n    k_diamond = 70,\r\n    k_Z = 71,\r\n    k_X = 72,\r\n    k_C = 73,\r\n    k_V = 74,\r\n    k_B = 75,\r\n    k_N = 76,\r\n    k_M = 77,\r\n    k_comma = 78,\r\n    k_fullStop = 79,\r\n    k_minus = 80,\r\n    k_ShiftR = 81,\r\n    k_Up = 82,\r\n    k_1_KP = 83,\r\n    k_2_KP = 84,\r\n    k_3_KP = 85,\r\n    k_CtrlL = 86,\r\n    k_Win = 87,\r\n    k_Alt = 88,\r\n    k_Space = 89,\r\n    k_AltGr = 90,\r\n    k_Fn = 91,\r\n    k_CtrlR = 92,\r\n    k_Left = 93,\r\n    k_Down = 94,\r\n    k_Right = 95,\r\n    k_0_KP = 96,\r\n    k_fStop_KP = 97,\r\n    k_Enter = 98,\r\n;\r\n<\/pre>\n<h2>References<\/h2>\n<ul>\n<li><em><a href=\"https:\/\/coreybraun.com\/posts\/qmk-keyboard-firmware\/\">Writing custom keyboard firmware with QMK<\/a><\/em> A blog post that includes an example of setting up per-key RGB. It also explains it in greater details than here, including setting up QMK (on Windows). It also demonstrates using a list of keynumbers (and a loop), instead of a series of calls to rgb_matrix_set_color() (to reduce redundancy and probably also reduce the code size).<\/li>\n<li><a href=\"https:\/\/github.com\/Shandower81\/CORY-FRAMEWORK-RGB-KEYBOARD\">Cory framework RGB keyboard<\/a>. An example of layer-dependent per-key RGB light, with lots of pictures (for example, referenced <a href=\"https:\/\/community.frame.work\/t\/how-to-get-to-point-you-can-have-per-key-rgb-control-for-keyboard-and-macropad\/47080\/27\">here<\/a>)<\/li>\n<\/ul>\n<p><!-- T H E   E N D . . .   Marker for editing in WordPress: pppp --><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The short version: in function rgb_matrix_indicators_kb() in file keymap.c, use function rgb_matrix_set_color(). For example, to set a blue colour on key F7 on a Keychron V5: That is for a V series Keychron keyboard (and presumably for all keyboards in &hellip;<\/p>\n<p class=\"read-more\"> <a class=\"more-link\" href=\"https:\/\/pmortensen.eu\/world2\/2023\/10\/02\/setting-rgb-colour-for-individual-keys-in-qmk\/\"> <span class=\"screen-reader-text\">Setting RGB colour for individual keys in QMK (per-key RGB colour)<\/span> Read More &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,28,26,35,16],"tags":[],"_links":{"self":[{"href":"https:\/\/pmortensen.eu\/world2\/wp-json\/wp\/v2\/posts\/4536"}],"collection":[{"href":"https:\/\/pmortensen.eu\/world2\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pmortensen.eu\/world2\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pmortensen.eu\/world2\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pmortensen.eu\/world2\/wp-json\/wp\/v2\/comments?post=4536"}],"version-history":[{"count":63,"href":"https:\/\/pmortensen.eu\/world2\/wp-json\/wp\/v2\/posts\/4536\/revisions"}],"predecessor-version":[{"id":6805,"href":"https:\/\/pmortensen.eu\/world2\/wp-json\/wp\/v2\/posts\/4536\/revisions\/6805"}],"wp:attachment":[{"href":"https:\/\/pmortensen.eu\/world2\/wp-json\/wp\/v2\/media?parent=4536"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pmortensen.eu\/world2\/wp-json\/wp\/v2\/categories?post=4536"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pmortensen.eu\/world2\/wp-json\/wp\/v2\/tags?post=4536"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}