Band Art – Sophia Wan and Stephanie Yip – Eric Parren
Our project band art utilizes the audience’s engagement and creativity to make both sounds and art that the user enjoys. We made our instruments/project self explanatory as most people already know of or have played drums and/or piano before. This way the users most likely know how to play our game without us having to explain it to them and have them test it out themselves as people did during user-testing. Each of the three drums make a different sound as well as each of the seven keys on our piano, this way, the user can remember what the sounds sound like and play something to their liking. Each instrument also corresponds to a different image displayed on the screen so the user can make art to their liking as well. During user testing, everything worked according to plan but some suggestions we got were to make the keys of our piano more sturdy and able to spring back better. Also, since we laser cutted our drums, there was a wood sound when the drumsticks hit the surface of the drums so one idea was to get rid of that. Another was to make the project so that the user can retrieve an image of their artwork after they are done playing. After user-testing, my partner and I worked on making the keys of the piano better, adding rubber bands to the tops of the drumstick to make them sound better and adding a saveImage() feature to our code so that after every minute, an image of the art is saved and can be accessed by the user.
The first thing we struggled with was the basis of our piano and our drums. Since we created the outline for our laser-cutted instruments on our own, we had to make sure that each piece would fit into each other given the kerf. After building our instruments, we struggled first with the drums. Since we were using knock sensors, at times the sensor would be too sensitive to the vibrations such as if there was a knock on the table. To solve this problem, we added a threshold to the sensorValues in Arduino. After we completed the drums, we had to think of a way to create our piano. Our first idea was to use buttons but that was difficult to go-through with since the keys were too wide for the breadboard and didn’t have steady footing since there would have to be wires underneath. Then we created our own makeshift button by soldering wires to copper paper to conduct electricity. This way each time one end of the key touches the bottom of the keyboard, it will send a value to the arduino and play a sound through processing. We wanted to make our keys be able to bounce back like normal piano keys do but we weren’t sure how to go about it. We first tried placing foam tape underneath but it didn’t bounce back like we wanted it to. Then we tried to hot glue springs underneath each key. This worked but it was a little difficult to push down each button and have them return to the same spot. After user testing, we decided to 3-D print tiny cylinders to put on the back of each key and stick a metal rod through all of the keys to make them stay at the same position and stay on the surface of each spring. After finally finishing the structure of our instruments, we then worked on the code. For the drums, each hit would put a splatter paint at a random position and color on the screen. If you hit above a certain sensorValue, you will trigger either a circle or a triangle to appear on the screen. Then for the piano, we place music notes that stay and move each time you play a key.
I think overall our project succeeded in doing what we intended it to do. The user can play around with sound and art and their imagination to the best of their ability without having any prior knowledge to do so. It also aligned with my definition of interaction because it required the audience to be engaged with our project and try to learn about it as they played. It also is satisfying for the musically and visually to use. If I had more time, maybe I would make the piano keys work even better and get the right springs for them this time as well as adding more code for each key to do something different. Overall, this project taught me a lot about using sensors, laser-cutting, 3-D printing and mainly coding from the arduino to processing, adding sound and adding various images.
- APPENDIX
Processing Code:
import processing.serial.*;
import processing.sound.*;
ArrayList<MusicNote> move = new ArrayList<MusicNote>();
Splat splatArray[] = new Splat[0];
Splat splatter;
MusicNote musicnote;
int oldValue = 0;
int m;
Serial serialPort; // Serial port
int NUM_OF_VALUES_FROM_ARDUINO = 10;
int arduino_values[] = new int[NUM_OF_VALUES_FROM_ARDUINO];
int old_arduino_values[] = new int[NUM_OF_VALUES_FROM_ARDUINO];
SoundFile sounds[] = new SoundFile[10]; // Array to store sound files
boolean isPressed = false;
void setup() {
size(1500, 800);
// Load sound files
sounds[0] = new SoundFile(this, “Drum sound 1.wav”);
sounds[1] = new SoundFile(this, “Drum 2.wav”);
sounds[2] = new SoundFile(this, “Drum 3.wav”);
sounds[3] = new SoundFile(this, “do.wav”);
sounds[4] = new SoundFile(this, “re.wav”);
sounds[5] = new SoundFile(this, “mi.wav”);
sounds[6] = new SoundFile(this, “fa.wav”);
sounds[7] = new SoundFile(this, “so.wav”);
sounds[8] = new SoundFile(this, “la.wav”);
sounds[9] = new SoundFile(this, “ti.wav”);
smooth();
//splatter = new Splat();
musicnote = new MusicNote();
serialPort = new Serial(this, “/dev/cu.usbmodem11201”, 9600);
m = millis();
}
void draw() {
getSerialData();
background(255);
musicnote.move();
if (splatArray.length >0) {
for (int k = 0; k<splatArray.length; k++) {
splatArray[k].display();
}
}
// Draw drum pads
//background(255);
if (millis() >= m + 60000) {
saveFrame(“arts-######.png”);
m = millis();
}
//if (arduino_values[0] == 1 && arduino_values[0] != oldValue) {
// int = random(
// sounds[i].play();
// oldValue = arduino_values[0];
// splatter.splats();
//}
for (int i=0; i<NUM_OF_VALUES_FROM_ARDUINO; i++) {
if (arduino_values[i] == 1 && arduino_values[i] != old_arduino_values[i]) {
sounds[i].play();
if (i < 3) {
strokeWeight(0);
//splatter.splats();
float tempX = random(50, 1950);
float tempY = random(50, 950);
float tempR = random(0,255);
float tempG = random(0,255);
float tempB = random(0,255);
for ( float j =3; j < 90; j++) {
splatArray = (Splat[])append(splatArray, new Splat(tempX + cos(random(0, TWO_PI))*2*j,tempY+ sin(random(0, TWO_PI))*3*j,random(0, 50),tempR, tempG, tempB));
//noLoop();
}
} else if (i > 2) {
isPressed = true;
musicnote.Notes();
}
//} else {
// sounds[i].stop();
println(“Got 1”);
}
else if (arduino_values[i] == 2 && arduino_values[i] != old_arduino_values[i]) {
if (i < 3) {
sounds[i].play();
float x = random(width);
float y = random(height);
noFill();
stroke(0);
strokeWeight(random(5, 30));
circle(random(x), random(y), random(80, 150));
triangle(random(x), random(y), random(x+10), random(y+10), random(x+20), random(y+20));
}
println(“Got 2”);
}
old_arduino_values[i] = arduino_values[i];
if (isPressed) {
for (int j = 0; j < 10; j++) {
move.add(new MusicNote());
}
println(“update”);
for (int j = 0; j < 10; j++) {
//move.get(j).display();
move.get(j).move();
}
isPressed = false;
}
}
//old_arduino_values[i] = arduino_values[i];
//if (isPressed){
// for (int j = 0; j < 10; j++){
// move.get(j).display();
// move.get(j).move();
// }
// isPressed = false;
//}
}
class Splat {
float x;
float y;
float rad;
float R;
float G;
float B;
Splat(float tx,float ty,float trad,float tr,float tg,float tb) {
x = tx;
y = ty;
rad = trad;
R = tr;
G = tg;
B = tb;
//x = random(50, 1950);
//y = random(50, 950);
//rad = random(0, 20);
//R = random(0, 255);
//G = random(0, 255);
//B = random(0, 255);
fill(R, G, B);
noStroke();
ellipse(x, y, rad, rad);
//ellipse(x, y, rad, rad);
}
//void splats() {
//x = random(50, 1450);
//y = random(50, 750);
//R = random(0, 255);
//G = random(0, 255);
//B = random(0, 255);
//fill(R, G, B);
//for ( float i =3; i < 90; i++) {
// float angle = random(0, TWO_PI);
// float splatX = x + cos(angle)*2*i;
// float splatY = y + sin(angle)*3*i;
// ellipse(splatX, splatY, rad-i, rad-i+1.8);
// //noLoop();
//}
void display() {
fill(R,G,B);
noStroke();
ellipse(x,y,rad,rad);
}
}
class MusicNote {
// float xPos;
// float yPos;
// float oldxPos;
// float oldyPos;
// float ySpd;
// String[] sample = {“♪”, “♫”}; // array of musical symbols
// int n;
// String note;
// float wordSize;
// MusicNote() {
// xPos = random(width);
// yPos = random(height);
// oldxPos = xPos;
// oldyPos = yPos;
// ySpd = 2;
// n = int(random(0, 1));
// note = sample[n];
// wordSize = random(30, 150);
// }
// void move() {
// if (yPos < height) {
// // yPos += ySpd;
// yPos = yPos+random(-100, 100);
// }
// xPos = xPos + random(-100, 100);
// println(“moving”);
// }
//void display() {
// //background(255);
// fill(0);
// textSize(wordSize);
// text(note, xPos, yPos);
//}
float xs[] = new float[10]; // int[] numbers = new int[3]
float ys[] = new float[10];
String[] sample = {“♪”, “♫”}; // array of musical symbols
String[] notes =new String[10];
MusicNote(){
for(int i=0; i<xs.length; i++){
int n = int(random(0,1));
notes[i] = sample[n];
}
for (int i = 0; i < 10; i++) {
xs[i] = random(width);
ys[i] = random(height);
}
}
void move() {
textSize(random(30, 100));
fill(0);
for (int i = 0; i < 10; i =i+1) {
text(notes[i], xs[i], ys[i]); //todo: notes index
ys[i] = ys[i] + 2;
if (ys[i] > 800) {
ys[i] = 0;
}
}
}
void Notes() {
move();
int index = (int) random(0, 1);
text(notes[index], xs[0], ys[0]);
}
}
void getSerialData() {
while (serialPort.available() > 0) {
String in = serialPort.readStringUntil( 10 ); // 10 = ‘\n’ Linefeed in ASCII
if (in != null) {
//print(“From Arduino: ” + in);
String[] serialInArray = split(trim(in), “,”);
if (serialInArray.length == NUM_OF_VALUES_FROM_ARDUINO) {
for (int i=0; i<serialInArray.length; i++) {
arduino_values[i] = int(serialInArray[i]);
}
}
}
}
}
Arduino Code:
const int sensorPin0 = A0; // Piezo vibration sensor connected to analog pin A0
const int sensorPin1 = A1;
const int sensorPin2 = A2;
void setup() {
Serial.begin(9600); // Start serial communication
}
void loop() {
int sensorValue1 = analogRead(sensorPin0);
int sensorValue2 = analogRead(sensorPin1);
int sensorValue3 = analogRead(sensorPin2); // Read the sensor value
//delay(100); // Delay for stability
if (sensorValue1 > 5) {
Serial.print(1);
} else {
Serial.print(0);
}
Serial.print(“,”);
if (sensorValue2 > 5) {
Serial.print(1);
} else {
Serial.print(0);
}
Serial.print(“,”);
if (sensorValue3 > 5) {
Serial.print(1);
} else {
Serial.print(0);
}
Serial.println();
delay(10);
}
Below is a link for all the photos and videos documented in the process.
https://drive.google.com/drive/folders/1ZXZMz2v9v2aSFbjXWsre3Gf1JIdmYg8t