1

I'm getting this error when I try to use modifier keys on my rotary encoder like so:

bool encoder_update_user(uint8_t index, bool clockwise) {
    if (index == 0) { /* First encoder */
        if (clockwise) {
            tap_code(QK_LCTL | KC_F24);
        } else {
            tap_code(QK_LCTL | KC_F23);
        }
    } 
    return false;
}

This is the error:

Compiling: keyboards/planck/keymaps/dawz/keymap.c                                                  keyboards/planck/keymaps/dawz/keymap.c: In function 'encoder_update_user':
keyboards/planck/keymaps/dawz/keymap.c:68:22: error: unsigned conversion from 'int' to 'uint8_t' {aka 'unsigned char'} changes value from '371' to '115' [-Werror=overflow]
   68 |             tap_code(QK_LCTL | KC_F24);
      |                      ^~~~~~~~~~~~~~~~
keyboards/planck/keymaps/dawz/keymap.c:70:22: error: unsigned conversion from 'int' to 'uint8_t' {aka 'unsigned char'} changes value from '370' to '114' [-Werror=overflow]
   70 |             tap_code(QK_LCTL | KC_F23);
      |                      ^~~~~~~~~~~~~~~~
cc1.exe: all warnings being treated as errors
 [ERRORS]
 |
 |
 |
make[1]: *** [tmk_core/rules.mk:443: .build/obj_planck_rev6_drop_dawz/keyboards/planck/keymaps/dawz/keymap.o] Error 1
Make finished with errors
make: *** [Makefile:539: planck/rev6_drop:dawz] Error 1

The encoder works when I put in a regular keycode like KC_VOLUP or KC_VOLDOWN, but I’m trying to use Ctrl + F23, F24, so I can use the knob as a Voicemeeter macro buttons controller.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dawz
  • 19
  • 2

4 Answers4

3

You can represent "Ctrl + (basic key)" combinations using the macro LCTL(kc) (and similar macros for other mods), but the technicality is that this creates a 16-bit keycode. So rather than tap_code(), which is limited to 8-bit basic keycodes, use tap_code16() to tap it:

// Copyright 2022 Google LLC.
// SPDX-License-Identifier: Apache-2.0
bool encoder_update_user(uint8_t index, bool clockwise) {
  if (index == 0) {
    tap_code16(clockwise ? LCTL(KC_F24) : LCTL(KC_F23));
  } 
  return false;
}

See also the QMK encoders documentation.

Pascal Getreuer
  • 2,906
  • 1
  • 5
  • 14
0

If you want to use modifier keys here with encoders you should try using tap_code16 instead of tap_code

Try this instead:

bool encoder_update_user(uint8_t index, bool clockwise) {
    if (index == 0) { /* First encoder */
        if (clockwise) {
            tap_code16(QK_LCTL | KC_F24);
        } else {
            tap_code16(QK_LCTL | KC_F23);
        }
    } 
    return false;
}

Here is the link to the QMK doc for this

SUB
  • 1
0

You could break down how a key combination is pressed:

  1. Hold down the modifier key
  2. Press some key (usually a letter or number)
  3. Release the modifier key

Then you could represent the whole process:

bool encoder_update_user(uint8_t index, bool clockwise) {
    if (index == 0) { /* First encoder */
        if (clockwise) {
            register_code(QK_LCTL);   // Press and keep holding down
            tap_code(KC_F24);         // Press and release
            unregister_code(QK_LCTL); // Release
        } else {
            register_code(QK_LCTL);
            tap_code(KC_F23);
            unregister_code(QK_LCTL);
        }
    } 
    return false;
}

This approach seems to be dumb, but you can achieve much more complicated cases, such as Ctrl+Alt+Shift+A or something that could hardly do with keycodes.

I did this for one of my self-made keyboard, it works fine.

Leo
  • 13,428
  • 5
  • 43
  • 61
-1

take a look at my keymap at https://github.com/qmk/qmk_firmware/tree/master/keyboards/keebio/iris/keymaps/sq5rix you have working encoders there look at rules.mk, config.h and keymap.c - changes are everywhere

Tom
  • 1
  • 1
  • 3
  • 1
    Thanks to SO. While this link may be useful, it is better to include the essential parts here in your answer. Otherwise, if the external link becomes inaccessible in the future, this answer will become useless. – wovano Oct 16 '21 at 14:42