Custom volume knob - Arduino Leo

volume_knob_header.jpg I got bored, so I made another custom volume knob that would be a nice add-on for my mech keyboard. And also great for dedicated ‘talk to speak’ buttons for teamspeak3. I actually made this a while ago, but haven’t had a chance to write a post about this since I didn’t finish the code, mostly just enough for it to work just for me.

Well, since the lockdown all over the world due to the pandemic by the Wu-f*cking-han virus, I have more spare time to spend actually, to finish this project.

The 3D printed enclosure

Design a case for it using fusion360. It has a rotary encoder as volume pot, 4 extra buttons for whatever I might want.


I had natural colour PETG filament at that time on my printer, so just print it thinking that I could print another one with different colour. But nah, this colour is fine

Installing buttons and encoder

The switches are mechanical cherry mx switches or probably clones, I don’t really know. I don’t really trust ebay these day. Anyhow, it works as it should be.


The installing is quite straight forward. The switches must be installed from the top and then solder from the inside. I guess, no changing switch after finish.

The Red-Blue LEDs are glued to the switch before installed to the enclosure. This was the only type I had at that size and I didn’t bother to buy the correct RGB LED since it was, like, $30 for 10 pieces. It’s crazy, right?

If you want RGB, just add one more PWM channel to control the third colour.

The encoder is just a generic encoder for arduino you can find on ebay, nothing special

Connecting the wires

A bit hard to solder the wires to the pins alone so I use some cutout perfboard to keep the pins in place and have pads for wires to hang on to.


I didn’t draw a wiring diagram for this one because it was sooo simple, just connect the switch directly to Pro Micro board (arduino leonardo equivalent), the other pin of the switch goes to GND, too easy.

// Pin configuration
#define ENCA  9 // D9 - PCINT5
#define ENCB  8 // D8 - PCINT4
#define ENCP  7 // push button

#define BT1 A3  // button 1
#define BT2 A2  // button 2
#define BT3 A1  // button 3
#define BT4 A0  // button 4
#define BT5 ENCP

#define LED1  15  // LED for button 1
#define LED2  14  // LED for button 2
#define LED3  3   // LED for button 3
#define LED4  2   // LED for button 4

#define LRED  6   // PD7 - OC4D// LED RED - Must be PWM pin
#define LBLUE 10  // PB6 - OC4B// LED BLUE - Must be PWM pin

I can’t remember exactly the bi-colour LEDs were common cathode or common anode, but that doesn’t matter, just flip LED1–LED4 to low or high and then pulse LRED pin or LBLUE pin and see how the LEDs light up. Then change the code to HIGH or LOW to turn on the LEDs accordingly.

By the way, there are 1k or 470R resistors in series of the common pin of each LED. You don’t want to fry the LED nor the Pro Micro.


Final look of the project


The code

You need 2 libraries: TimerThree and NicoHood HID. NicoHood has excellent HID library for arduino. The built-in keyboard/mouse libraries are just garbage compare to NicoHood’s.

#include <TimerThree.h> // for LED fade out
#include "HID-Project.h" // NicoHood's library

Because of laziness, I still use analogWrite() for PWM.

#define _pwm(x, y) analogWrite(x, y)

Too much hassle to dig deep into Mega32u4 to do it properly just for onetime project. Hopefully one day, I may change this to custom PWM to improve LED fading effect, but for now it’s acceptable.

This is the last project I use AVR microcontroller. I think I won’t use AVR ever again. Probably I could use some Tiny AVRs for very simple stuff since they are dirt cheap, but I’ll stay far far away from Mega AVR.


Add comment

Fill out the form below to add your own comments

User data

Add your comment

[color=red] TEXT [/color]
[quote] TEXT [/quote]
[code=arduino avrasm cpp css java javascript nginx perl python] TEXT [/code]
Clear format