Lab submission 5 - Piezo speaker

Submitted by stlim on Tue, 03/05/2013 - 21:24

Description

I made a mini-violin using piezo speaker, potentiometer, and three photocells. The program has two modes of play: manual mode and assisted mode. In the manual mode, the user's fingerings of binary combinations (0 to 7) on the three photocells make different pitches of the sound. In assisted mode, a processing code decides pitches of the sound based on a musical piece. The program has pitch data of parsed MIDI file so that it sequentially output the value according to the user's input.

 

Video Demo

http://youtu.be/Rvw5ZGnuzOY

 

 

Components Used

- 3 10k ohm resistors
- 3 photocells
- 1 piezo speaker
- 1 Arduino Uno board
 

Arduino Code: Mini-violin

 

 

int PHOTO_THRESHOLD = 700;
int SPEAKER_CYCLE = 3;
 
int photoPin1 = 0;
int photoPin2 = 1;
int photoPin3 = 2;
 
int photoVal1 = 0;
int photoVal2 = 0;
int photoVal3 = 0;
int binaryVal = 0;
 
int potVal = 0;
int oldPotVal = 0;
int potPin = 4;
boolean wasHigh = true;
boolean started = false;
 
int speakerPin = 7;
 
const int tones[] = {1915, 1700, 1519, 1432, 1275, 1136, 1014, 956};
const int vivaldi[] = {0, 0, 0, 0, 803, 536, 601, 637, 715, 803, 715, 1072, 1072, 601, 637, 715, 803, 851, 601, 601, 637, 637, 715, 637, 601, 536, 477, 425, 803, 715, 637, 601, 536, 477, 851, 803, 715, 637, 601, 536, 955, 851, 803, 715, 637, 803, 851, 1072, 1136, 1072, 715, 1072, 1136, 1072, 637, 1072, 1136, 1072, 568, 715, 803, 715, 536, 1072, 536, 536, 568, 637, 715, 803, 851, 955, 1072, 955, 851, 955, 851, 955, 851, 955, 851, 955, 851, 955, 851, 955, 851, 955, 851, 955, 851, 955, 851, 955, 851, 955, 851, 955, 851, 955, 851, 1072, 1072, 1072, 715, 803, 851, 955, 1072, 955, 1431, 1431, 803, 851, 955, 1072, 1136, 803, 803, 851, 1072, 601, 637, 715, 803, 851, 601, 601, 637, 637, 955, 851, 803, 715, 637, 601, 851, 803, 715, 637, 601, 536, 803, 715, 637, 601, 536, 477, 851, 851, 803, 715, 851, 955, 1072, 637, 601, 536, 637, 715, 1072, 851, 803, 715, 851, 955, 1072, 637, 601, 536, 637, 715, 1072, 715, 536, 637, 715, 803, 851, 803, 851, 803, 851, 803, 851, 803, 851, 803, 803, 955, 601, 637, 715, 758, 715, 955, 601, 637, 715, 758, 715, 955, 601, 637, 715, 758, 715, 955, 601, 637, 715, 758, 715, 955, 901, 955, 1072, 955, 901, 1431, 901, 955, 1072, 955, 901, 1431, 901, 955, 1072, 955, 901, 1431, 901, 955, 1072, 955, 901, 1431, 1275, 1203, 1275, 1203, 1431, 955, 901, 803, 901, 803, 955, 715, 637, 601, 637, 601, 715, 601, 477, 536, 601, 536, 477, 715, 477, 536, 601, 536, 477, 715, 450, 477, 536, 477, 450, 715, 450, 477, 536, 477, 450, 715, 477, 536, 601, 536, 477, 715, 477, 536, 601, 536, 477, 715, 450, 477, 536, 477, 450, 715, 450, 477, 536, 477, 450, 477, 715, 536, 601, 637, 715, 758, 851, 955, 851, 758, 715, 637, 601, 536, 601, 637, 715, 758, 851, 955, 851, 758, 715, 637, 601, 536, 601, 637, 601, 637, 715, 536, 601, 637, 601, 637, 715, 536, 601, 637, 601, 601, 601, 568, 568, 568, 536, 536, 536, 506, 506, 506, 477, 477, 477, 477, 477, 477, 477, 477, 477, 477, 477, 477, 536, 536, 536};
const int IDLE = 0, MANUAL = 1, ASSISTED = 2, COLLABORATIVE = 3;
int command;
 
int count = 0;
 
void setup() {
  pinMode(potPin, INPUT);
  pinMode(speakerPin, OUTPUT);
  Serial.begin(9600);
  command = -100;
}
 
void loop() {
  while(Serial.available() > 0){
    
    command = Serial.read();
    
    if(command==IDLE) {
      
    }
    else if(command==MANUAL) {
      //  read fingering
      photoVal1 = analogRead(photoPin1) > PHOTO_THRESHOLD ? 1 : 0;
      photoVal2 = analogRead(photoPin2) > PHOTO_THRESHOLD ? 1 : 0;
      photoVal3 = analogRead(photoPin3) > PHOTO_THRESHOLD ? 1 : 0;
      binaryVal = 4*photoVal1 + 2*photoVal2 + 1*photoVal3;
      
      //  make sound if MANUAL mode
      for(int i=0;i<SPEAKER_CYCLE;i++) {
        digitalWrite(speakerPin, HIGH);
        delayMicroseconds(tones[binaryVal]);
        digitalWrite(speakerPin, LOW);
        delayMicroseconds(tones[binaryVal]);
      }
    }
    else {  //  assisted mode
      potVal = analogRead(potPin) / 128;
      
      if(!started && potVal<6 && wasHigh) started = true;
      
        if(started && potVal<6 && wasHigh) {
          wasHigh = false;
          Serial.println('r');  //  request new pitch
          delay(2);
        }
        else if(started && potVal>6 && !wasHigh) {
          wasHigh = true;
          Serial.println('r');  //  request new pitch
          delay(2);
        }
        
        if(started)
          for(int i=0;i<SPEAKER_CYCLE;i++) {
            digitalWrite(speakerPin, HIGH);
            delayMicroseconds(vivaldi[command]);
            digitalWrite(speakerPin, LOW);
            delayMicroseconds(vivaldi[command]);
          }
    }
  }
}
 

Processing Code: Mini-violin

 

 

import processing.serial.*;
 
String portname = "/dev/tty.usbmodem411";
Serial port;
 
int state;
final int IDLE = 0, MANUAL = 1, ASSISTED = 2, COLLABORATIVE = 3;
 
float buttonWidth = 280;
float buttonHeight = 120;
float buttonRound = 5;
int buttonR = 200, buttonG = 255, buttonB = 120;
int bgR = 0x40, bgG = 0x40, bgB = 0x40;
 
//int tones[] = {1915, 1700, 1519, 1432, 1275, 1136, 1014, 956};
String[] vivaldi = {"", "", "", "", "D#5", "A#5", "G#5", "G5", "F5", "D#5", "F5", "A#4", "A#4", "G#5", "G5", "F5", "D#5", "D5", "G#5", "G#5", "G5", "G5", "F5", "G5", "G#5", "A#5", "C6", "D6", "D#5", "F5", "G5", "G#5", "A#5", "C6", "D5", "D#5", "F5", "G5", "G#5", "A#5", "C5", "D5", "D#5", "F5", "G5", "D#5", "D5", "A#4", "A4", "A#4", "F5", "A#4", "A4", "A#4", "G5", "A#4", "A4", "A#4", "A5", "F5", "D#5", "F5", "A#5", "A#4", "A#5", "A#5", "A5", "G5", "F5", "D#5", "D5", "C5", "A#4", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "C5", "D5", "A#4", "A#4", "A#4", "F5", "D#5", "D5", "C5", "A#4", "C5", "F4", "F4", "D#5", "D5", "C5", "A#4", "A4", "D#5", "D#5", "D5", "A#4", "G#5", "G5", "F5", "D#5", "D5", "G#5", "G#5", "G5", "G5", "C5", "D5", "D#5", "F5", "G5", "G#5", "D5", "D#5", "F5", "G5", "G#5", "A#5", "D#5", "F5", "G5", "G#5", "A#5", "C6", "D5", "D5", "D#5", "F5", "D5", "C5", "A#4", "G5", "G#5", "A#5", "G5", "F5", "A#4", "D5", "D#5", "F5", "D5", "C5", "A#4", "G5", "G#5", "A#5", "G5", "F5", "A#4", "F5", "A#5", "G5", "F5", "D#5", "D5", "D#5", "D5", "D#5", "D5", "D#5", "D5", "D#5", "D5", "D#5", "D#5", "C5", "G#5", "G5", "F5", "E5", "F5", "C5", "G#5", "G5", "F5", "E5", "F5", "C5", "G#5", "G5", "F5", "E5", "F5", "C5", "G#5", "G5", "F5", "E5", "F5", "C5", "C#5", "C5", "A#4", "C5", "C#5", "F4", "C#5", "C5", "A#4", "C5", "C#5", "F4", "C#5", "C5", "A#4", "C5", "C#5", "F4", "C#5", "C5", "A#4", "C5", "C#5", "F4", "G4", "G#4", "G4", "G#4", "F4", "C5", "C#5", "D#5", "C#5", "D#5", "C5", "F5", "G5", "G#5", "G5", "G#5", "F5", "G#5", "C6", "A#5", "G#5", "A#5", "C6", "F5", "C6", "A#5", "G#5", "A#5", "C6", "F5", "C#6", "C6", "A#5", "C6", "C#6", "F5", "C#6", "C6", "A#5", "C6", "C#6", "F5", "C6", "A#5", "G#5", "A#5", "C6", "F5", "C6", "A#5", "G#5", "A#5", "C6", "F5", "C#6", "C6", "A#5", "C6", "C#6", "F5", "C#6", "C6", "A#5", "C6", "C#6", "C6", "F5", "A#5", "G#5", "G5", "F5", "E5", "D5", "C5", "D5", "E5", "F5", "G5", "G#5", "A#5", "G#5", "G5", "F5", "E5", "D5", "C5", "D5", "E5", "F5", "G5", "G#5", "A#5", "G#5", "G5", "G#5", "G5", "F5", "A#5", "G#5", "G5", "G#5", "G5", "F5", "A#5", "G#5", "G5", "G#5", "G#5", "G#5", "A5", "A5", "A5", "A#5", "A#5", "A#5", "B5", "B5", "B5", "C6", "C6", "C6", "C6", "C6", "C6", "C6", "C6", "C6", "C6", "C6", "C6", "A#5", "A#5", "A#5"};
 
int index = 4;
int val = 0;
 
void setup() {
  size(displayWidth, displayHeight);
  frameRate(30);
  smooth();
  noStroke();
  textSize(40);
  
  //  draw three buttons
  colorMode(RGB, 255);
  
  //  set current state
  state = IDLE;
  
  //  open serial port
  port = new Serial(this, portname, 9600);
}
 
void draw() {
  
  drawUI();
  play();
}
 
void play() {
  switch(state) {
    case IDLE:
      port.write(IDLE);
      break;
    case MANUAL:
      port.write(MANUAL);
      break;
    case ASSISTED:
      port.write(index);
      break;
    /*case COLLABORATIVE:
      port.write(index);
      break;*/
    default:
      break;
  }
}
 
void drawUI() {
  background(bgR, bgG, bgB);
  
  switch(state) {
    case IDLE:
      bgR = 0x40;
      bgG = 0x40;
      bgB = 0x40;
      break;
    case MANUAL:
      bgR = 0x50;
      bgG = 0x40;
      bgB = 0x40;
      fill(buttonR, buttonG, buttonB, 180);
      rect((displayWidth-buttonWidth*4)/2,
      (displayHeight-buttonHeight)/2+buttonHeight*1.1,
      buttonWidth,
      buttonHeight/5,
      buttonRound);
      break;
    case ASSISTED:
      bgR = 0x40;
      bgG = 0x50;
      bgB = 0x40;
      fill(buttonR, buttonG, buttonB, 255);
      rect((displayWidth-buttonWidth)/2,
      (displayHeight-buttonHeight)/2+buttonHeight*1.1,
      buttonWidth,
      buttonHeight/5,
      buttonRound);
      fill(255, 255, 255, 255);
//      text("val = " + val, 100, 250);
      break;
    /*case COLLABORATIVE:
      bgR = 0x40;
      bgG = 0x40;
      bgB = 0x50;
      fill(buttonR, buttonG, buttonB, 255);
      rect((displayWidth+buttonWidth*2)/2,
      (displayHeight-buttonHeight)/2+buttonHeight*1.1,
      buttonWidth,
      buttonHeight/5,
      buttonRound);
      break;*/
    default:
      break;
  }
  
  //  manual mode button
  fill(buttonR, buttonG, buttonB, 180);
  rect((displayWidth-buttonWidth*4)/2,
  (displayHeight-buttonHeight)/2,
  buttonWidth,
  buttonHeight,
  buttonRound);
  fill(bgR, bgG, bgB);
  text("manual",
  (displayWidth-buttonWidth*4)/2 + 70,
  displayHeight/2 + 10);
  
  //  assisted mode button
  fill(buttonR, buttonG, buttonB, 255);
  rect((displayWidth-buttonWidth)/2,
  (displayHeight-buttonHeight)/2,
  buttonWidth,
  buttonHeight,
  buttonRound);
  fill(bgR, bgG, bgB);
  text("assisted",
  (displayWidth-buttonWidth)/2 + 60,
  displayHeight/2 + 10);
  
  //  collaborative mode button
  /*fill(buttonR, buttonG, buttonB, 255);
  rect((displayWidth+buttonWidth*2)/2,
  (displayHeight-buttonHeight)/2,
  buttonWidth,
  buttonHeight,
  buttonRound);
  fill(bgR, bgG, bgB);
  text("collaborative",
  (displayWidth+buttonWidth*2)/2 + 15,
  displayHeight/2 + 10);*/
}
 
void mouseClicked() {
  if((displayWidth-buttonWidth*4)/2<mouseX
  && mouseX<(displayWidth-buttonWidth*4)/2+buttonWidth
  && (displayHeight-buttonHeight)/2<mouseY
  && mouseY<(displayHeight-buttonHeight)/2+buttonHeight
  ) {
    state = MANUAL;
  }
  else if((displayWidth-buttonWidth)/2<mouseX
  && mouseX<(displayWidth-buttonWidth)/2+buttonWidth
  && (displayHeight-buttonHeight)/2<mouseY
  && mouseY<(displayHeight-buttonHeight)/2+buttonHeight
  ) {
    state = ASSISTED;
    index = 3;
  }
  /*else if((displayWidth+buttonWidth*2)/2<mouseX
  && mouseX<(displayWidth+buttonWidth*2)/2+buttonWidth
  && (displayHeight-buttonHeight)/2<mouseY
  && mouseY<(displayHeight-buttonHeight)/2+buttonHeight
  ) {
    state = COLLABORATIVE;
    index = 4;
  }*/
  else {
    state = IDLE;
  }
}
 
void serialEvent(Serial p) {
  val = port.read();
  
  if(val=='r') {
    index++;
  }
  
  index = index % vivaldi.length;
}
0
Your rating: None
Drupal theme by Kiwi Themes.