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.

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);
}