An Arduino-based HID multimedia controller using a rotary encoder and push buttons. Supports multiple switchable profiles for different applications — no drivers required, recognised as a standard keyboard and media device by any OS.
The controller uses a rotary encoder (turn + click) and a separate push button to cycle through profiles. LEDs indicate the currently active profile combination.
Two independent profile axes give a 4x2 grid of behaviours (8 total):
- Rotary mode (4 modes, switched by encoder click) — controls what turning the knob does
- Button mode (2 modes, switched by push button) — modifies the rotary behaviour
| Rotary Mode | Button Mode 1 | Button Mode 2 |
|---|---|---|
| 1 | Volume up/down | Volume down/up (inverted) |
| 2 | Ctrl+Tab / Ctrl+Shift+Tab (tab switching) | Ctrl+Tab / Ctrl+Shift+Tab |
| 3 | Up/Down arrow (Lightroom, PowerPoint) | Right/Down arrow |
| 4 | [ / ] (Photoshop brush size) |
R / L keys |
- Arduino Pro Micro (or any Arduino with HID support — Leonardo, Micro, etc.)
- Rotary encoder with push button (CLK, DT, SW pins)
- Separate push button
- 8x LEDs (4 for rotary mode indicator, 4 for button mode indicator)
Pin layout:
| Pin | Function |
|---|---|
| A0 | Encoder CLK |
| A1 | Encoder DT |
| A3 | Encoder SW (push) |
| 3 | Button |
| 10, 16, 14, 15 | Mode LEDs (rotary) |
| 6, 7, 8, 9 | Mode LEDs (button) |
- HID-Project — for Consumer media keys (volume etc.)
- Arduino Keyboard library
Install both via the Arduino Library Manager before uploading.
- Install the HID-Project and Keyboard libraries
- Open
button_and_rotary_switches.inoin the Arduino IDE - Select your board (Pro Micro / Leonardo / Micro)
- Upload to the Arduino
The device will appear as a USB HID keyboard and media controller immediately.
Add more actions:
Add new case entries inside the rotateRight() and rotateLeft() functions.
Refer to the HID-Project Consumer API
for available media key constants.
Add more profiles:
Increase maxModes (rotary profiles) or maxBTNModes (button profiles),
add the corresponding LED pins, and add new case blocks in the switch statements.
- Not all cases are fully mapped — several are placeholders left for customisation
- Debounce delay is set to 50ms, adjustable via
debounceDelay - Profile changes have a 300ms delay to prevent accidental double-switching