Final Project – Soundbox of Light – Charlene Kulesa

19 Dec

IMG_1670 IMG_1675 IMG_1694

My project is an interactive installation that tracks light intensity and correlates that data to a specific musical note. Movement is a secondary and indirect component that impacts the sound as it changes the degree of light intensity that is read by the photoresistor sensors. The base of the “soundbox of light” is a repurposed turntable where the record is raised above the turntable arm and has 4 cutout sections on the record that allow the ambient light to pass through to the photoresistor sensor that is attached to the turntable arm. The code is written so that if the light intensity is greater than 500, and the push button for the turntable is turned on, that it will play note 20 (reference the Midi Note Chart for the specific musical note). The record is cut so that the cutout sections are all equidistance and therefore when the turntable is turned on the notes are played as a rhythmic background beat.

The laser harp portion was added to the end of the turntable and the frame that houses the 3 lasers has a hinge that allows the frame to either lay down on top of the turntable or positioned upright when being played. The initial intent was to have a tilt switch sensor that turns on and off the lasers but due to inconsistent readings from the tilt switch I had to default to a push button sensor to turn on and off the lasers. Photoresistor sensors were placed at the base of the frame to align with each laser at the top of the frame.

The laser harp code uses both the direct light from the laser and the ambient light of the room to determine the musical note that is played on the laser harp. If the light intensity was less than 900 that meant that there was a break between the laser and its corresponding photo resistor sensor. This was the baseline that determined whether a note should be played. The actual note and pitch being played is based off of the light intensity. This light intensity decreases and increase as the user’s hand gets closer or farther away from the sensor.. The pitch of the note is dependent on the ambient light of the room and therefore the sound can vary from room to room, even though the code is exactly the same. If it is desired to hard code the exact note to be played depending on the height of the hand that is covering the laser, one could add a range detector and hard code a specific note to the hand location. For this project, I preferred the element of the ambient light as an uncontrolled variable that impacted the sound but I also see the benefit of having more control over the sound and note being played regardless of the ambient light.

Here is the code:

#include

// Constant variables:
int LEDpin = 13; // set LED to pin 13
int laserAPin = 10; // set laserA to pin 10
int laserBPin = 11; // setlaserB to pin 11
int laserCPin = 12; // set laserC to pin 12
int buttonTt = 5; // set turntable button to pin 5
int buttonL = 4; // set laser button to pin 4

// Variables for turntable:
int valTt = 0; // set turntable val to 0
int old_valTt= 0; // set turntable old val to 0
int stateTt =0; // set turntable state to 0

// Variables for lasers:
int valL = 0; // set turntable val to 0
int old_valL= 0; // set turntable old val to 0
int stateL =0; // set turntable state to 0

// Variables for notes:
byte noteA = 0; // The MIDI note value to be played for laserA
byte noteB = 0; // The MIDI note value to be played for laserB
byte noteC = 0; // The MIDI note value to be played for laserC
byte noteTt = 0; // The MIDI note value to be played for Turntable

// Variables for analog values:
int AnalogAValue = 0; // value from analog laserA photosensor
int AnalogBValue = 0; // value from analog laserB photosensor
int AnalogCValue = 0; // value from analog laserC photsensor
int AnalogTtValue = 0; // value from analog turntable sensor

// Software serial:
SoftwareSerial midiSerial(2, 3); // digital pins that we’ll use for soft serial RX & TX

void setup()
{
// Set the states of the I/O pins:
pinMode(LEDpin, OUTPUT);
pinMode (laserAPin, OUTPUT);
pinMode (laserBPin, OUTPUT);
pinMode (laserCPin, OUTPUT);
pinMode (buttonTt, INPUT);
pinMode (buttonL, INPUT);

// Set MIDI baud rate:
Serial.begin(9600);
midiSerial.begin(31250);

}

void loop()
{
// Set logic for turning on and off turntable via button:
valTt = digitalRead(buttonTt); // reads input on turntable button
if ((valTt == HIGH) && (old_valTt == LOW)) // check if val has transitioned
{stateTt = 1 – stateTt; // change state from on to off or vice-versa
delay (10); } // set delay

old_valTt = valTt; // val is now old val, store it

if (stateTt == 1) // check to see if state of turntable button is 1 (on)
{digitalWrite (LEDpin, HIGH); } // if true turn on LED
else { digitalWrite (LEDpin, LOW); } // if false turn off LED

// Set logic for turning on and off lasers via button:
valL = digitalRead(buttonL); // reads input on laser button
if ((valL == HIGH) && (old_valL == LOW)) // check if val has transitioned
{stateL = 1 – stateL; // change state from on to off or vice-versa
delay (10);} // set delay

old_valL = valL; // val is now old val, store it

if (stateL == 1) // check to see if state of laser button is 1 (on)
{
digitalWrite (laserAPin, HIGH); // if true turn on lasers A, B and C
digitalWrite (laserBPin, HIGH);
digitalWrite (laserCPin, HIGH);
}
else // if false turn off lasers A, B and C
{
digitalWrite (laserAPin, LOW);
digitalWrite (laserBPin, LOW);
digitalWrite (laserCPin, LOW);
}

// Set up analog read values:
AnalogAValue = analogRead(1);
AnalogBValue = analogRead(2);
AnalogCValue = analogRead(3);
AnalogTtValue = analogRead(5);

// Define note values:
noteA = (AnalogAValue/21); // A top range is approx 790; this equation equals note 36 (C)
noteB = ((AnalogBValue/15)-1); // B top range is approx 810; this equation equals note 51 ( D#)
noteC = (AnalogCValue/12); // C top range is approx 825; this equation equals note 67 (G)
noteTt = (AnalogTtValue/23);

// Logic that determines when and what note is played:
if ((AnalogAValue < 900) && (stateL == HIGH)) // if laserA sensor value is less than 900
{noteOn(0x90, noteA, 0x35);} // then play noteA at medium velocity

if ((AnalogBValue < 900) && (stateL == HIGH)) // if laserB sensor value is less than 900
{noteOn(0x90, noteB, 0x35);} // then play noteB at medium velocity

if ((AnalogCValue 500) && (stateTt == HIGH)) //
{noteOn(0x90, 0x20, 0x45);}

delay (250); // set delay value
}

// plays a MIDI note.
// cmd is greater than 127, or that data values are less than 127:
void noteOn(byte cmd, byte data1, byte data2)
{
midiSerial.write(cmd);
midiSerial.write(data1);
midiSerial.write(data2);

//prints the values in the serial monitor
Serial.print(“A:”);
Serial.print(AnalogAValue);
Serial.print (“, B:”);
Serial.print (AnalogBValue);
Serial.print (“, C:”);
Serial.print (AnalogCValue);
Serial.print (“, Tt:”);
Serial.print (AnalogTtValue);
Serial.print(“, cmd: “);
Serial.print(cmd);
Serial.print(“, data1: “);
Serial.print(data1);
Serial.print(“, data2: “);
Serial.println(data2);
}

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s