Introduction: Building a Basic Midi Controller Part 1 - Easy 3 Pot (Potentiometer) Arduino Uno Effects Midi Controller (Serial-USB)... Quick,easy and Cheap!

Picture of Building a Basic Midi Controller Part 1 - Easy 3 Pot (Potentiometer) Arduino Uno Effects Midi Controller (Serial-USB)... Quick,easy and Cheap!

Hello everyone,

I'm relatively new to Arduino and so have been battling my way to make my own midi controllers. There is a huge amount of information dotted around but I couldn't find a simple tutorial for such a simple device; so here it goes.

My original intention was to create a mixer similar to that used with a pair of decks. However, before I move onto that I wanted to make a piece of code which gave accurate and stable readings for potentiometers.

Step 1: What You'll Need!

  • Arduino of any kind, in this case I am using an Arduino Uno.
  • 6 short cables
  • 5 long cables
  • A prototyping breadboard
  • 3 x 10k Linear Potentiometers (the potentiometer should normally be labelled B10K)
  • Hairless Midi Serial Bridge (Software for sending/receiving midi data)
  • LoopBe1 (Virtual Midi Device Software)

Make sure you have all of these before starting.

Step 2: Wiring It Up...

Picture of Wiring It Up...

Hopefully you know the basics of circuits. Wire up cables from the positive rail to the positive pin on each of the pots, then do the same for the ground to the ground pins on the pots. The middle pin of each potentiometer is for data, providing an analogue reading from 0-1023. In the code we will use later this value is divided by 8 to give a value between 0-127 which is necessary so that the MIDImessage command works.

Hook up each of the middle pins to analogue pins on the Arduino 0 to 2 (A0 - A2).

Note: If your pots when finishing the tutorial work inversely (clockwise decreases the value and anti clockwise increases the value) then you simply need to switch the ground and power for each pot which should now give you the values rising when turned clockwise and decrease when turned anti-clockwise.

Step 3: Installing the Software...

Install LoopBe1 and Hairless Midi Serial Bridge if you haven't already.

To check that LoopBe1 is running, it should be in the bottom right of your OS (windows) and mute should be unchecked.

Once you have installed Hairless Midi, go into the preferences and set as the image shows. Do not worry about having your Arduino hooked up yet.

Step 4: The Code

Here's the nice bit of simple code based upon an example made back in 2009 by starfiretech. The key adjustments I have made to this code were to check new values against old values, only sending midi data when a change is detected; and the other adding a small delay to remove any slight variations given in value when the pot is not being touched, slightly touched or gets a little knock. Before I added this I was getting some variation (by +/- 1) in value when slightly touched which the delay helps to remove.

int val = 0; //Our initial pot values. We need one for the first value and a second to test if there has been a change made. This needs to be done for all 3 pots.
int lastVal = 0; int val2 = 0; int lastVal2 = 0; int val3 = 0; int lastVal3 = 0;

void setup() { Serial.begin(9600); // Set the speed of the midi port to the same as we will be using in the Hairless Midi software }

void loop() { val = analogRead(0)/8; // Divide by 8 to get range of 0-127 for midi if (val != lastVal) // If the value does not = the last value the following command is made. This is because the pot has been turned. Otherwise the pot remains the same and no midi message is output. { MIDImessage(176,1,val);} // 176 = CC command (channel 1 control change), 1 = Which Control, val = value read from Potentionmeter 1 NOTE THIS SAYS VAL not VA1 (lowercase of course) lastVal = val;

val2 = analogRead(1)/8; // Divide by 8 to get range of 0-127 for midi if (val2 != lastVal2) { MIDImessage(176,2,val2);} // 176 = CC command, 2 = Which Control, val = value read from Potentionmeter 2 lastVal2 = val2; val3 = analogRead(2)/8; // Divide by 8 to get range of 0-127 for midi if (val3 != lastVal3) { MIDImessage(176,3,val3);} // 176 = CC command, 3 = Which Control, val = value read from Potentionmeter 3 lastVal3 = val3; delay(10); //here we add a short delay to help prevent slight fluctuations, knocks on the pots etc. Adding this helped to prevent my pots from jumpin up or down a value when slightly touched or knocked. }

void MIDImessage(byte command, byte data1, byte data2) //pass values out through standard Midi Command { Serial.write(command); Serial.write(data1); Serial.write(data2); }

Step 5: Upload and Setup With Your DAW

Picture of Upload and Setup With Your DAW

If all has been copied correctly or adapted to your needs, the code should upload fine. Make sure you disable Hairless Midi Serial Bridge before trying to upload. You cannot to both at the same time!

Once the code has been uploaded successfully, ensure LoopBe1 is on and startup Hairless Midi serial Bridge.

Set the options as shown with your Arduino on the serial port and LoopBe1 as your midi output.

Next you need to setup the options in your DAW. In Ableton I have put LoopBe1 as a midi input ONLY (this is important as LoopBe1 can only act as either an input or outout in each application, you may get an error if you do and LoopBe1 will be muted. In this case make sure you have the correct settings in ableton as shown, then untick the mute button on LoopBe1) and put the input on remote mode.

Great, If all has worked then you should be able to see the midi input light turn on when moving one of the pots.

Step 6: Midi Mapping

Picture of Midi Mapping

Next map your midi controls to something in the DAW. Here I have inserted a test music track and applied a ping pong delay to that track. I have then assigned the 3 pots to different controls on the ping pong delay. To asign a pot, first click the midi button at the top right of the app. All assignable controls should now turn blue. Next click on the control in the plugin you want to be controlled by one of your pots. Once selected, then move a pot. That pot is now assigned to that control. Repeat for the other 2 pots but controlling different variables on the plugin.

Step 7: The Result

Here's a short video showing it in action.

Since this is my first instructable I'd love some feedback to improve on in the future. Hope this has helped a few of you trying to get to grips with Arduino Midi controller making.

Comments

ChristopherD174 (author)2017-09-15

Everything looks right from start to finish, however Ableton is still not recognizing that it's receiving MIDI signals even after configuring MIDI input on my Mac for ipMIDI as input while hairless MIDI is running. Hairless-midiserial confirms it is receiving proper signals from the 3 pots from 0-127, then I set up the input as remote for ipMIDI, but still Ableton LIve 9 Suite does not recognize incoming MIDI signals. What could I be missing?

I figured it out, I had to use IAC bus, not ipMIDI and configure my Ableton MIDI to have "Track" on. Here's the video that taught me in case anyone else needs it too: https://youtu.be/AepicXO7Dlc

gianbattista (author)2017-08-13

Congratulations!!! It's a very nice project. Just a question: may I use with my iMac?

Thank a lot for your kind help....

Gian Battista Pettinelli

DaniilZ made it! (author)2017-08-11

2 ez

Giorgio PalmasD made it! (author)2017-07-01

Cool ! Thanks for the project, this is my version with 5 potentiometers.

Do you know the code to add keys?

jnattrass (author)2017-01-07

Loopbee keeps muting me due to the amount of signals I think, is there anyway to solve this issue? its the only thing thats stopping it at the moment

DolphinAirlines (author)2016-12-24

now how would i go about adding buttons. so i could play samples off of them

Sencerkilic (author)2016-12-23

Hi all,

I am new to Arduino and Max and i can't figure out how to do it with Max. I wired everything and uploaded the code to Arduino but on Max i am really confused and i can't afford for LoopBe1 software right now. At first didn't now it wasn't free and i bought some potentiometers but can't figure it out. Also i want to learn Max to build controllers like this. I am lost at "serial" object on Max and can't find the port name for example. Any help or a Max patch for this project will be very appreciated!

mikepartlife (author)2015-12-21

Hey Andrew,

I followed your instructions up until the arduino code.. After uploading it to the board and opening it in the serial monitor I receive the unknown character question mark symbol. I have attached an image below, I copied your code exactly. I know this error normally appears when the baud rates are different in the serial and arduino code but this isnt the case.. Is it something simply i am overlooking? sorry im a relative beginner

Thanks

Mike

wurx (author)mikepartlife2016-11-22

99% of the time it's because your Baud rate is incorrect. Check the code for the Baud rate and then set the same rate on the Serial Monitor screen. (lower right hand corned)

MatiasC25 (author)2016-07-06

Hi, do you know why it flickers a little bit the values? im using it via MIDI cable and its always sending data... i have to be moving all the time the potentiometer i want to control the parameter or otherwise choose one randmly because theyre all active. and if i map it the value moves a little bit, any idea why? thanks!

APW-Design (author)MatiasC252016-09-29

Hi there Matias, sorry for the slow reply. This will be due to the delay which may not be significant with your pots (potentiometers). I can't sya for certain but this ussually happens with poor quality pots or pots that have a very high sensitivity. try increasing the delay to see if this solves the problem. increase 10 to 15, 20 etc until you find something stable, let me know how this work for you.

"delay(10); //here we add a short delay to help prevent slight fluctuations, knocks on the pots etc. Adding this helped to prevent my pots from jumping up or down a value when slightly touched or knocked."

Cosca07 (author)2016-06-22

Thanks for this tutorial!! Works fine.

Someone know how to add buttons to this??

Yorec (author)2016-05-13

Cool project ! i 'm from France thanks for the tutorial everything works fine ! (i also added more pots) but i want to add 12 buttons. Can anyone help me with that?

This is the code.

int val = 0; //Our initial pot values. We need one for the first value and a second to test if there has been a change made. This needs to be done for all 3 pots.

int lastVal = 0;

int val2 = 0;

int lastVal2 = 0;

int val3 = 0;

int lastVal3 = 0;

int val4 = 0;

int lastVal4 = 0;

int val5 = 0;

int lastVal5 = 0;

int val6 = 0;

int lastVal6 = 0;

void setup()

{

Serial.begin(9600); // Set the speed of the midi port to the same as we will be using in the Hairless Midi software

}

void loop()

{

val = analogRead(0)/8; // Divide by 8 to get range of 0-127 for midi

if (val != lastVal) // If the value does not = the last value the following command is made. This is because the pot has been turned. Otherwise the pot remains the same and no midi message is output.

{

MIDImessage(176,1,val);} // 176 = CC command (channel 1 control change), 1 = Which Control, val = value read from Potentionmeter 1 NOTE THIS SAYS VAL not VA1 (lowercase of course)

lastVal = val;

val2 = analogRead(1)/8; // Divide by 8 to get range of 0-127 for midi

if (val2 != lastVal2)

{

MIDImessage(176,2,val2);} // 176 = CC command, 2 = Which Control, val = value read from Potentionmeter 2

lastVal2 = val2;

val3 = analogRead(2)/8; // Divide by 8 to get range of 0-127 for midi

if (val3 != lastVal3)

{

MIDImessage(176,3,val3);} // 176 = CC command, 3 = Which Control, val = value read from Potentionmeter 3

lastVal3 = val3;

val4 = analogRead(3)/8; // Divide by 8 to get range of 0-127 for midi

if (val4 != lastVal4)

{

MIDImessage(176,4,val4);} // 176 = CC command, 4 = Which Control, val = value read from Potentionmeter 4

lastVal4 = val4;

val5 = analogRead(4)/8; // Divide by 8 to get range of 0-127 for midi

if (val5 != lastVal5)

{

MIDImessage(176,5,val5);} // 176 = CC command, 5 = Which Control, val = value read from Potentionmeter 5

lastVal5 = val5;

val6 = analogRead(5)/8; // Divide by 8 to get range of 0-127 for midi

if (val6 != lastVal6)

{

MIDImessage(176,6,val6);} // 176 = CC command, 6 = Which Control, val = value read from Potentionmeter 6

lastVal6 = val6;

delay(10); //here we add a short delay to help prevent slight fluctuations, knocks on the pots etc. Adding this helped to prevent my pots from jumpin up or down a value when slightly touched or knocked.

}

void MIDImessage(byte command, byte data1, byte data2) //pass values out through standard Midi Command

{

Serial.write(command);

Serial.write(data1);

Serial.write(data2);

}

szymex73 (author)2016-04-16

This project is amazing! But i have problem with adding more potentiometers. Can anyone help me with that?

Yorec (author)szymex732016-05-13

my code for this with 4 pots and two sliders! work for me.

int val = 0; //Our initial pot values. We need one for the first value and a second to test if there has been a change made. This needs to be done for all 3 pots.

int lastVal = 0;

int val2 = 0;

int lastVal2 = 0;

int val3 = 0;

int lastVal3 = 0;

int val4 = 0;

int lastVal4 = 0;

int val5 = 0;

int lastVal5 = 0;

int val6 = 0;

int lastVal6 = 0;

void setup()

{

Serial.begin(9600); // Set the speed of the midi port to the same as we will be using in the Hairless Midi software

}

void loop()

{

val = analogRead(0)/8; // Divide by 8 to get range of 0-127 for midi

if (val != lastVal) // If the value does not = the last value the following command is made. This is because the pot has been turned. Otherwise the pot remains the same and no midi message is output.

{

MIDImessage(176,1,val);} // 176 = CC command (channel 1 control change), 1 = Which Control, val = value read from Potentionmeter 1 NOTE THIS SAYS VAL not VA1 (lowercase of course)

lastVal = val;

val2 = analogRead(1)/8; // Divide by 8 to get range of 0-127 for midi

if (val2 != lastVal2)

{

MIDImessage(176,2,val2);} // 176 = CC command, 2 = Which Control, val = value read from Potentionmeter 2

lastVal2 = val2;

val3 = analogRead(2)/8; // Divide by 8 to get range of 0-127 for midi

if (val3 != lastVal3)

{

MIDImessage(176,3,val3);} // 176 = CC command, 3 = Which Control, val = value read from Potentionmeter 3

lastVal3 = val3;

val4 = analogRead(3)/8; // Divide by 8 to get range of 0-127 for midi

if (val4 != lastVal4)

{

MIDImessage(176,4,val4);} // 176 = CC command, 4 = Which Control, val = value read from Potentionmeter 4

lastVal4 = val4;

val5 = analogRead(4)/8; // Divide by 8 to get range of 0-127 for midi

if (val5 != lastVal5)

{

MIDImessage(176,5,val5);} // 176 = CC command, 5 = Which Control, val = value read from Potentionmeter 5

lastVal5 = val5;

val6 = analogRead(5)/8; // Divide by 8 to get range of 0-127 for midi

if (val6 != lastVal6)

{

MIDImessage(176,6,val6);} // 176 = CC command, 6 = Which Control, val = value read from Potentionmeter 6

lastVal6 = val6;

delay(10); //here we add a short delay to help prevent slight fluctuations, knocks on the pots etc. Adding this helped to prevent my pots from jumpin up or down a value when slightly touched or knocked.

}

void MIDImessage(byte command, byte data1, byte data2) //pass values out through standard Midi Command

{

Serial.write(command);

Serial.write(data1);

Serial.write(data2);

}

AdriaanB2 (author)2016-04-24

Thank for the tutorial, I have one issue though. I recreated this with 8 pots and 4 faders and everything sends messages to my DAW as it should, but it also sends additional random midi notes and error messages in Hairless MIDI. Does anybody know where to start looking?

BalázsL (author)AdriaanB22016-04-28

Try higher baum rate.

makeosaurus (author)2016-03-04

How would I go around adding buttons? Also, What would happen if I used different Pot values?

APW-Design (author)makeosaurus2016-04-08

Hi there,

I'm going to add a new tutorial soon due to the massive response I have had to this tutorial. I'll explain the addition of further buttons for functions and this tutorials application on a greater scale for the creation of mixing boards etc. There will also be tutorials explaining how to build a pressured based drum pad with silicon and another using a distance sensor as a variable for midi control.

subzero69 made it! (author)2016-01-29

Works lovely with VDJ. Could not get it working on the MAC :( issues my end tbh. It certainly works on windows. :D So all good.

mrkubag (author)2016-01-24

Will it work with switch? I want to try doing something similiar to Midi Fighter. Sorry for bad English.

bbaris (author)2015-07-30

Hello congratulations Andrew. Instead of using LoopBe1, I have used MidiYokeNT software (totally free) with Reaper. It works very well too :). So thank you for sharing your awesome arduino project.

makeosaurus (author)2015-07-07

how do you set up hairless midi?? there is no picture!

APW-Design (author)makeosaurus2015-07-07

Apologies, looks as though a few images have gone missing so I'll get these uploaded.

snoop911 (author)2015-05-15

Do you have any thoughts on Cycling74's Max software? It seems to be geared for Arduino / Midi Instruments, but not sure if it's worth checking out.

StumbleF (author)snoop9112015-05-21

Max is very powerful, and is indeed geared for MIDI instruments (it predates Arduino by a good few years!). With Max you can skip the middleware (Hairless MIDI<->Serial Bridge in this case), directly capture the serial com port and convert the serial data into MIDI. You can also forward the MIDI messages, use them within Max, manipulate video and generate audio... Its a swiss army knife of audio and performance use cases - everything from generating and processing audio to manipulating video.
That said, Max is very expensive and would be difficult to use without some basic programming knowledge. Its a visual programming environment, meaning you don't write code per se, but rather drag and drop pre-built functions. However, knowing the basics of programming makes everything a lot easier.
I'm a big fan of Max, so I would strongly recommend you download the trial, follow a few basic tutorials and poke around the help section which helpfully includes fully functional and modifiable example "patches" (think Arduinos sketches).

snoop911 (author)StumbleF2015-05-25

Thanks, I'm very new to MIDI/hardware so the idea of getting up and running, quickly is a plus! I'm surprised there hasn't been any instructables for it.. I wonder if there's any open source equivalent of Max?

StumbleF (author)snoop9112015-05-29

Max shares a common root with Pure Data, which is open source. Its not as pretty and works slightly differently, but for basic midi stuff its just as powerful as max

APW-Design (author)StumbleF2015-05-21

Nice one buddy, I was going to explain it all but ive been short of time recently so I appreciate the update. I hope this has simplified making a midi controller with Arduino for people.

tomatoskins (author)2015-05-15

This is awesome! I love making little controllers like this!

About This Instructable

56,977views

176favorites

License:

Bio: My name is Andrew (Andy) and I am currently a student at Leeds Beckett University studying BA (Hons) Product Design at the Leeds School of ... More »
Add instructable to: