Saturday, June 30, 2012

Final Project::: The Self-Motivated Xylophone

For the final project I chose to do a Self-Motivated Xylophone - you hit it once and it will play many notes for you!

https://vimeo.com/45028437

The project was meant to serve as a prototype for a larger installation with many of the same technical aspects. Basically what it should look like when it's completely done is a deconstructed and interactive tongue drum that will respond to some physical input and play all around the installation. Since a xylophone is also percussive and melodic I thought it would be a great chance to test out the technical aspects and see what kind of issues I would run into both with a smaller scale project like this and then keeping in mind the foreseeable challenges of trying to apply these concepts to a larger scale. 

This is a tongue drum 

The way this works is that there are six piezo pickups on the bottom of the keys on the xylophone that are programmed in a way that enables them to recognize when they are being hit and then play a unique sequence associated with that piezo. All of the piezos and solenoids are linked to notes within C major making any note hit (that is not sharp or flat aka on the upper shelf) sound good with each other. You can also play notes while a sequence is running as well to complement the sequence that is being played. 




The biggest problems I ran into were basic power and resistor errors (that were easily fixed with some help) and then not fully understanding the algebraic function that allows the xylophone to play all the numbers in the sequence. Once figuring that out I was able to program all the solenoids to have different sequences and accurately program the piezos to respond to a hit.

Here's the code I wrote


int piezo1 = A0;
int piezo2 = A1;
int piezo3 = A2;
int piezo4 = A3;
int piezo5 = A4;
int piezo6 = A5;
int piezo1Value=0;
int piezo2Value=0;
int piezo3Value=0;
int piezo4Value=0;
int piezo5Value=0;
int piezo6Value=0;


//SEQUENCE 1
int sequence1[] = {
3 , 4 , 6 , 8, 5, 11, 2, 5, 11, 2, 5, 11, 2, 6, 6, 5 ,4, 7, 7, 8, 11, 10, 9, 11, 10, 9, 3 , 4 , 6 , 8, 5, 11, 2, 5, 11, 2, 5, 11, 2, 6, 6, 5 ,4, 7, 7, 8, 11, 10, 9, 11, 10, 9};
//52 values
int delays1[] = {
20, 20, 20, 25, 30, 30, 30, 25, 100, 50, 30, 30, 30, 20, 100, 25, 30, 90, 90, 25, 100, 25, 30, 30, 30, 25, 20, 20, 20, 25, 30, 30, 30, 25, 100, 50, 30, 30, 30, 20, 100, 25, 30, 90, 90, 25, 100, 25, 30, 30, 30, 25
};

//SEQUENCE 2
int sequence2[] = {
11, 10, 8, 3, 4, 5, 2, 6, 7, 2, 4, 6, 7, 8, 8, 2, 11, 7, 6, 2, 5, 4, 9, 3, 8, 7, 6, 3, 11, 9, 4, 5, 6, 4, 8, 5, 6, 11, 10, 8, 4, 2, 11, 3, 4, 2, 4, 5, 7, 3};
//52 values
int delays2[] = {
60, 80, 60, 20, 60, 80, 20, 20, 60, 80, 60, 100, 20, 30, 50, 60, 80, 20, 20, 60, 80, 20, 100, 20, 80, 20, 25, 30, 40, 50, 60, 80, 20, 40, 60, 80, 40, 20, 60, 80, 100, 20, 30, 40, 50, 20, 20, 100, 60, 60
};

//SEQUENCE 3
int sequence3[] = {
4, 2, 11, 11, 6, 5, 4, 8, 8, 8, 10, 12, 11, 10, 12, 11, 5, 8, 7, 3, 3, 11, 2, 11, 3, 11, 4, 8, 6 , 8, 5, 11, 2, 5, 11, 2, 5, 11, 2, 6, 6, 5 ,4, 7, 7, 8, 11, 10, 9, 11, 2};
//52 values
int delays3[] = {
60, 80, 200, 200, 60, 80, 200, 200, 60, 80, 100, 150, 30, 40, 50, 60, 80, 20, 200, 60, 80, 20, 200, 60, 80, 100, 20, 30, 40, 50, 60, 80, 20, 150, 60, 80, 20, 200, 60, 80, 100, 150, 30, 40, 50, 20, 20, 100, 60, 60, 20};

//SEQUENCE 4
int sequence4[] = {
10, 11, 4 , 8, 9, 10, 2, 5, 12, 10, 3, 4, 2, 6, 6, 5 ,2, 7, 4, 8, 5, 2, 9, 11, 10, 9, 10, 11, 4 , 8, 9, 10, 2, 5, 12, 10, 3, 4, 2, 6, 6, 5 ,2, 7, 4, 8, 5, 2, 9, 11, 10, 9};
//52 values
int delays4[] = {
20, 20, 20, 25, 30, 30, 100, 25, 10, 20, 20, 20, 30, 60, 10, 20, 30, 80, 100, 70, 70, 100, 30, 100, 100, 70, 20, 20, 20, 25, 30, 30, 100, 25, 10, 20, 20, 20, 30, 60, 10, 20, 30, 80, 100, 70, 70, 100, 30, 100, 100, 70
};

//SEQUENCE 5
int sequence5[] = {
3 , 4 , 6 , 8, 5, 11, 2, 5, 11, 2, 5, 11, 2, 6, 6, 5 ,4, 7, 7, 8, 11, 10, 9, 11, 10, 9, 3 , 4 , 6 , 8, 5, 11, 2, 5, 11, 2, 5, 11, 2, 6, 6, 5 ,4, 7, 7, 8, 11, 10, 9, 11, 10, 9};
//52 values
int delays5[] = {
60, 80, 60, 20, 60, 80, 20, 20, 60, 80, 60, 20, 30, 25, 20, 10, 60, 80, 60, 80, 150, 20, 150, 20, 30, 20, 60, 80, 60, 20, 60, 80, 20, 20, 60, 80, 60, 20, 30, 25, 20, 10, 60, 80, 60, 80, 150, 20, 150, 20, 30, 20
};

//SEQUENCE 6
int sequence6[] = {
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 2, 2, 5, 6, 8, 10, 12, 11, 4, 3, 6, 9, 11, 5, 7, 4, 8, 2, 9, 5, 4, 10, 11, 8, 7, 7, 6, 3, 5};
//40 values
int delays6[] = {
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 100, 200, 300, 400, 500, 60, 80, 200, 200, 60, 80, 200, 200, 60, 80, 100, 200, 300, 400, 500, 60, 80, 200, 200, 60, 80, 200, 200, 60, 80};


void setup(){

  for(int i = 2; i < 11 ; i++) {
    pinMode(i, OUTPUT);
  }
  Serial.begin(9600);

}


void loop(){

  //PIEZO 1 - is on low d
  piezo1Value = analogRead(piezo1);
  //Serial.println(piezo1Value);
  if(piezo1Value >200){
    for(int i = 0; i < 51 ; i++) {
      digitalWrite(sequence1[i], HIGH);
      delay(20);
      digitalWrite(sequence1[i], LOW);
      delay(delays1[i]);
    }
  }
 
//PIEZO 2
//is on g
piezo2Value = analogRead(piezo2);
//Serial.println(piezo2Value);
  if(piezo2Value>200){
    for(int i = 0; i < 51 ; i++) {
      digitalWrite(sequence2[i], HIGH);
      delay(20);
      digitalWrite(sequence2[i], LOW);
      delay(delays2[i]);
    }
  }
 
//PIEZO 3
//on middle c
piezo3Value = analogRead(piezo3);
//Serial.println(piezo3Value);
  if(piezo3Value>1000){
    for(int i = 0; i < 51 ; i++) {
      digitalWrite(sequence3[i], HIGH);
      delay(20);
      digitalWrite(sequence3[i], LOW);
      delay(delays3[i]);
    }
  }
 
//PIEZO 4 - is on high c
piezo4Value = analogRead(piezo4);
 //Serial.println(piezo4Value);
  if(piezo4Value>300){
    for(int i = 0; i < 51 ; i++) {
      digitalWrite(sequence4[i], HIGH);
      delay(20);
      digitalWrite(sequence4[i], LOW);
      delay(delays4[i]);
    }
  }

//PIEZO 5
//on low c
piezo5Value = analogRead(piezo5);
Serial.println(piezo5Value);
  if(piezo5Value>950){
    for(int i = 0; i < 51 ; i++) {
      digitalWrite(sequence5[i], HIGH);
      delay(20);
      digitalWrite(sequence5[i], LOW);
      delay(delays5[i]);
    }
  }
 
//PIEZO 6 - I USED ONE LESS THAN 40 BECAUSE 0 COUNTS AS A NUMBER IN WEIRD MATH LANGUAGE - same with all of them!
//on high E
piezo6Value = analogRead(piezo6);
//Serial.println(piezo6Value);
  if(piezo6Value>600){
    for(int i = 0; i < 39 ; i++) {
      digitalWrite(sequence6[i], HIGH);
      delay(20);
      digitalWrite(sequence6[i], LOW);
      delay(delays6[i]);

    }

  }

}


Overall, I'm very pleased with how this project came out and am excited to use these principles in the larger piece!


Saturday, June 23, 2012

Final Project Concept & Progress

For my final project I plan on creating a percussive xylophone that works with you to create melodic and beautiful harmonies and melodies. The idea is that certain notes trigger a string of notes that are in the same key as the note hit with the mallet. There will be piezo pickups taped to the bottom of the keys that will trigger a series of solenoids to perform their dance.

So far I've run into a few coding issues with testing on LEDs...

The following code represents progress thus far and issues I've been having with:
  • creating a threshold that disables sensors from being read beyond that threshold 
  • LEDs starting 'HIGH' rather than 'LOW' thus reversing the order of how it is lit 
  • general troubleshooting with Serial Monitor values.


This is how it performs with the above code:
 

I used a FSR instead of a piezo for this example as well. Currently waiting on the rest of the parts, can't wait to try it out with actual solenoids! 



Friday, June 22, 2012

H Bridge Lab

H Bridges allow the motor to spin in two directions! I wish I had taped something to the axel to better visualize it. The switch controls the direction. 

Tuesday, June 19, 2012

Stupid Pet Trick



After getting a makeover, the Stupid Pet Trick had it's seamless debut in class. The discussion provided a glimpse into user perspective and reasoning behind the interface. For us it was a playful way to explore these technologies in an interesting way, but perhaps if fully fleshed out into a bigger project more thought and consideration to design and purpose would be necessary in order for it to be effective and meaningful to someone experiencing it.

Multiple Serial Output Lab



All types of data!



Reading data from the sensor


Hello! 


What happens when you enter data into the Serial Monitor


Was unable to get Processing to make the ball appear. Not sure what the issue was since I was reading data from the sensors. Will try to figure out where I went wrong before the end of class!

Monday, June 18, 2012

Serial Out Lab

ASCII Characters! Arduino 'writes' serially in ASCII (instead of translating) and 'reads' serially in numbers we can understand



Hex Characters in CoolTerm!


 How to identify all serial ports available on the machine in Processing

 Graphing via Processing, so satisfying!


This lab was the way we've communicated serially and opened up a conversation between the Arduino and the computer. As we move on this is going to be an insane and awesome tool to use!

Tuesday, June 12, 2012

Tone Output Lab



FSR Controlled Piezo Pitches


Musical Instrument


Best Song Ever



These were super fun. Definitely going to use these concepts to create interesting noise projects in the future! 

Servo/Analog Out Lab

Servo Controlled with Flex Sensor

Saturday, June 9, 2012

Stupid Pet Trick::: Prototype

IT WORKS!

It took us a few minutes to figure out how to use the same value (from one flex sensor) to send to two different servo motors, but then we figured it out! Other issues we encountered were really minor, ie. taping wires together, hooking up a flex sensor test incorrectly, etc.

Here's the code we are using and a video of the prototype: