I have designed a framework for making affordable and stylish modular controllers. You can use the content of this Instructable to make a wide range of controllers for a wide range of applications relevant to artists, DJs, VJs, gamers, producers, and the like. The DJ controllers I showcase in this document serve only as examples of (more conventional) interfaces you can create within the framework.

I focused on making this project affordable, stylish, and most important, builder friendly. The controllers can be re-programmed to send serial, MIDI, or HID messages. The modular design allows you to plug the controllers into one another, thus requiring only one USB port on your computer. Each module can have approximately 28 digital inputs/outputs, 23 analog inputs, and 4 rotary encoders. Those more savvy could add components such as touchscreens, sensors, pressure pads, etc., to the controllers using this framework. No special tools or equipment are required to build these controllers beyond a basic soldering iron and wire stripper. Also, very little coding is necessary. Editing the code is more like filling in the blanks.


More info here.

Some hype at engadget.

**Remember to read this entire Instructable before beginning any of the constituent steps**

Step 1: Components

I have spent endless hours searching for the best and most reasonably priced components from around the world. I ordered many different components to test out and compare, most of them were rubbish and were not used in project. Here is the list of the best stuff I found. The ones with * are my favorites.


  • Teensy++ @ PJRC (USA)
  • Teensy suppliers in Europe: 1, 2, 3


(Many of these pushbuttons are available in different sizes and color - check the sites for more options. With pushbuttons, you usually get what you pay for.)


(If these are out of stock, they may also be available at digikey.com or newark.com. If you are a scratch DJ you probably demand a 'frictionless' fader. DJ Deals sells them for cheap, and they are simple enough to use with the DIY controllers.)

Slide knob

  • Many options available at Newark.


Potentiometer Knobs

(Knurled knobs can only be attached to knurled shafts. Knobs with set screws will require a hex key to couple with the potentiometer. 6.4mm knobs coupled with 6mm shafts fit slightly non-concentric - this can be fixed with some scotch tape. 6.35mm potentiometers do exist although I was unable to find an economical option.)


(Search 'PEC11-' on Newark to get a long list of nice and affordable encoders. I used PEC11-4115F-S0018 and PEC11-4215F-S0024 in my build. I tested many encoders and found the Bourns ones to be best. They have both D, and knurled shaft options available.)


Wires & Connectors


Header Pins

  • Male @ All Electronics, Sparkfun, Futurlec, Adafruit, SureElectronics
  • Female @ Sparkfun, SureElectronics, Futurlec

(Sure electronics is by far the cheapest!)


(Every site has plenty of different LED options. Keep in mind this controller framework is not really designed to control more than a few LEDs. Now that is not to say you can't use many LEDs in this project, you just can't control them, ie, turn them on and off when you please.)

All hardware (nuts, bolts, standoffs) can be found at McMaster (USA). McMaster is the best!

Soldering iron, wire cutters/strippers.

There are many other components you may want to include in your interface such as LCDs, touchscreens, trackballs, pressure pads, proximity sensors, etc. SparkFun and Adafruit are the best resources for these kinds of components. Although the controllers I showcased in this Instructable are somewhat conventional, I encourage you to get crazy. DIY gives you the power to do anything you can imagine - just wait till you see the next controller I am going to build!

Read the datasheets carefully before buying components.

Discount/surplus stores like Futurlec & All Electronics have excellent prices, but also carry some components which are totally bogus - be extra careful before buying from these stores.

Note that all these components are panel mount (with exception to the LEDs). There is an important distinction between surface mount and panel mount components. Surface mount components fasten directly to the printed circuit board (PCB) while panel mount components fasten to the top panel and connect to the PCB via wire and solder connections. It is usually not possible to use surface mount components unless you fabricate custom PCBs and have expert soldering skills. Using panel mount components makes this project accessible to anyone.

So how much do these controllers cost? I don't kow how much your controller is gonna cost but mine were cheap, really cheap!

If you are from Europe or Asia this list may not be totally relevant or useful. Please send me links to suppliers in your countries so I can add them to this document.

<p>Hey, thanks for the Instructable! I was interested in implementing the shift button in a code from another instructable: <a href="http://www.instructables.com/id/PACMOD-MIDI-DJ-Controller/?ALLSTEPS" rel="nofollow">http://www.instructables.com/id/PACMOD-MIDI-DJ-Con...</a> but I'm having trouble with the mapping of the shifted buttons. I edited the code to use pin 3 as a shift button and it works but when I hold the shift button, the new midi notes seem to be all over the place, would you have any idea how to fix that? </p><p>it's currently mapping the shifted MIDI notes from<br>48, 49, 50 to 18, 17, 16<br>44, 45, 46, 47 to 14, 0, 1, 2<br>40, 41, 42, 43 to 3, 4, 5, 6</p><p>It's supposed to map the shift notes like this (+12 from original):</p><p>48, 49, 50 to 60, 61, 62<br>44, 45, 46, 47 to 56, 57, 58, 59<br>40, 41, 42, 43 to 52, 53, 54, 55<br><br>I'd really appreciate any help! Thanks!<br><br>---------------------------------------------------------------------------------------</p><p>#include &lt;Bounce.h&gt;</p><p>/*</p><p>PacMod DJ Controller 002</p><p>*/</p><p>//SHIFT_______________________________________________</p><p>//shift buttons offer dual functionality to your pushbuttons and encoders</p><p>//if using a shift button enter the pin number here, else put 0</p><p>int shiftPin = 3;</p><p>int shiftChange;</p><p>// pin definitions</p><p>const int digital_pin[] = { 0, 1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 13 };</p><p>const int analog_pin[] = { A3, A4, A5, A6, A7 };</p><p>// variables for the states of the controls</p><p>boolean digital_stored_state[24];</p><p>int analog_stored_state[6];</p><p>// amount of change that constitutes sending a midi message</p><p>const int analog_threshold = 2;</p><p>const int analog_scale = 8;</p><p>// Debounce</p><p>long debounceDelay = 20;</p><p>Bounce digital_debouncer[] = {</p><p>Bounce(digital_pin[0], debounceDelay),</p><p>Bounce(digital_pin[1], debounceDelay),</p><p>Bounce(digital_pin[2], debounceDelay),</p><p>Bounce(digital_pin[3], debounceDelay),</p><p>Bounce(digital_pin[4], debounceDelay),</p><p>Bounce(digital_pin[5], debounceDelay),</p><p>Bounce(digital_pin[6], debounceDelay),</p><p>Bounce(digital_pin[7], debounceDelay),</p><p>Bounce(digital_pin[8], debounceDelay),</p><p>Bounce(digital_pin[9], debounceDelay),</p><p>Bounce(digital_pin[10], debounceDelay),</p><p>Bounce(digital_pin[11], debounceDelay),</p><p>Bounce(digital_pin[12], debounceDelay),</p><p>Bounce(digital_pin[13], debounceDelay),</p><p>//Bounce(digital_pin[14], debounceDelay),</p><p>//Bounce(digital_pin[15], debounceDelay),</p><p>//Bounce(digital_pin[16], debounceDelay),</p><p>//Bounce(digital_pin[17], debounceDelay),</p><p>//Bounce(digital_pin[18], debounceDelay)</p><p>};</p><p>// MIDI settings</p><p>int midi_ch = 3;</p><p>int midi_vel = 127;</p><p>const int digital_note[] = { 48, 49, 50, 51, 44, 45, 46, 47, 40, 41, 42, 43};</p><p>const int analog_control[] = { 0, 1, 2, 3, 4, 5 };</p><p>void setup() {</p><p>Serial.begin(38400);</p><p>// set the pin modes &amp;&amp; zero saved states</p><p>int b = 0;</p><p>//SHIFT - pin config _______________________________________________</p><p>//we need enable the shift pin as an INPUT as well as turn on the pullup resistor</p><p>if(shiftPin!=0){</p><p>pinMode(shiftPin,INPUT_PULLUP); //shift button</p><p>}</p><p>// digital pins</p><p>for (b = 11; b &gt;= 0; b--) {</p><p>pinMode(digital_pin[b], INPUT_PULLUP);</p><p>digital_stored_state[b] = false;</p><p>}</p><p>// analog pins</p><p>for (b = 0; b &lt; 5; b++) {</p><p>analog_stored_state[b] = 0;</p><p>}</p><p>}</p><p>void loop() {</p><p>fcnProcessButtons();</p><p>//SHIFT loop _______________________________________________</p><p>if(shiftPin!=0){</p><p>if(digitalRead(shiftPin)==LOW){ //check if shift button was engaged</p><p>shiftChange = 12; //if enganged, the offset is 12</p><p>}else{</p><p>shiftChange = 0;</p><p>}</p><p>}</p><p>}</p><p>//Function to process the buttons</p><p>void fcnProcessButtons() {</p><p>int b = 0;</p><p>// digital pins</p><p>for (b = 11; b &gt;= 0; b--)</p><p>if(b!=shiftPin){ //ensure this is not the shift pin</p><p>int j = b + shiftChange; //add the shift change (+12)</p><p>digital_debouncer[b].update();</p><p>boolean state = digital_debouncer[b].read();</p><p>if (state != digital_stored_state[j]) {</p><p>if (state == false) {</p><p>usbMIDI.sendNoteOn(digital_note[j], midi_vel, midi_ch);</p><p>} else {</p><p>usbMIDI.sendNoteOff(digital_note[j], midi_vel, midi_ch);</p><p>}</p><p>digital_stored_state[j] = !digital_stored_state[j];</p><p>}</p><p>}</p><p>// analog pins</p><p>for (b = 0; b &lt; 5; b++) {</p><p>int analog_state = analogRead(analog_pin[b]);</p><p>if (analog_state - analog_stored_state[b] &gt;= analog_scale || analog_stored_state[b] - analog_state &gt;= analog_scale) {</p><p>int scaled_value = analog_state / analog_scale;</p><p>usbMIDI.sendControlChange(analog_control[b], scaled_value, midi_ch);</p><p>/* Serial.print(&quot;analog value &quot;);</p><p>Serial.print(b);</p><p>Serial.print(&quot;: &quot;);</p><p>Serial.print(analog_state);</p><p>Serial.print(&quot; scaled: &quot;);</p><p>Serial.println(scaled_value);*/</p><p>analog_stored_state[b] = analog_state;</p><p>}</p><p>}</p><p>}</p>
<p>Very nice instructable! I even decided to make a Remix 2.0, you can check it out here: http://www.instructables.com/id/Custom-Arduino-MIDI-Controller/ </p>
<p>Thanks for this awesome tutorial !!! </p><p>but i have a question, do you have a headphone output on your controller ? </p>
<p>Very interesting tutorial. I thought the wood enclosures on your controllers were epic.! I made a tutorial on how to make a midi controller as well. My tutorial explains how to make a very simple and easy midi controller. You can find it here if you are interested: http://www.midilifestyle.com/blog/basic-controller-build/</p>
<p>this would be nice for photoshop!</p>
When will teensy monster be available?
<p>Would it be possible to add velocity sensative pads?</p>
<p>Send me the part specs and I can let you know. </p>
<p>Thanks for your Inspiration!<br>I've built a single piece controller quite some time ago. I finnaly ducumented it on my website! Check it out!</p><p>http://lbsfilm.at/custom-built-arduinobased-midi-dj-controller/</p>
<p>Bad Ass!</p>
<p>How did you get that VU meter to work? what are you using to drive it?</p>
Thank you so much for probably the best tutorial in the world! Great stuff! Lots of info and all. I do have a couple of questions tho: I am planning on attaching an XLR mic to the controller itself (like on pioneer cdj mixer) and found a thing which you can attach the lead to. Im stuck here. Im not sure how to connect the wires and in what way from that into the teensy board to connect it to the pc to use it as a live mic. If anyone could help me out here i would be incredibly thankful! Also I am planning kn attaching an LCD touch screen on an extension on each deck. I found relaively cheap 3.5 LCD touch monitors which should be okay with teensy (i can use arduino if required) in order to either see the wave forms in Traktor DJ (like on Pioneer CDJ). I do not know how I can do this, but I though whether its possible to use that screen to show a part of my pc screen so i can adjust it to show these things. Sounds complicated, but I basically want to use these screens to see whats going on in my DJ software without having to look at my computer. Also another quick question, is it possible to m&agrave;ke a headphone port so I can attach my headphones to it and use these as a pre cue (again like on the pioneer CDJ). All help and comments will be incredibly usefull as I am a complete beginner to this and I am trying to do everything as slowly but as well as possible.
Apologies for poor spelling
<p>Can i use teensy 2 or teensy 3.1 ?</p><p>For 14 rotary pot</p><p>and 2 encoders</p><p>and 18 push button</p>
<p>Hey Fuzzy, my friend and i made a controller but there are some problems: sometimes the jitter extremely and sometimes they are all just on 127. we tested many different things, but we couldnt find the problem. we even tried to make a ground shield against interferences but somehow it only worked for a short period and then it went back like it was before. do you know what the mistake/ problem could be? thanks in advance <br>btw: your instructable is awesome!<br>orell and lenny</p>
Wow awesome! Nice work. <br>Others have complained about jitter too. Unfortunately it was an issue I could never replicate. I can probably show you a hack for the code that will help, but best look at your circuit first. Make sure you have a solid ground (laptop power plugged in). Are you running your analog ins through Teensy or the analog mux? <br>
<p>Thank you. Yes we grounded it and even try to make a little shield to prevent interferences. I looked for short circuits or slack joints but i havent found anything. I used quite a lot analog inputs, so we had to use the demultiplexer and all analog inputs. I mostly solved the jittering problem by changing the analogThreshold of the teensy and the mux, but now most of the potentiometers don't work anymore while all digital inputs still work. the analog ins sometime spit out random values and sometimes many inputs appear to have the exact same signal(like they were connected). it appears to be a slack joint or something alike but i tested all connections and they were fine. Do you know what the source of this issue could be?</p><p>(and sorry for any writing mistakes, im not a native english speaker)</p>
TeensyMonster is coming out this month: teensymonster.com<br><br>I will be updating all the documentation and code so everything is super easy to follow and reliable. <br><br>If your controller still has issues I suggest switching to the TeensyMonster framework!
<p>still coming out this month? I am in the midst of building my controller and hoping to use this for my project. </p>
<p>The jittering in my controller was due to code issues. These are solutions that helped for me and might help with your problem. </p><p>(1) The original version of the code has a mistake with the analog teensy pins. See highlighted part in attached pic. It should be 38,39,40 etc.</p><p>(2) It's very important to set the analog pin values to 0 if there's no pots connected to those pins. This should be done for the teensy analogs and the mux analogs.</p><p>(3) I deleted the sample LED code. That also caused jitter issues with my controller. If you running your LED's from the Teensy, you can comment out the LED code and check for jitter again.</p><p>I'm no pro and this could be some basics that you've checked already, but maybe 1 of these can help.</p>
<p>Here's a few pics of my Virtual DJ based controller. 3 Of my pots on teensy analog pins 0-2 is not working properly. It's giving the same output as pins 0-2 in the mux eg. analog 1 for both pot 2 on the teensy and pot 2 on the mux in the serial monitor. I've got 19 pots - 16 on the mux and 3 on the teensy. Please see my previous post.</p>
<p>I managed to find a solution to my issue. I don't think it's the most efficient solution but it works. I told the teensy that there's 24 analog pins and gave dummy pin values to the first 16 pins. This allowed it to assign values above 15 to the teensy analogs. The mux is using analog 0-15 and the teensy 16-23. See pic.</p>
<p>Please help!!!!!!!!! I'm not to familiar with coding. I have a problem with mapping my analog inputs in Virtual DJ. When I map the Teensy analogs, it gives me CTRL 0 to CTRL 6 and when I map the Mux Inputs, it's CTRL 0 to CTRL15. So the first 7 inputs of the mux and teensy have the same name in the mapping. That means if I turn 1 of the 2 knobs and both is maybe CTRL 3 for teensy and mux analog, it changes 2 controls on VDJ. Is there possibly a way to give the teensy or mux analogs other names or different signals?</p>
<p>great work Mr. Fuzzy. i managed to modify your code for teensy 3.0 but i cannot map encoders in traktor to browse trough list for example.... can you help me please? thank you!!!</p>
<p>How difficult would it be to adapt the code for an Arduino UNO?</p>
very do-able but i would recommend teensy
<p>SO sick. thanks for sharing.</p>
Awesome instructable. Started prototyping with an arduino and it only worked once. I've ordered my teensy++ (after stumbling across this instructable) and as you can imagine is very expensive in South Africa. But oh man, this is the best controller for midi projects and easy to setup via arduino IDE. I'm not a DJ, only an electronic enthusiast that accidentally saw an arduino project on youtube 3 months ago. Since then I've ordered a few arduinos to play with. Man, this is so much more interesting than fixing old car radios for friends. I've battled a bit with the jogwheel and browser wheel as this was my first time working with encoders. It was actually working and my issue was in the mapping of the dj software. That was because I did not follow step 4 to check if everything is working. What a waste of time. Nevertheless, I just wanted to know if I can add a 74HC595 shift register for more inputs. I'm about 4 inputs short and would rather do without it, than sell my other kidney to buy another teensy. Also I'm no coder and that is my problem. I can do minor tweeks in the code but would not be able to add the shift register in the code. Anybody please help.
Hallo again Mr.Fuzzy, <br>now I am really looking forward to some code-updates. I would especially be interested in how the teensy can not only send, but also receive MIDI-signals from Tractor. Example: an LED which lights up, when a Deck is playing. Tracktor can send MIDI-Out-Singnals, but which code do I have to insert where to make the teensy receive this signals? Do you have any experience with it, or do you know where to find soltions? Thanks for your help!
im not into arduino really, but this is a big instructable, thunbs up
So my I2C connections aren't working. The master module works in the midi sniffer, but the other ones don't. Here is a picture of the first few lines of the code in each one. <br> <br>I checked the hardware multiple times, and it turns out I accidentally had the resistors set up to the ground, but it turns out that wasn't the problem.
Sir, <br>Was waiting for this tutorial. <br>Can you please upload the schematic for better understanding? <br>And waiting for a DJ Vinyl Scratcher Tutorial
Could you point me in the right direction for programing button combinations that trigger separate actions for push buttons?
more high quality <a href="http://www.ledlightshub.com" rel="nofollow">LED lights</a> at the site&nbsp;http://www.ledlightshub.com.
hello again. So i didnt get a bread board. how would you suggest testing my components? All i ordered is the teensy. not the other larger pcb. I am planning on soldering directly to the teensy so I am kind of hesitant to just solder everything then do the coding even though the only buttons im using now are arcade buttons, so simple on/off switches. I plan to use only 0-16 I/O's on the teensy then chaining all the grounds.
you must have a breadboard for prototyping. <br><br>https://www.adafruit.com/products/239<br><br>do not solder directly to the teensy unless you are pro and enjoy spending hours de-soldering. <br><br>
thank you so much for posting this. <br> <br>So, I have a question regarding the LED Situation. I was wanting color changing LEDs under some clear rim Sanwa buttons. I'm sure that I could get them to light up but I want complete control over every buttons color. for example when I play one song I want this color scheme/template and a different one for a different song. I am basicly just making a midi fighter/mixer. below is what I have been thinking: <br> <br>8x8 arcade buttons(color changing led on button rims) <br>8 faders <br>solo and mute buttons on each fader(leds under each) <br>2 bus/eq knobs for each fader <br>8x8 fx knobs <br>spring loaded mod wheel <br> <br>what kind of pcb would i need for this? It needs to be mac compatible and plug and play. I guess i'm willing to shell out if i have to considering that this is like 3 controllers in one. Please point me in the right direction master.
64 arcade buttons? That is a lot. This framework will not support that many inputs. You need to get some i2c i/o expanders (mcp23017) or some shift-registers. Basically that will require lots of custom circuitry and coding.
Hi there Fuzzy-Wobble! <br>First off this is a fantastic instructable. I have built a controller and done the coding, but I have one major problem left: how to use it with Ableton live. I haven't been able to work out how to map/script it, so sadly it has sat in the corner for the last few months. I tried a midi sniffer and the messages seem fine. If anyone could help me or point me to a tutorial that would be very much appreciated! <br>Ps. It's really nice to see that even so long after you released this instructable you still reply to comments.
Looks like djerk may have the solution you are looking for. I have never mapped to Ableton but I know it is possible. I have seen it done many times.
drsalty, you could try adding the controller manually if ableton's not picking it up. <br> <br>1. Go to the following directory on your computer: Mac: [Your home folder]/Library/Preferences/Ableton/[your version]/User Remote Scripts/ Windows: [Windows boot drive]/Users/ [your Username]/AppData/Roaming/Ableton/[your version]/Preferences/User Remote Scripts/ <br> <br>2. You should see a UserConfiguration.txt file in this directory. This is the template that you will use to create custom controller mappings for Ableton. <br> <br>3. Create a new directory under &quot;User Remote Scripts&quot; and name it what you want your controller named in Ableton. <br> <br>4. Copy the UserConfiguration.txt file in to the new directory for your controller. (make sure to copy and not move, as you may need a clean template later.) <br> <br>5. Open the UserConfiguration.txt you just copied in to the new controller directory and follow the template to specify what you want each knob/button/slider to control (You will need the MIDI CC data from each control on your controller to configure this file.) *note* defining Macro 1 - 8 is very powerful as you can place your soft synths in instrument racks and define macros for commonly used controls. (controls like: Cutoff, Resonance, Osc Pitch, modulation, Envelope settings, AMP Volume, etc.) <br> <br>6. Save UserConfiguration.txt Now open Ableton and go back to the MIDI tab in preferences. If you've done everything correctly, you will now notice your custom controller name in the 6 pull downs for Instant Mappings. <br> <br>Source : https://forum.ableton.com/viewtopic.php?f=1&amp;t=167341
Hi Fuzzy-Wobble, <br><br><br> <br>I'm so glad I've found your instructable, it has been really informative.<br> <br>I'm currently at University in England, studying a degree in Music Technology. I'm basing my Final Year Project on the creation of a MIDI controller.<br><br> <br> <br>So far, I have added a MIDI output to an Arduino Uno (which seems a bad move now, looking at your instructable!) which is then connected to my computer via a MIDI to USB cable. The arduino is programmed to play MIDI notes.<br><br> <br> <br>I really like this instructable as I'm no coder. Is it going to be really difficult for me to follow this instructable with an Arduino? I understand your reasonining for not choosing one, but I've overcome the main issue of USB/MIDI now. Do you have any pointers to help me along? <br><br><br> <br>Many thanks again, this instructable and your final products have reinspired me again :)
Heya. You will have to revise the code quite a bit so it works with Arduino. The code is made only for Teensy++ at the moment. <br> <br>The first controller I made (http://fuzzywobble.com/project.php?p=18&amp;n=controllers-v1) was with Arduino and a MIDI shield.
Can this be done with teensy 3.0 ?
Yep. You would have to edit the code a bit, but it is possible.
i put my hat off in front of this amazing guide :)
Nicely done! A well documented instructable and some good tips for &quot;Doing it yourself&quot; without making a slavish copy of your project. <br> <br>I particularly like the fact that you provide a decently analysis as to which micro controller is most suitable and why. This is an area that I find interesting but there's so many choices with so MANY different combinations of input output etc. I tend to find it all rather confusing.
Does anyone know if theres a way to put a built in sound card with headphone out and so on ?
is it possible to add pitchsliders to the &quot;cd-players&quot;/decks and a crossfader to the mixer, if so, how ?

About This Instructable


598 favorites


Bio: I am a human from planet earth. I use my brain to make things. fuzzywobble.com
More by Fuzzy-Wobble: Teensy Monster v1.0 // DIY MIDI Controller Prototyping Wizardry With SPACEBREW Top / Best DIY Electronic Stores & Suppliers
Add instructable to: