Final Project 90% Status Update

Idea

As you have read previously, I planned on creating a generative interactive art piece. However, with frequent feedback and suggestions, the idea is now more of a piano with art on screen.  The distance sensor on Arduino helps to identify from where to drop balls from the top and bounce on screen and the potentiometer allows the user to select the color of the balls. As soon as the user moves hands away from the setup, the art form stops with the new production of balls. The sound to be played is dependent on where exactly on the bottom the balls hit.

To stick with a theme, the color palette is defined to be following:

One concern is that the colors on the screen are different from what was printed on the knob. I’m not sure how I can fix this but I hope it is not a big issue.

The tunes were collected as samples but still require some more work to have a better general music sound. The overall interaction design (that includes a bigger circuit wiring and piano theme cardboard layout) is still under process.

 

User Testing

Feedback

  • add different shapes (will try and depending on better aesthetic will finalize)
  • allow for faster response
  • better positioning of distance sensor
  • fun to play

 

Code

//Main Project Processing File
//Serial connection and sound
import processing.serial.*;
import processing.sound.*;
Serial myPort;

//variables for color mapping
int count = 400;
float radToDeg = 180.0 / PI;
float countToRad = TWO_PI / float(count);
float currentcolor;
float Xslider;

boolean playing = false;
boolean fade = false;

//array list for balls
ArrayList<Ball> balls;

//sounds
SoundFile[] files;
int numsounds = 10;


void setup() {
  fullScreen();
  //size(800,600);
  noStroke();
  frameRate(25);
  
  //port communication
  String portname=Serial.list()[0];
  myPort = new Serial(this,portname,9600);
  
  // Create an empty ArrayList (will store Ball objects)
  balls = new ArrayList<Ball>();
  
  //sounds
  files = new SoundFile[numsounds];
  for (int i = 0; i < numsounds; i++) {
    files[i] = new SoundFile(this, (i) + ".wav");
  };
  colorMode(HSB,360,99,99);
    
}

void draw() {
  background(0,0,99);
  if(frameCount%30==0 && fade == false){
    addBalls(7);
  }
  
  for (int i = balls.size()-1; i >= 0; i--) { 
    Ball ball = balls.get(i);
    ball.move();
    ball.display();
    if(ball.x <= Xslider-width/5 || ball.x >= Xslider+width/5 || fade==true){
      if(ball.life > 200){
        ball.life = 150;
        
      }
    }
    if(ball.y >= height){
      int numsound = int(map(ball.x,0,width,0,9));
      playSounds(numsound);
    }
    if (ball.finished()) {
      balls.remove(i);
    } 
  }
}

void playSounds(int numsound){
  if(numsound>=0 && numsound<=9 && !files[numsound].isPlaying() ){
    files[numsound].play();
  }
  for(int i=0;i<10;i++){
    if(files[i].isPlaying() && i!=numsound){
      if(frameCount%20==0){
        files[i].stop();
      }  
    }
  }
}

void addBalls(int count) {
  // A new set of x ball objects are added to the ArrayList
  for(int i=0; i<count; i++){
    float randomS = random(3,10);
    float ballWidth = random(4,30);
    float xPos = random(Xslider-width/10, Xslider+width/10);
    float yPos = random(-100,0);
    float angle = currentcolor * countToRad;
    int hue = int(angle * radToDeg);
    balls.add(new Ball(xPos, yPos, ballWidth,randomS,hue));
  }
}

//Serial Communication
void serialEvent(Serial myPort){
  String s=myPort.readStringUntil('\n');
  s=trim(s);
  if (s!=null){
    
    int values[]=int(split(s,','));
    if (values.length==2){
      currentcolor = map(values[0],0,1023,290,380);
      if(values[1]>150 && values[1]<1700){
        fade= false;
        Xslider= map(values[1],150,1700,width, 0);
      }
      else{
        fade = true;
      }
    }
  }
}
// Simple bouncing ball class

float noiseScale = 700;


class Ball {
  
  float x;
  float y;
  float speed;
  float gravity;
  float w;
  float life = 370;
  int colorhue;
  boolean bounced= false;
  
  Ball(float tempX, float tempY, float tempW, float tempS, int hue) {
    x = tempX;
    y = tempY;
    w = tempW;
    speed = tempS;
    colorhue = hue;
    gravity = 0.1;
  }
  
    void move() {
    // Add gravity to speed
    speed = speed + gravity;
    // Add speed to y location
    y = y + speed;
    float noiseVal = noise(x*noiseScale);
    int sign;
    if(Xslider<width/2){
      sign = -1;
    }
    else{
      sign = 1;
    }
    noiseVal = sign * noiseVal;
    
    // If ball reaches the bottom
    // Reverse speed
    if (y > height) {
      // Dampening
      speed = speed * -0.9;
      y = height;
      bounced = true;
    }
    
    if(bounced==true){
      x = (noiseVal+x);
    }
    if(bounced==true && y<=10){
      // Dampening
      speed = speed * -0.9;
      y = 10;
      bounced = false;
    }
  }
  
  boolean finished() {
    // Balls fade out
    life--;
    if (life < 0) {
      return true;
    } else {
      return false;
    }
  }
  
  void display() {
    // Display the circle
    fill(color(colorhue,99,99),life);
    ellipse(x,y,w,w);
  }
}
//Arduino Code
int trigger_pin = 2;
int echo_pin = 3;
long pulse_duration;

void setup() {
  Serial.begin(9600);
  pinMode(trigger_pin, OUTPUT);
  pinMode(echo_pin, INPUT);
  digitalWrite(trigger_pin, LOW);
  Serial.println("0,0");
}

void loop() {
  int sensor = analogRead(A0);
  digitalWrite(trigger_pin, HIGH);
  digitalWrite(trigger_pin, LOW);
  pulse_duration = pulseIn(echo_pin, HIGH);
  Serial.print(sensor);
  Serial.print(',');
  Serial.println(pulse_duration);
}

 

Leave a Reply