Drop the Beat

Submitted by lwang on Sun, 04/21/2013 - 20:45

Description:

We wanted to make a musical instrument we could seemingly touch and manipulate. We liked the idea of somehow touching or interacting with water to produce music. We ended up making a water instrument which is an aquarium of water that can be played by any interaction which creates ripples in the water. In our demo, we are using a water bottle to drip water into the tank. 

The aquarium is rested on top of a styrofoam board. We've embeded six photocell sensors which rest underneath the aquarium. They are attached to 12 alligator wires which are wired to our arduino board. When the photocells detect change in light above a certain threshold, it plays a noise, which is also mapped to a visualization through processing. The ripple generate midi sounds now, which can feed into garage band or any midi synths to create sounds. 

Material:

6 photocell sensors

12 alligator clips

styrofoam board

wires

arbuino board

 

Code:

Processing code:

 

import processing.serial.*;
import themidibus.*;
 
MidiBus myBus; // The MidiBus
 
Timer[] timers = new Timer[6];
int[] counters = new int[6];
  
String portname = "/dev/tty.usbmodemfa131"; ///dev/cu.usbmodemfa131
Serial port;
String buf="";
int cr = 13;  // ASCII return   == 13
int lf = 10;  // ASCII linefeed == 10
 
 
void setup()
{
  //size(400,260);
  size(1280, 800);
  println(Serial.list());
  port = new Serial(this, portname, 9600); 
  port.write("65");
  
  //movies[0].play();
  MidiBus.list();
  //myBus = new MidiBus(this, 0, "");
  myBus = new MidiBus(this, "", 0);
  
  for (int i = 0; i < timers.length; i = i+1) {
    timers[i] = new Timer(400);
    counters[i] = 1;
  }
  noStroke();
  background(0,0,0);
}
 
void draw()
{
    
  for (int i = 0; i < timers.length; i = i+1) {
    if (timers[i].started & timers[i].isFinished()) {
       noteOff(i+1); 
    }
  }
  
  fill(232,255,240, 5);
  rect(0,0, width, height);
  
}
 
void noteOn(int i) {
  
  timers[i-1].start();
  //counters[i-1] += 1;
  myBus.sendNoteOn(0, (i+10) * 5, 150);
  
  draw_note(i);
  
}
 
void draw_note(int i) {
  int row = 2;
  int pos = i;
  
  fill(57, 121, 148);
  if( i > 3 ) {
    row = 1;
    pos = i - 3;
  }
  
  ellipse(width/3 * (pos-1) + width/6, height/4 * row + (width/6 * (row - 1)) , width/6, width/6);
}
 
void noteOff(int i) {
  myBus.sendNoteOff(0, (i+10) * 5, 150);
  timers[i-1].started = false;
  
//  if(counters[i-1] > 1) {
//     counters[i-1] -= 1;
//  }
//  
//  if(counters[i-1] > 10) {
//    counters[i-1] = 0;
//  }
}
 
void keyPressed() {
//  if(key == '1') {
//    myBus.sendNoteOn(0, 60, 127);
//  }
  
  if(key == '1') {
     noteOn(1);
  }
  
  if(key == '2') {
     noteOn(2);
  }
  
  if(key == '3') {
     noteOn(3);
  }
  
  if(key == '4') {
     noteOn(4);
  }
  
  if(key == '5') {
     noteOn(5);
  }
  
  if(key == '6') {
     noteOn(6);
  }
  
}
 
void keyReleased() {
  
//  if(key == '1') {
//    myBus.sendNoteOff(0, 60, 127);
//  }
  
  
  if (keyCode == ENTER) {
    println("Rebase");
    
    port.write(65); 
    
    fill(0);
    rect(0,0, width, height);   
  } 
 
  
}
 
// called whenever serial data arrives
void serialEvent(Serial p) {
  int c = port.read();
 
  if (c != lf && c != cr) {
    buf += char(c);
    // println(buf);
  }
  
  if (c == lf) {
    int val = int(buf);
    //println("val="+val);
    
    if(val < 7) {
     noteOn(val);
     println("play: " + val);
    }else{
     //noteOff(val-6);
     println("pause: " + (val-6));
    }
     
    buf = "";
   
  }
  
}
 
timer:
// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com
 
// Example 10-5: Object-oriented timer
 
class Timer {
 
  int savedTime; // When Timer started
  int totalTime; // How long Timer should last
  
  boolean started = false;
  
  Timer(int tempTotalTime) {
    totalTime = tempTotalTime;
  }
  
  // Starting the timer
  void start() {
    // When the timer starts it stores the current time in milliseconds.
    savedTime = millis(); 
    started = true;
  }
  
  void stop() {
    started = false;
  }
  
  // The function isFinished() returns true if 5,000 ms have passed. 
  // The work of the timer is farmed out to this method.
  boolean isFinished() { 
    // Check how much time has passed
    int passedTime = millis()- savedTime;
    if (passedTime > totalTime) {
      started = false;
      return true;
    } else {
      return false;
    }
  }
}

 

 
Arduino code:
int sensorPin[] = {0,1,2,3,4,5};
int numOfSensor = 6;
 
int sensorBase[] = {300,300,300,300,300,300};
boolean sensorState[] = {false, false, false, false, false, false};
int threshold = 5;
 
void setup() {
  Serial.begin(9600);
  
}
void loop() {
 
  if (Serial.available() > 0 ) {
    base();
  }
 
  for(int i=0; i<numOfSensor; i++) {
    check(i);
  }
}
 
void check(int s) {
  int val = analogRead(sensorPin[s]);    // read the value from the sensor, between 0 - 1024
//  Serial.print(s);
//  Serial.print(": ");
//  Serial.println(val);
  
  
  if (val > sensorBase[s] + threshold) {
    if(sensorState[s] == false){
      Serial.println(s+1);
      sensorState[s] = true;
    }
  }
  else {
    if(sensorState[s] == true) {
      Serial.println(s+7);
      sensorState[s] = false; 
    }
  }
  
  delay(10);
}
 
void base(){
  //Serial.println("base: ");
  for(int i=0; i<numOfSensor; i++) {
    sensorBase[i] = analogRead(sensorPin[i]);
    //Serial.println(sensorBase[i]);
  }
  
  while(Serial.available() > 0) {
   Serial.read();
  }
}
  
IMG_1277.jpg
IMG_1279.jpg
0
Your rating: None
Drupal theme by Kiwi Themes.