Entries Tagged 'Max/MSP' ↓

6 pots –> Arduino –> MIDI –>Max/MSP

I’ve been wanting to make some MIDI controllers for a while but I have never gotten past some crappy prototypes based on the PIC16F84A. So, after re-reading a really excellent book that a friend of mine at Berklee School of Music gave me, MIDI for the Professional, I decided to give it a try with the Arduino. I just wanted to make a simple 6 pot circuit that outputs values on 6 midi “Control Change (CC)” channels. You can download everything here (midi_test is a Max binary) and here are the details:

The first design rule I had was that it had to be a full midi implementation since I am running it through my Yamaha UX16 – USB MIDI Interface. So, I need:

  • a baud rate of 31250 (MIDI standard)
  • outputs 8 bit bytes
  • only uses 7 bits as value so messages must be b/w 0 and 127
  • needs to only send message when something changes

The first specification is simple. In Arduino’s setup() function, declare:

Serial.begin(31250);

To store the values in bytes, we need the appropriate data structure:

byte currentPot[6] = {0,0,0,0,0,0};

To make sure the bytes are only b/w 0 and 127 (and actually fit in a byte):

currentPot[i] = analogRead(i) / 8;

divide the result of analogRead() (0-1023) by 8 because 1023/8 = 127.875 . It just a simple way to map the values. Now, to make sure that it only sends when something changes, we have defined another data structure:

byte pot[6] = {0,0,0,0,0,0};

to store the past values of the pots. The program iterates through both byte arrays, if the value at i has changed by more than some delta, :

#define e 1

the message is sent and the current value replaces the old value. Make e = 0 if you want it to send a message every time there is a slight change but you may have some false sends due to the power supply not being completely clean causing some oscillations in the pot values. It may also be weird round off errors from the division by 8 (just a second guess, I don’t know for sure). Your experience may differ.

So, how are the messages built and sent? First build this schematic to the arduino (just the midi connector part):

This is provided by Tom Igoe. Check out this link for more. Now the software side:

void sendMidi(byte controlNum, byte val) {
   Serial.print(0xB0, BYTE);
   Serial.print(controlNum, BYTE);
   Serial.print(val, BYTE);
}

The first byte sent is 0xB0 (176, DEC) which is the HEX value to tell the MIDI device that the next bytes will make up a control change message. MIDI is best read in HEX format because there are 16 of everything so it all fits in neat labeled packages. For example, the different control change “control numbers” in HEX are B0 to BF. It basically maps out so that the first digit represents a type of message and the second represents the “channel” number. Genius protocol. If you still don’t understand but actually care, look here and/or here. The next byte is reserved for the control number. For us, this number will represent which pot the next value belongs to but in a general sense, it represents a “channel”. The next value is simply the value (0-127) being sent.

For the schematic of the pots, I got 6 10K pots and hooked them up in this arrangement. Pin 1 goes to GND, pin 2 goes to an analog pin, and pin 3 goes to 5 volts. This could use a drop resistor but that would take more time. Maybe for something more permanent. Connect these to pins 0-5. I did it like this:

6_pots
The rest of this code is pretty self-explanatory. Let me know if you are confused. I also created a simple max patch (midi_test) that comes in the 6_pot package. Here is a screen-shot:
Max_patch_6_pots
To use it open (File–>MIDI Setup) and change your midi input device to the symbol ‘a’. Then startup your arduino and tweak. Each channel is sent to different oscillators, some saw waves, some sine. The saw waves start at 400 Hz and so do the sine waves. Not too exciting but it is some kind of output. If you don’t have Max you can get the Runtime and run this. Also, if you don’t know how to use Max, turn up the volume by sliding up that vertical slider with your mouse (not all the way!) and hit the speaker button (audio on). Well, that is it for now. Maybe more on this later. I think next time I will talk about getting these values into Processing.