Ergodox: Make LEDs indicate the layer you are on

This article assumes that you are working with the source code downloaded from MassDrop.

Open the file lib /key-functions/public/basic.c and add the following line below after all the #define statements.

extern uint8_t keyboard_leds;

Then go to the push function of the layer you want the LEDs to light up on. Let’s assume we want to turn on NumLock LED when layer 2 is active. In kbfun_layer_push_2 function, we add the following line:

keyboard_leds = 0x01;

So the function will look like this:

/*
 * [name]
 *   Layer push #2
 *
 * [description]
 *   Push a layer element containing the layer value specified in the keymap to
 *   the top of the stack, and record the id of that layer element
 */
void kbfun_layer_push_2(void) {
	keyboard_leds = keyboard_leds | 0x01;
	layer_push(2);
}

/*
 * [name]
 *   Layer pop #2
 *
 * [description]
 *   Pop the layer element created by the corresponding "layer push" function
 *   out of the layer stack (no matter where it is in the stack, without
 *   touching any other elements)
 */
void kbfun_layer_pop_2(void) {
	keyboard_leds = keyboard_leds & ~(uint8_t)0x01;
	layer_pop(2);
}

You will notice that there is a keyboard_leds = keyboard_leds & 0x01 in the pop function for layer 2. This will turn the LED off when we exit the layer. For CapsLock LED set keyboard_leds to 0x02 and set it to 0x04 for scroll lock.

What if you want to turn on multiple LEDs when you are on a specific layer? If you want the NumLock and Scroll Lock LED to turn on when you are on layer 2, you would write the following:

keyboard_leds = keyboard_leds | 0x01 | 0x02; 

//To turn them off
keyboard_leds = keyboard_leds & ~(uint8_t)0x01 & ~(uint8_t)0x02;

Posted

in

by

Tags:

Comments

5 responses to “Ergodox: Make LEDs indicate the layer you are on”

  1. anro Avatar
    anro

    There’s a slight bug here.
    To turn off a LED you should use:
    keyboard_leds &= (uint8_t) ~(0x01);

    This works because it makes a mask of 1s of all bits *except* the bit representing the LED you want to turn off, thereby leaving other LEDs in whatever state they were in previously.

    Your example above actually does the opposite of what you want:
    keyboard_leds &= (0x01)
    will turn off all LEDs except that one when you exit the layer. This is because the mask has all zeroes except for the selected LED and the AND operation will only preserve the LED that you want, in this case, to turn off.

    Your use of binary OR is the correct way to turn on a LED when entering a layer without affecting the status of other LEDs.

    I found this post quite helpful in my own hacking on my ergodox. Thanks!

  2. Moazzam Avatar

    Thanks for pointing that out anro. I will confirm it and change my post accordingly. And, I am very glad you found it helpful.

  3. Duq Avatar
    Duq

    Hello!

    Upon constructing my ergodox and using it for a bit I found that it would be useful to have a layer indicator because how I appropriated my layers.

    https://www.massdrop.com/ext/ergodox/?referer=ZXKRQ7&hash=b209b02042f5ab4d3b372634dcbdd187

    I play random for SC2 and there were some keys that were particularly terrible to get to because of the split configuration. I haven’t hashed through everything yet, but the main ones were these:

    zerg: ‘h’ for hatcheries
    protoss: ‘y’ for cybernetics core
    terran: ‘u’ for bunker and ‘l’ for lift

    I still have more discovery to do, but it already made it apparent that I would have to do this if I were to make a right attempt at making the ergodox work on the regular.

    Anyway, I have a layer for each race[layer 1, layer 2, layer 3] and brought over the offending keys to the 1.5 unit keys on the left hand.

    Now, the meat of this post… how to enable the LED indicators existing(LEDa, LEDb, and LEDc) to indicate what layer you are on.

    I used your code to base how I did it:
    http://moazzam-khan.com/blog/?p=885

    It did not work for me… It did turn the LEDs on for me but it would not turn them off…

    Your current construct for turning off the LEDs is(placed in the ‘pop’ function of the desired layer):
    keyboard_leds = keyboard_leds & 0x01;

    The following does not work either:
    keyboard_leds = keyboard_leds & 0x01;

    There is comment to use:
    keyboard_leds &= (uint8_t) ~(0×01); or keyboard_leds &= (0×01)

    Does not work either.

    What I found that works is this line:
    keyboard_leds = 0x00;

    The final source should look similar to this:
    Code: [Select]
    void kbfun_layer_push_1(void) {
    keyboard_leds = keyboard_leds | 0x01;
    layer_push(1);
    }

    /*
    * [name]
    * Layer pop #1
    *
    * [description]
    * Pop the layer element created by the corresponding “layer push” function
    * out of the layer stack (no matter where it is in the stack, without
    * touching any other elements)
    */
    void kbfun_layer_pop_1(void) {
    keyboard_leds = 0x00;
    layer_pop(1);
    }

    AND, if you pay attention to how I did my layers you should always have an appropriate pop button to go back to the base layer to clear the LED and bring you back to the base layer.

    Hope this helps someone, because it took a bit of tinkering. Big thanks to Moazzam for getting me started.

    Regards,
    Duq

  4. Moazzam Avatar

    I updated the post with the right way to turn LEDs off (at least with what worked for me)

  5. patrain Avatar
    patrain

    This is great man. I got it to work great for Layer 1 being the caps lock led and Layer 2 as the scroll lock led. Only issue is that caps lock turns the light on and off independently of the layer pushing and popping. Ill look into that later, just some thing to fix I guess.

Leave a Reply

Your email address will not be published. Required fields are marked *