Arduino MIDI controller

A project that I’ve been working will use ultrasonic range finders to determine the locations of people in a space to send MIDI signals back to Ableton Live to trigger tracks of sound. This prototype sends one of four byte strings that make up a MIDI controller command, based on the distance from the sensor. It’s made up of an Arduino, a Maxbotix EZ1, a MIDI to USB cable and some RGB LEDs for visual feedback.

Arduino MIDI Controller

Simply put, if you’re within 8 inches of the sensor, one measure of music on the computer plays and the LEDs show one color. Greater than 16 inches, a different measure plays and the LEDs change to a different color. More than 24 inches away from the sensor and you get yet a different measure of music and color on the rgb LEDs. In the end I hope to scale the spatial awareness of this to intervals within 10 feet, with the LEDs lighting 1′x2′ plexiglass panels with the sensors mounted below the panels, facing into a space.

For now, here’s some Arduino code if anybody’s interested in playing with it:

/*

CTYSND - a spatial musical instrument
Author: Jay Pozo

http://www.jaymatter.com

December 2009

for more info about MIDI messages, go here:

http://www.midi.org/techspecs/midimessages.php

*/

// data pin for the range finder sensor
const int sensorPin1 = 6;

byte firstNote = 0x01;
byte secondNote = 0x02;
byte thirdNote = 0x03;

// commandByte: 0x90 is a note
// 0xB1 is a controller change on channel 2
byte commandByte = 0xB1;

// the third byte sends the velocity. In this case, 0x7F is max of 127
byte thirdByte = 0x7F;
byte lastNotePlayed;

long sensor1Pulse;
long distance1; // in inches

// pins for the colored led panels
// this will have to change later, probably through a shift register to support 8 sets of LEDs
int redPin1 = 9;
int greenPin1 = 10;
int bluePin1 = 11;

// our ranges, in inches
int rangeStart = 0;
int rangeStep1 = 8;
int rangeStep2 = 16;
int rangeStep3 = 24;

void setup() {

Serial.begin(31250);

pinMode(redPin1, OUTPUT);
pinMode(greenPin1, OUTPUT);
pinMode(bluePin1, OUTPUT);

pinMode(sensorPin1, INPUT);
}

void loop() {

sensor1Pulse = pulseIn(sensorPin1, HIGH);
distance1 = sensor1Pulse/147; // distance is in inches (see documentation of sensor for value of 147)

if ( distance1 > rangeStart && distance1 < rangeStep1 )
{
analogWrite(redPin1, 255);
analogWrite(greenPin1, 255);
analogWrite(bluePin1, 255);
if (lastNotePlayed != firstNote)
{
noteOn(commandByte, firstNote, thirdByte);
lastNotePlayed = firstNote;
}

}

if ( distance1 > rangeStep1 && distance1 < rangeStep2 )
{
analogWrite(redPin1, 255);
analogWrite(greenPin1, 0);
analogWrite(bluePin1, 255);
if (lastNotePlayed != secondNote)
{
noteOn(commandByte, secondNote, thirdByte);
lastNotePlayed = secondNote;
}

}

if ( distance1 > rangeStep2 && distance1 < rangeStep3 )
{
analogWrite(redPin1, 255);
analogWrite(greenPin1, 255);
analogWrite(bluePin1, 0);
if (lastNotePlayed != thirdNote)
{
noteOn(commandByte, thirdNote, thirdByte);
lastNotePlayed = thirdNote;
}

}

if (distance1 > rangeStep3 )
{
analogWrite(redPin1, 0);
analogWrite(greenPin1, 0);
analogWrite(bluePin1, 255);

// noteOff();

}

delay(300);
}

void noteOff()
{
Serial.print(0xFC,BYTE);
}

void noteOn(int cmd, int pitch, int velocity) {
Serial.print(cmd, BYTE);
Serial.print(pitch, BYTE);
Serial.print(velocity, BYTE);
}


3 responses so far, want to say something?

  1. Zack says:

    This is awesome! Is this for the project with your friend’s photographs?

    I’m definitely pilfering code to muck around with.

  2. Jay says:

    This is for the other one – turning a physical space into a midi controller. I’ll post the rgb LED panel part of this soon.

  3. Jay says:

    And thanks! :)

Leave a Reply

DSC_4292DSC_2684DSC_4510DSC_0031DSC_3663DSC_3708DSC_3631DSC_3459DSC_3653DSC_3635DSC_7829DSC_2638