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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//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;
}
}
}
}
//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; } } } }
//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;
      }
    }
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 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);
}
}
// 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); } }
// 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);
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//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);
}
//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); }
//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