Introduction: PC USB Media Volume Controller Based on Arduino

Picture of PC USB Media Volume Controller Based on Arduino

Hello all and welcome to my third Instructable.

A friend of mine has a sound system with a dial for volume control, and it sits on his desk looking really neat. I wanted something similar but with extra functionality and customizable. I figured that the Arduino Pro Micro can work like a HID device (i.e keyboard or mouse) and so using that, I could create what I call a Media Volume Controller.

PLEASE NOTE: This Instructable will only work with Arduino Leonardo or Arduino Pro Micro - an Arduino that supports HID functionality as a USB host. Please make sure your Arduino is compatible! If you have another Arduino, then yes it is possible to do it but believe me, it is extremely long and not worth the hassle. Purchase and Arduino Pro Micro from eBay and save yourself the headache!: Arduino Pro Micro - eBay

Apologies if I have missed anything out. I do review my Instructables quite regularly so I will add anything I may have forgotten...

Overall Concept

So what we will be doing is writing a script that can execute commands when a certain combination of buttons is pressed on the keyboard. The keyboard input will be coming from the Arduino Pro Micro (APM) which will know when/what to output depending on the buttons pressed on the APM. There will be 6 buttons which will be for play/pause, next track, previous track, show/hide desktop, user 1, and user 2. The last two buttons are customisable to what you want them to do, but that requires changing the AutoHotKey script which I'm sure you will be able to later..

So in my case, pressing CTRL + F11 on the keyboard, whilst the script is running, will open my task manager. The reason we have these shortcuts is because the APM can send keyboard press commands, and so when a button change is detected on the APM it can send the command to the computer and the script will detect it as key presses, therefore executing the command (open task manager). The rotary dial will control volume up and down, and has switch so you can mute as well. It will all be powered by USB so there is no need for an external power supply.

Tools required:

  • Soldering Iron
  • Solder
  • Wire cutters
  • Heatshrink tubing various
  • Wood saw/jigsaw
  • Sharp blade (Xacto or Stanley)
  • 32TPI fine tooth saw
  • sandpaper
  • Drill and drill bits various
  • Various wire (24AWG)
  • Multimeter

Materials required:

  • 18mm MDF or similar your choice
  • 5mm clear acrylic or your thickness choice
  • 3 x 5050 SMD RGB LEDs
  • USB Mini B PCB connector
  • USB A to mini-B connector
  • Arduino Pro Micro/Leonardo
  • Copper tape OR tactile buttons
  • 470k resistors x 6 and 1k resistors x 6 for capacitive buttons OR 1k resistors x 6 for tactile buttons
  • 220R resistors x 3
  • 180R resistors x 6
  • 2N2222 NPN Transistor x 3
  • Rotary Encoder Keyes 5 pin
  • 2 x 10nF capacitors for rotary encoder

Step 1: Designing the Appearance

Picture of Designing the Appearance

I wanted the whole thing to be black gloss, to give it a sleek look. The overall design consists of two layers of 18mm MDF with an acrylic piece 5mm thick, sandwiched in between. This acrylic piece will be edge-lit and will respond to changes in volume. The top part for the buttons and volume dial will be black acrylic with custom made backlit buttons. As you will find out, I had some difficulties and made some capacitive touch buttons instead. The USB input connector will be on the back on the product.

I didn't want the whole thing to be too big as it would take up too much space, but it's a nice size right now. Overall it is 110mm x 100mm x 50mm depth. This includes 18mm MDF x 2, 5mm acrylic x 2, and extra clearance.

Please see the diagram and/or Publisher file to check my design out. You can adjust the design as you like.

Step 2: Writing the AutoHotKey Script

This part may be a little bit tricky. This was the first time I had ever used this software and I wasn't too sure how it worked so I had to refer online quite a lot. This software allows us to write scripts which can execute commands when a certain combination of buttons is pressed. It looks for key presses from the Arduino and executes the command when it receives one.

There are 6 buttons so we have 6 available commands that we can send to the script to execute - as I mentioned, the 6 commands I used are the most common. You could also change them for gaming.

The script has assigned CTRL and some Fkeys to perform each command - you can change the script if you like but you will need to convert the script to an exe . Download the following: AutoHotKey

If you leave everything the same then you can simple run the .exe file attached after you have the Arduino programmed and everything wired up.

Step 3: Programming the Arduino

The Arduino code is simple - it contains multiple if statements which check the state of the buttons and then send the key presses if the buttons are high (pressed) else they do nothing. The rotary encoder uses interrupts to check for changes, and a counter keeps track of the current volume. This variable is used to map a PWM output value of the RGB LEDs to adjust the lighting according to the volume. As you put the volume up, the acrylic will slowly increase brightness of blue, and when you press mute, the acrylic lights up red. I will add some more colour changes for example when you press a button it goes green, press another button it goes yellow etc.

There are #define definitions at the top of the code which point to the pins for each button. You can adjust these pin number to suit yourself although if you are doing this exactly the same then do not change these pin numbers. They are according to the schematic in the next step. You should not have to change any of the code unless you understand the code, which it is quite decent to understand.

PLEASE NOTE: Again, this Instructable will only work with Arduino Leonardo or Arduino Pro Micro - an Arduino that supports HID functionality as a USB host. Please make sure your Arduino is compatible! If you have another Arduino, then yes it is possible to do it but believe me, it is extremely long and not worth the hassle. Purchase and Arduino Pro Micro from eBay and save yourself the headache!: Arduino Pro Micro - eBay

When selecting the device in the Arduino IDE make sure to choose the correct one.

PLEASE NOTE: If you are using capacitive buttons then you want to upload the 'mediavolcontrollerHIDcapacitive.ino' file else if you are using normal tactile buttons then you want to upload the 'mediavolcontrollerHIDwithLED.ino' file.

Step 4: The Buttons

Picture of The Buttons

This is where I struggled - the plan was to create custom backlit buttons using tactile switches and some pieces of acrylic. I did complete this but it wasn't successful.

I designed the look of the buttons in Publisher, sprayed the acrylic pieces black, printed the design out and proceeded to engrave the symbols on the acrylic. The next step was to add the SMD LEDs to the acrylic, and then I finally aligned the buttons and drilled out holes to place the tactile switches. The switches were glued in place and wires soldered to them. Although it looked pretty good, it didn't work great because I had use some hot glue to hold the buttons in place. Three out of six buttons actually worked perfectly, but the remainder were stuck so I decided this would not be durable enough for every day use.

I then went on to discover capacitive touch buttons which can be easily made using copper tape, some resistors, and downloading an Arduino library. After much research I chose the capacitive buttons.

They were made simply by cutting out more or less square pieces of copper tape, sticking them down after aligning them and then soldering two resistors on to them One resistor is a send and the other is a receive, and the Arduino can detect changes in this, therefore allowing us to use buttons.

If you do not want to go through this then you can easily replace the inputs with normal tactile buttons but make sure you upload the correct code to the Arduino. Don't forget pull up resistors!

Step 5: Wiring It All Up

Picture of Wiring It All Up

Check the schematic to ensure you wire it all correctly - the schematic is related to the Arduino code. Make sure the Arduino code has been uploaded first, and then disconnect everything and continue to wire everything up according to the schematic.

I made a set of test capacitive buttons on a piece of cardboard but I didn't take a picture of this at the time unfortunately.

Step 6: Testing It All Out Before Making the Enclosure

Picture of Testing It All Out Before Making the Enclosure

I had it wired up to my test buttons rig to make sure it all worked before I was going to put it together.

I tried out all the functions of the MVC, and noticed that there was some lag when adjusting volume. I also noticed that as I'd turn the volume up, the keyboard would sometimes press random keys which would distort the mouse focus (it would disappear) - some really funny things happened.

I figured out that the problem was with the script I had written - I had misunderstood a bit of the code and had to remove the $ sign I had placed in some parts. After this was amended, everything seemed to work fine. I messed around with the delay settings in the Arduino code, and found that the best delay was 75ms for the rotary encoder and 50ms for the buttons. This is already done in the code.

Once you are happy with the test run we can continue to make the enclosure.

Step 7: Making the Enclosure Part 1

Picture of Making the Enclosure Part 1

According to the design, we need 2 x MDF 18mm thick 130mm x 100mm and one acrylic 5mm thick x 130mm x 100mm. This is for the sandwich layer which is crucial for the edge-lit effect. I cut my MDF with a jigsaw and the acrylic with a 32TPI hand saw.

Once you have these three pieces cut out, line them up and make adjustments using a sander if required. It took me a fair bit of sanding to make them lined up since my jigsaw alignment is off. Once they are lined up you want to label the top, front, back, bottom and sides so you know the exact orientation of all the pieces. The next step is to cut out a rectangle on the top MDF leaving around 10mm clearance around the whole MDF piece (see the pictures). This will be where the Arduino and other components will fit into.

For the clear acrylic, you need to place 3 RGB SMD 5050 LEDs (CHECK THE PINOUTS IN THE PICTURES!) on the rear end so they shine out the sides and the front. I did this by cutting 3 slots at the rear end big enough to fit a single RGB LED in. I folded the wires in such a way that the negative wires are on the left and the positives are on the right, so once the top MDF has been secured I will know the polarity of the wires when I'm soldering it to the Arduino. You can secure the RGB LEDs using some hot glue but be sure that the acrylic is still flat. the RGB LED should fit nicely within 5mm. You want to place the LEDs so that the wires are pointing up and down - not left and right. Because they are pointing up and down, you can fold the bottom wires over to the top and then separate them by polarity. You then want to hot glue them into place!

(As you can see in the last two pictures, there is a transistor for each RGB channel).

After this you want to measure the part where you will be placing the USB connector in the bottom MDF part, and then drill a hole through big enough to allow a USB cable to pass through. This is so the USB cable can reach into the top MDF piece. (CHECK THE PINOUTS IN THE PICTURES!)

Step 8: Making the Enclosure Part 2

Picture of Making the Enclosure Part 2

You now want to cut out a hole for the USB connector in the bottom MDF piece at the rear , or anywhere that you prefer the USB connector to go. You will also need a short USB A to mini-B cable which you can butcher, as you will need just the USB mini-B part to go into the Arduino, and the bare ends will be soldered on to a USB mini-B connector which will be on the body of the product.

We want to spray the MDF black, but you will need MDF primer - I applied it with a paintbrush although you will get much better results using a foam brush. Give the MDF a light sanding first, then apply one coat of primer. If required, give it another light sanding and then another coat or primer. Be sure to apply enough primer to the edges of the MDF because it soaks it really quickly. When you spray paint it, it will look patchy if you don't primer/sand it properly. Once the primer has fully dried after 24 hours, give it a coat of black spray paint, followed by another coat 4-6 hours later. Finally you want to let it dry for at least 24 hours in a warm area.

Once the paint job is finished, you can now continue to assemble the three pieces together. The bottom MDF goes first, followed by the acrylic (MAKE SURE you get the orientation correct) and finally the top MDF piece. I chose to put 3 bolts from top to bottom, by drilling 3 holes (one on each side, and one at the rear). Make sure everything is aligned and tighten the bolts up. Now you are left with the top part - the actual control board.

For this part you need the black acrylic and you need to drill a hole right in the centre large enough to let the rotary encoder through/thread go through tightly. To make the touch buttons cut out 6 x 15mm x 20mm copper tape pieces, and stick them at the location you like. Once that is done you want to drill two small holes on the top of each piece of tape so the resistors can pop through, and you can solder them on to the copper tape. When this is done you can hot glue the resistors on the inside of the acrylic to hold it all in place making sure nothing crosses. Check the picture out to see how I've done this part. When you have the buttons soldered, make sure everything is connected to the correct pins on the Arduino by cross referencing with the schematic.

If I've learnt one thing from all this DIY stuff, it's to check, check again, and check once again!

Step 9: Final Thoughts and Discussion

Picture of Final Thoughts and Discussion

And here we have the final product.. With the exception of the dial - I have this somewhere in the garage but I just need to attach it on to the rotary encoder.

So if I was to do this again, firstly I would use a laser cutter to print out multiple sandwich layers with much better precision than I have. The improvements I will be making will include having the acrylic light up different colours when different buttons are pressed, rather than it just being red or blue. Also I would like to make it a bit smaller and compact - I could have maybe used some less thicker wood for the bottom part. The top part's MDF thickness was just right as it is roughly the height of the Arduino Pro Micro.

Thank you for looking! Please feel free to leave any comments and feedback. I will be more than happy to answer any of your questions!

Comments

Robert-B (author)2016-01-24

Awesome project! I'm trying to integrate this in my project too. However, I won't be using leds. Is it necessary to edit the code if I remove the transistors and all of the leds from the circuit? (Since the arduino output is just HIGH or LOW I figured it wouldn't make much of a difference if something is connected or not).

Robert-B (author)Robert-B2016-02-02

I would really appreciate an answer

EdwardF2005 (author)Robert-B2017-05-31

No it wouldn't

l19bal (author)Robert-B2016-02-02

Hi apologies as I have been very busy. The LEDs are there for a nice visual effect. You can chose to include them or not, and if you don't, the code doesn't necessarily require editing. Hope that helps.

Robert-B (author)l19bal2016-02-02

Thanks! that means i can remove the NPN transistors as well right?

l19bal (author)Robert-B2016-02-03

Yes so if you were to remove the portion circled red (LEDs and transistors) this would not affect the function of the project. But you would lack the visually appealing LED effect.

Robert-B made it! (author)l19bal2016-02-06

I uploaded the code to the arduino, ran the autohotkeyscript and it automatically repeatedly sends the "mute button"; Its outputting (Ctrl+10) every half a second or so. It also does this when the arduino isn't connected to anything but my pc.

(Other things I noticed are that the rotary encoder was sort of functioning as a scroll wheel, when powering the arduino and the arduino all the "button simulations" were activated once. The arduino doesn't react to any button presses.)

Any idea what I'm doing wrong?

l19bal (author)Robert-B2016-02-10

Hi I'm not sure why you are having this issue. Please make sure that each function in the AutoHotKey script is unique and does not conflict with any of your personal customizations. In terms of the buttons not responding, please make sure you upload the file 'mediavolcontrollerHIDwithLED.ino' to the Arduino since you are not using capacitive touch buttons. If that doesn't make a difference, I would recommend rewiring everything and making it neater! Hope that helps.

Robert-B (author)l19bal2016-02-10

Thanks for your answer. I realised the pinouts for the capacitive buttons shown in the schematic aren't used for the tactile buttons as well. I can't find the schematic for tactile buttons in the instructable so I tried to make it up out of the code. Is there any chance you still have a picture of the schematic for the tactile buttons stored somewhere? Is the schematic of the tactile buttons (with pull-up resistors) I tried to make correct? ( I have left the leds and transistors out).

l19bal (author)Robert-B2016-02-12

Hi yes the schematic does look correct. You are using pull up resistors for each switch but since the code detects high pulses, I would recommend using pull down resistors. I do not have a schematic for buttons unfortunately! Alternatively, in the code you could change if (reading == HIGH && previous == LOW toif (reading == LOW && previous == HIGH but you would need to do that for all the if statements which detect the buttons presses. It would be much easier to use pull down resistors however! So where Vcc 5v goes into the resistors at the top, you would simply connect them to GROUND instead of 5v. And the other pin of the switches would go to 5v instead of ground. If I get a chance to I will upload a schematic for you! Hope that helps.

Robert-B (author)l19bal2016-02-14

Thanks for your help! It's working as it should now. I noticed that the internal pull-up resistor for the mute switch on the rotary encoder was missing, that's why it wasn't functioning. Also, the ahk-file was programmed to use CTRL + F8 and CTRL + F9 as scrolling wheel instead of adjustment of volume. I also realised that the pins on the arduino aren't aligned the same way as in the schematic. Perhaps you could mention some of these things in the instructable to prevent people from running into the problems like I did.

Thanks for sharing this project!

adicontakt (author)2016-11-16

hello , i have a problem when I try to compile the software it will give me some error " mediavolcontrollerHIDwithLED:92: error: 'Keyboard' not found. Does your sketch include the line '#include <Keyboard.h>'?

Keyboard.begin();"

and many more , but this is the first , can you tell me how to fix it?

EdwardF2005 (author)adicontakt2017-05-31

have you installed the keyboard library?

MatthewOgborne (author)2016-02-11

Howdy,

Some good news that will simplify the code and implementation of this for you.

See the code sample here http://pastebin.com/viR7U8rC

That is volume up, volume down and mute thats works with an Arduino Leonardo!

It's using the the HID library https://github.com/NicoHood/HID and Consumer functions, so need for a separate app or exe to run the media controls.

Hope that helps!

Matt

ZΣRO (author)2015-12-10

Very helpful, as I'm planning on creating an arduino-based physical control panel for my computer. I had to dig pretty far to find this! Thanks for the wonderful information~~

l19bal (author)ZΣRO2016-02-02

Glad it helped you out! I'd love to see your final product ☺

kentforth (author)2016-01-07

What software did you use for creating design?

l19bal (author)kentforth2016-01-07

I designed everything in Microsoft Publisher, done the schematic in ExpressSCH.

chazkapow (author)2015-10-15

This is a great home made piece of kit, good wiring - nicely done.

l19bal (author)chazkapow2015-10-15

Thank you, much appreciated :)

About This Instructable

13,802views

123favorites

License:

Bio: BEng Software and Electronic Engineering with Honours. Currently employed as a Developer for IBM. Experience with embedded systems, full stack development, UI/UX design, enterprise ... More »
More by l19bal:PC USB Media Volume Controller based on ArduinoWater Cooled and Wall Mounted Xbox 360Bench PSU Power Supply from Old ATX with Arduino and LCD Monitor
Add instructable to: