Having a quick dial to turn down your computer’s volume is a handy tool that many multimedia keyboards have built in. But if you don’t have one on your keyboard, you can build it yourself with an Arduino, a knob, and a little bit of code. This guide will introduce how to add external libraries and control your PC with an Arduino.
To control a computer with an Arduino, we’re going to be using a variant Uno called the Leonardo. Unlike the Uno, this board is based on the ATmega32u4 chipset, which natively supports USB communication, letting the board act as a mouse and keyboard. Conveniently, this also allows it to send media control commands, similar to how volume, play, and pause buttons on keyboards work.
In order to use these media commands, though, you’ll need to enable an extra library in your Arduino IDE. Libraries contain additional code that can perform various specialized tasks, and the Arduino IDE comes with a collection of libraries for common functions like controlling servos, mice, or keyboards. However, the IDE also includes a searchable directory of additional libraries that can extend your projects even further.
It’s here where we’ll find the media control library we need. In the Arduino IDE, navigate to Sketch > Include library > Manage libraries… then search for “hoodloader”. Then click “Install.” Now, the HID-project library is available in your IDE. We’ll show you how to include it in your sketches down below in the code section.
There are a number of ways to build this particular tool, and it is technically possible to use an Arduino Uno using the Hoodloader2 library. However, the setup process for this method is outside the scope of this guide, so instead we will focus on the Arduino model that’s designed to act as a USB mouse and keyboard by default. With that in mind, you will need the following:
Arduino Leonardo | ![]() |
A Potentiometer
This is a simple, three-pronged input with an attached knob or dial. By regulating the power throughput, this input can adjust a value inside your Arduino, which we’ll use as a volume control. |
![]() |
Arduino IDE
If you haven’t set up the Arduino IDE you can check out our previous guide here. |
![]() |
You’ll also need a Micro USB cable, if you haven’t got one lying around, as well as a working computer.
This guide is designed for Windows users, and while the guide should work for users of other operating systems, the details may vary.
First, here’s the full code for the sketch we’ll be using.
#include
int potpin = 0; // Assign analog pin to potentiometer
int val = 0; // Variable to read value from potentiometer, starts at 0
int oldVolume = 0; // Used to compare volume levels
int currentVolume = 0; // Used to compare volume levels
void setup() {
Serial.begin(9600); // This will allow you to read the current value of the dial
}
void loop() {
val = analogRead(potpin); // Reads potentiometer value (between 0 and 1023)
val = map(val, 0, 1023, 0, 50); // Scale value to volume (value between 0 and 50)
Serial.print(val); // Print dial/volume position
Serial.println(); //
if (val != oldVolume) {
if(val > oldVolume){
//delay(100);
Consumer.write(MEDIA_VOLUME_UP);
currentVolume = currentVolume + 2;
oldVolume = val;
}
else{
//delay(100);
Consumer.write(MEDIA_VOLUME_DOWN);
currentVolume = currentVolume – 2;
oldVolume = val;
}
}
}
You can copy this code to your IDE and upload it if you want to skip ahead to the wiring section. For now, let’s explain a few of the important parts of this sketch.
#include
This line will include the media control library you added earlier into your sketch. This provides access to commands we’ll discuss in just a bit. While adding the Hoodloader library to your IDE through the menu makes it available for use in sketches, this line is necessary for any sketch that uses the commands contained within.
int potpin = 0; // Assign analog pin to potentiometer
int val = 0; // Variable to read value from potentiometer, starts at 0
int oldVolume = 0; // Used to compare volume levels
int currentVolume = 0; // Used to compare volume levels
The first line here initiates the signal pin from the potentiometer (or knob/dial). The position of the dial is then assigned to the val variable. This is used to raise or lower the volume level.
Since the volume level can’t be directly assigned, the sketch instead instructs the PC to raise or lower the volume level by increments of two—Windows volume levels range from 0 to 100—until the desired volume level is increased. The latter two variables, oldVolume and currentVolume are compared at each iteration of the loop until they match the level output by the dial.
val = analogRead(potpin); // Reads potentiometer value (between 0 and 1023)
val = map(val, 0, 1023, 0, 50); // Scale value to volume (value between 0 and 50)
These two lines of code read the position of the dial and then maps that value onto a scale from 0 to 50. Normally, a potentiometer can read values from 0 to 1023, but that’s way more variability than we need, so we’ll clamp the range down to 0 to 50.
Since Windows uses a volume range of 0 to 100 and increments this level by 2 at a time with each volume up or down command, this should make the minimum and maximum value of the dial correspond to the minimum and maximum volume level in Windows.
if (val != oldVolume) {
if(val > oldVolume){
Consumer.write(MEDIA_VOLUME_UP);
currentVolume = currentVolume + 2;
oldVolume = val;
}
else{
Consumer.write(MEDIA_VOLUME_DOWN);
currentVolume = currentVolume – 2;
oldVolume = val;
}
}
In this basic loop, the value pulled from the dial is compared with the previous volume level. As long as nothing has changed, the loop will do nothing. Once the dial moves, then the loop kicks in. If the dial moves up, then the loop will issue the MEDIA_VOLUME_UP command until the system volume matches the dial position. If the dial moves down, the loop will issue the MEDIA_VOLUME_DOWN command instead.
This command is sent using the Consumer.write() function of the HID-project API. This command can also be used for tasks such as pausing media, playing media, or muting the volume. Try adding more inputs like buttons and tweaking the sketch to use these.
The Wiring
Now that you know how the code works, you can upload the sketch to your Arduino Leonardo. Once it’s uploaded, you can start wiring up your potentiometer. The wiring for this project is simple:
● Connect the first pin on the potentiometer to GND.
● Connect the middle pin to Analog pin A0.
● Connect the final pin on the potentiometer to 5V.
● Connect the micro USB port on the Leonardo to the computer.
While many Arduino projects can function independently of a computer as long as they have a power source, this one needs to stay connected to the computer for obvious reasons.
This version of the sketch works best if both your computer’s volume and the dial are set to zero when first starting the Arduino. To make it more flexible, however, try using additional commands from the Consumer library to automatically turn down the system volume to sync it up with your dial when it’s first plugged in.