Skip to content

Light Math

LastContinue edited this page Jul 20, 2020 · 5 revisions

All of the "Light Math" here is based on my "ancient" QMK fork. Current QMK uses something completely different that I haven't set aside the time to try to figure out (mostly because my old stuff still works). If you want contribute to QMK, then you'll need to figure something else out, but if you're okay with old code, then the below will still work for you 😄

So you want to be able to do key-by-key light settings like in the GUI configurator, but in QMK?

Basic Overview


Gather Files

Get (either pull down from Git or download). This is my own version of an older MD fork that had key-by-key lighting, however, that branch is now so behind QMK that I was getting compiler errors when using a newer version of the compiler tool-chain in MacOS so I just built my own and made it so that the files for doing key-by-key live at a keymap level.

Inspect sample keymap code

Inside of that code you just pulled or downloaded, under qmk_firmware/keyboards/massdrop/ctrl/keymaps you'll see a dir called lastcontinue. This is the config I use on a daily basis and you can use this for inspiration. Of course I have lots of stuff I like and you probably don't so the bare minimum you need to get this to work in a map of your own is having

#include "lc_led_matrix.h"
#include "lc_led_matrix.c" 
led_instruction_t led_instructions[] = { ... whatever you want };

At the bottom of the page you'll see an array called led_instructions. This is where the "magic" happens.

Notice that in each one of those .flags there are some numbers like id0, id1, etc.

What are those?

Those are the keys you're selecting for the current color or effect.

Keys? There are only two or three keys listed?

It uses a technique called "bitwise" to make a number that represents several other numbers. Think of it like a hash.

Why are there id0, id1, id2, id3? Why not just one big number to represent all of them?

The CTRL board uses a 32 bit processor, so breaking numbers down into multiples of 32 is something it likes. 120/32 = 3.75 so round that up to 4 so that maps to id0-id3.

Lets take a look at the map: keyboard map Notice those colors correspond to the idX. Green is id0, aqua is id1, orange is id2, and purple is id3.

Yeah that's great, but how do I actually use that information?

You're ready for the next step:

Use python scripts to generate numbers

Use either

and follow the examples adding less or more arrays to the dict based on what you want to do with the board. The numbers in those arrays correspond directly with numbers on the map. You don't actually need to know python to get these to work as it's mostly just copy-paste where you want the numbers.

Let's say we want all the top keys to be one color, and the backlight to be another. We could do something like

 keys = range(1,87)
 back_light = range(88,120)

 all_keys = {"keys":keys, "back_light":back_light}

and that should return

keys .id0 = 4294967295, .id1 = 4294967295, .id2 = 4194303, .id3 = 0,
back_light .id0 = 0, .id1 = 0, .id2 = 4286578688, .id3 = 8388607,

(You can just remove the ones that are set to = 0)

Lets copy those numbers down and lets move the next step

Add numbers to keymap.c

Go back into the keymap.c from before and scroll down the the led_instructions section. There should be plenty of examples to give you inspiration.

Lets say we wanted to take the numbers from the last step and make the keys red and the backlight rainbow. You'd do

led_instruction_t led_instructions[] = {    
    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 4294967295, .id1 = 4294967295, .id2 = 4194303, .r = 255, .g = 0, .b = 0 },
    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_PATTERN, .id0 = 0, .id1 = 0, .id2 = 4286578688, .id3 = 8388607, .pattern_id = 3 } 
    { .end = 1 }

the last {.end = 1} is super important so don't forget this

Lets break this down

  • LED_FLAG_MATCH_ID says "I want to use numbers to match this". This is a given, but sometimes you gotta be verbose.
  • LED_FLAG_USE_RGB this is just saying "I want to match a color I will define"
  • LED_FLAG_USE_PATTERN this is saying "I want to use a pattern from led_programs.c" this index is based on how you've ordered your patterns in led_programs.c. In the lastcontinue map that file is on the same level.

Of course there is more you can do, but there should be enough examples you should be able to figure out what you want to do.

Compile the map you just built and enjoy!

See another FAQ about limitations, but I feel for most usages,this will get a nice result.