QMK Discussion Thread


That should be possible. But you want to call layer_on(x) or the like.


Is there any reason Timer 4 on the atmega32u4 isn’t supported for backlighting? Pins D6/D7 support a hardware PWM from it.

I ask because I’ve got a YD68 which uses D6 as the backlight pin. I took a stab at it over the weekend, but didn’t get far. Of course, I’m not neither a C nor firmware developer, so there’s a lot of parts I didn’t understand.


Probably because the backlight is written to support Timer 1, I think you’d have to rewrite a bunch of the code to support timer 4.

It may be worth opening an issue on github.


Does QMK support “IO Expander” ?

I plan to use a Pro Micro with this MCP23018T-E/SS

I want a relatively cheap “controller board” with QMK support because I can’t directly use an ATMega32u4, I just don’t get the stuffs about “bootloader” :frowning_face:


Yes. The ErgoDox EZ (and Dactyl) uses an IO Expander, actually. And uses the “MCP23018-E/SP” specifically. And both use QMK. So I think you should be fine with the expander that you’ve listed.


Just in addition to @drashna’s reply: according to the datasheet, the SP version of the MCP23018 is the through hole, DIP version, while the SS version is a SMD version in SSOP package.

Both versions will work, but the SP version is easier to deal with.


I need help with customizing the leds.

I have two leds connected to D0 and D4, I use D4 for Capslock.
here is what I want with the D0:

  • if default layer is “normal layer” (index is 0) - I use keycode DF(0) to switch
    • turn D0 led off
  • if default layer is “numpad layer” (index is 4) - I use keycode DF(4) to switch
    • num lock is off: blink the D0 led ( turn it on/off every 0.1s )
    • num lock is on: turn D0 led on

C is not my strong programing language,
I put together some code I found after searching,

Here is the code I have currently
#include "tnm40.h"

static uint16_t led_timer;
static bool isNumLockOn = false;
static bool ledOn = false;
static uint8_t default_layer = 0;

void led_set_user(uint8_t usb_led) {
	isNumLockOn = usb_led & (1<<USB_LED_NUM_LOCK);
    if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
        PORTD |= (1<<4);
    } else {
        PORTD &= ~(1<<4);

void matrix_scan_user(void) {
	default_layer = eeconfig_read_default_layer();
	if (default_layer & (1 << 4)) { // index 4: numpad layer
		if (isNumLockOn) {
			PORTD |= (1<<0);
		} else {
			led_timer = timer_read();
			if (timer_elapsed(led_timer) >= 100) {
				if (ledOn) {
					PORTD &= ~(1<<0);
				} else {
					PORTD |= (1<<0);
				ledOn = !ledOn;
	} else {
		PORTD &= ~(1<<0);

the D0 led is off even if I have switched default layer to the “numpad layer”.

any help is appreciated! :blush:

EDIT: the “hidden tag” is a bit subtle, isn’t it? :thinking:


Are you sure you want DF here? This changes the base layer. Depending on what you’re doing, a normal layer change (like TG or MO) mya work better here.

But what I’d do is…

void matrix_scan_user(void) {
  static uint16_t led_timer = timer_read();
  static bool is_led_on = false;
  PORTD &= ~(1<<0);
  if (biton32(default_layer_state) == 4) {
    if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) {
      is_led_on == true;
    } else {
      if (timer_elapsed(led_timer) > 100) {
        is_led_on ^= 1;
        led_timer = read_timer();
    if (is_led_on) { PORTD |= (1<<0); }

  if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) {
      PORTD |= (1<<4);
  } else {
      PORTD &= ~(1<<4);



thank you very much!
it is working! :grin:

Are you sure you want DF here? This changes the base layer. Depending on what you’re doing, a normal layer change (like TG or MO) mya work better here.

hmm… it’s just my assumption. While in the “numpad” layer, I won’t be using other layers so I think DF or TG would be the same. :thinking: I did use MO in layer 0, though.

I will try using TG instead of DF. :smiley:


I’m glad to hear it! :slight_smile:

And yeah, DF is for changing the base layer. It’s best for stuff like qwerty vs colemak vs, etc. You can use it other ways, but other layer codes are probably better to use. (and if you do change it, then change the default_layer_state to just layer_state)


I want to ask about RGB underglow, I plan to use WS2812B (it is supported by QMK)
Do I need to add individual resistor for each led?

I assume that I need to connect a ProMicro pin to “DIN” of WS2812B, is there any specific ProMicro pin I have to use? or any pins is fine? :thinking:


I’m assuming that you’re using WS2182 strips. If so, that’s all you need. Only the backlighting feature needs resisters. The underglow just needs the strip, usually.

If this is for “on the PCB”, then I’m not as sure.


yes, I want to put these WS2182 “on the PCB”.
I will do more research on these then :grinning:


You don’t need resistors, according to the datasheet. However, it do recommend using a 100nF bypass capacitor per LED.