A rotary encoder is a device that you can twist to perform actions. Some encoders can also be pushed, just like a button! Some keyboards, like the Kyria, support rotary encoders.
But what can you actually use them for?
Well, a rotary encoder twists clockwise and counter clockwise. It lends itself to actions that you'd otherwise need to repeatedly press a button for, and to actions that have both a forward and a reverse direction. For example:
- Audio control, to turn the volume up or down;
- Scrolling, to scroll up or down a page or document with Page Up and Page Down;
- Tabbing, to go to the previous or next browser tab with for example Control Tab and Control Shift Tab;
- Window movement, to go to the previous or next window with Alt Tab and Alt Shift Tab;
- History scrubbing, to perform undo and redo;
- Scrolling horizontally by word, with Control Arrow Left and Control Arrow Right (if you hold down shift while turning the encoder, you can select words too!);
- Scrolling through search results, with Find Next and Find Previous when you map the encoder actions to your text editor's shortcuts.
Of course, you can program them to do anything. I've seen people program common text snippets so you can enter text with the simple turn of the encoder.
Since most encoders can also function as a button, you can simply use the keymap to assign an action to the button press. You can for example have an encoder mute on press, and control volume with rotation, but it can also be another action entirely. Our ALPS Industrial Encoder supports both scrolling and pressing it as a button, and it's very tactile, making it easy to feel a click every time the encoder perform an action.
I designed a custom knob specifically for keyboards. You can get your own at splitkb.com.
Code Samples
So now you know some of the things you can do with a rotary encoder, and now you want to actually use it. At the time of writing, the QMK Configurator doesn't yet allow to configure the rotary encoders, so you'll need to get your build environment set up and customize your keymap by code.
You can read the official QKM documentation on rotary encoders here. If you're using the default keymap, chances are you'll need to enable the use of encoders by adding ENCODER_ENABLE = yes
to your rules.mk
file. Once you've done that, you can use the following code examples. First, let's explain a bit of what the code does overall. Here's the example that's listed in the official documentation, where I added some extra comments:
/* The encoder_update_user is a function.
* It'll be called by QMK every time you turn the encoder.
*
* The index parameter tells you which encoder was turned. If you only have
* one encoder, the index will always be zero.
*
* The clockwise parameter tells you the direction of the encoder. It'll be
* true when you turned the encoder clockwise, and false otherwise.
*/
bool encoder_update_user(uint8_t index, bool clockwise) {
/* With an if statement we can check which encoder was turned. */
if (index == 0) { /* First encoder */
/* And with another if statement we can check the direction. */
if (clockwise) {
/* This is where the actual magic happens: this bit of code taps on the
Page Down key. You can do anything QMK allows you to do here.
You'll want to replace these lines with the things you want your
encoders to do. */
tap_code(KC_PGDN);
} else {
/* And likewise for the other direction, this time Page Down is pressed. */
tap_code(KC_PGUP);
}
/* You can copy the code and change the index for every encoder you have. Most
keyboards will only have two, so this piece of code will suffice. */
} else if (index == 1) { /* Second encoder */
if (clockwise) {
tap_code(KC_UP);
} else {
tap_code(KC_DOWN);
}
}
return false;
}
The code block above is the basis of the code samples below. You'll replace the tap_code parts with the code samples, but the overall structure will remain the same.
Now let's get to the actual code samples!
Audio Control
Simple but effective, controlling audio is what most people will do with at least one of their encoders.
if (clockwise) {
tap_code(KC_VOLU);
} else {
tap_code(KC_VOLD);
}
Scrolling
There are many ways to scroll. You can use the mousewheel scroll keycodes, or simply arrow up or down a few times. My preferred way is to use Page Up and Page Down, as I find it faster and more reliable for my needs.
if (clockwise) {
tap_code(KC_PGDN);
} else {
tap_code(KC_PGUP);
}
Tabbing
Moving through your browser tabs is easy enough with Control + Tab and Control + Shift + Tab, but you can also do it with an encoder.
if (clockwise) {
tap_code16(C(KC_TAB));
} else {
tap_code16(S(C(KC_TAB)));
}
Window Movement
Like with tabs, you can also move through applications. In Windows, you can do this with Alt + Tab and Alt + Shift + Tab.
The code sample below is a modified version of the Alt Tab with a macro version listed in the QMK documentation about Macros.
Alt Tab with an encoder involves adding three pieces of code. Add the first bit at the top of your keymap.c
:
bool is_alt_tab_active = false;
uint16_t alt_tab_timer = 0;
Second, place this piece of code in your encoder code. It will start holding Alt if it's not holding it yet, and send a tab for each click you turn on the encoder.
if (clockwise) {
if (!is_alt_tab_active) {
is_alt_tab_active = true;
register_code(KC_LALT);
}
alt_tab_timer = timer_read();
tap_code16(KC_TAB);
} else {
if (!is_alt_tab_active) {
is_alt_tab_active = true;
register_code(KC_LALT);
}
alt_tab_timer = timer_read();
tap_code16(S(KC_TAB));
}
And last, the part that makes it all work. This'll release Alt for you if you haven't send a tab yet in a second. You can change the 1250 part (in milliseconds) to be higher or lower if you prefer. If matrix_scan_user
already exists, add the body of the function below to the already existing function:
void matrix_scan_user(void) {
if (is_alt_tab_active) {
if (timer_elapsed(alt_tab_timer) > 1250) {
unregister_code(KC_LALT);
is_alt_tab_active = false;
}
}
}
History Scrubbing
This will perform Control + Z when you turn the encoder clockwise, and Control + Y when turning it counterclockwise. With this, you can easily "scroll" through the history when editing a document. In some Adobe products, Control + Shift + Z is used for undo. You can hold Shift while turning counterclockwise to undo in that case.
if (clockwise) {
tap_code16(C(KC_Y));
} else {
tap_code16(C(KC_Z));
}
Scrolling Horizontally by Word
This will perform Control + Right Arrow when you turn the encoder clockwise, and Control + Left Arrow when turning it counterclockwise. If you hold shift while turning the encoder, you'll be able to select words while the cursor moves!
if (clockwise) {
tap_code16(C(KC_RGHT));
} else {
tap_code16(C(KC_LEFT));
}
Scrolling Through Search Results
When you search for something in your text editor, often you'll also have shortcuts to move to the next or previous result. In Visual Studio Code, these are F3 and Shift + F3. Here's how to do that on an encoder:
if (clockwise) {
tap_code(KC_F3);
} else {
tap_code16(S(KC_F3));
}