piezo.png

diagram:
diagram.png
Inside the Piezo Buzzer
inside.png

Piezo

A Piezo is an electronic device that can both be used to play tones and to detect tones. The normal piezoelectric effect is generating electricity from squeezing a crystal.

Piezos have polarity. Commercial devices usually have a red and a black wire indicating how to plug it to the board. Connect the black one to ground and the red one to the input. You also have to connect a resistor in the range of the Megaohms in parallel to the Piezo element;


Sometimes it is possible to acquire Piezo elements without a plastic housing, then they will just look like a metallic disc and are easier to use as input sensors.
To read a piezo you can just hook it into an analog input, but you need to drain off any voltage with a resistor, or it just builds up.

When the Piezo element is used to detect sound, it is a knock sensor. These converters read a voltage value and transform it into a value encoded digitally. In the case of the Arduino boards, you transform the voltage into a value in the range 0..1024. 0 represents 0 volts, while 1024 represents 5 volts at the input of one of the six analog pins.


The code example will capture the knock and if it is stronger than a certain threshold, it will send the string "Knock!" back to the computer over the serial port. In order to see this text you could either use a terminal program, which will read data from the serial port and show it in a window, or make your own program in e.g. Processing.


 int ledPin = 13;
int piezoPin = 2;

int THRESHOLD = 100;  // set minimum value that indicates a knock

int val = 0;       // variable to store the value coming from the sensor
int t = 0;         // the "time" measured for how long the knock lasts

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(19200);
  Serial.println("ready");      // indicate we're waiting
}

void loop() {
  digitalWrite(ledPin,LOW);     // indicate we're waiting

  val = analogRead(piezoPin);   // read piezo
  if( val >THRESHOLD ) {      // is it bigger than our minimum?
    digitalWrite(ledPin, HIGH); // tell the world
    t = 0;
    while(analogRead(piezoPin) > THRESHOLD) {
      t++;
    } // wait for it to go LOW  (with a little hysteresis)
    if(t>100) {  // cut off the low values because they're noise
      Serial.print("knock! ");
      Serial.println(t);
    }
  }

 
  delay(100);  // make a delay to avoid overloading the serial port
}
 
 


Exercise 2-Motor Pulse

Wire up a Piezo and a motor
int ledPin = 13;
int knockSensor = 0;               
byte val = 0;
int statePin = LOW;
int motor=___;
int THRESHOLD = 100;
int t;

void setup() {
 pinMode(ledPin, OUTPUT); 
 beginSerial(9600);
}

void loop() {
  val = analogRead(knockSensor);     
  if (val >= THRESHOLD) {
  //reverse the state of the pins
    ___________________
    //turn the led on
    ___________________
    
    t=0;
    while(analogRead(knockSensor)>THRESHOLD){
        t++;
    }
    if (t!=0){
     Serial.print("Knock!");
     Serial.print(t);
     analogWrite(motor,100);
     delay(1000);
     analogWrite(motor,0);
  }
 }
 
}


Exercise 3-Get Creative

You can mount the element on anything (under rugs, floor mat, door, your body, etc.)

This one is glued to a larger brass disc for a drum trigger.



Hook a piezo up to something, connect with Processing. Every time someone knocks on your object, play a sound!
Playing Sounds in Processing
import ddf.minim.*;
import processing.serial.*;

String portname = "________________";  // get portame
Serial port;  // Create object from Serial class

AudioSample sounds[];

//list your sounds and import them into processing
String sound_names[] = 
{
  ________,
 ________,
  ________,
  ________,
  ________,
  ________
};

void setup(){ 
  size(___, ____);
  background(______________);
  stroke(255);
  // always start Minim before you do anything with it
  Minim.start(this);
  Minim.debugOn();
  
  sounds = new AudioSample[sound_names.length];
  
  for( int i=0; i< sound_names.length; i++ ) {
    sounds[i] = Minim.loadSample(sound_names[i], 512);
  }
  
  // Open the port that the board is connected to and use the same speed (19200 bps)
  port = new Serial(this, portname, 19200);

}

void draw(){
  // do the drawing on events
  
  
}

void soundball() {
  int r = int(random(sounds.length));
  println("picked sound #"+r);
  sounds[r].trigger();   // play a random sound

  int x = int(random(0,300));
  int y = int(random(0,300));
  fill(240,0,0);
  ellipse(x,y, 40,40);
  fill(30,0,0);
  ellipse(x,y, 8,8);
}

void serialEvent(Serial p) { 
  char inByte = port.readChar();
  println("received char: "+ inByte);
  if( inByte == '!' ) {  // '!' is end of "knock!"
    soundball();
  }
}

void keyPressed() {
  if(key == ' ') {
    background(40,40,40);  // erase screen
  }
  soundball();
}

void stop()
{
  // always close Minim audio classes when you are done with them
  for( int i=0; i<sounds.length; i++ ) {
    sounds[i].close();
  }
  super.stop();
}

Exercise 4—Cheesy Hallmark Card

chart.png
/* Play Melody
 * -----------
 *
 * Program to play melodies stored in an array, it requires to know
 * about timing issues and about how to play tones.
 *
 * The calculation of the tones is made following the mathematical
 * operation:
 *
 *       timeHigh = 1/(2 * toneFrequency) = period / 2
 *
 * where the different tones are described as in the table:
 *
 * note 	frequency 	period 	PW (timeHigh)	
 * c 	        261 Hz 	        3830 	1915 	
 * d 	        294 Hz 	        3400 	1700 	
 * e 	        329 Hz 	        3038 	1519 	
 * f 	        349 Hz 	        2864 	1432 	
 * g 	        392 Hz 	        2550 	1275 	
 * a 	        440 Hz 	        2272 	1136 	
 * b 	        493 Hz 	        2028	1014	
 * C	        523 Hz	        1912 	956
 *
 * (cleft) 2005 D. Cuartielles for K3
 */

int ledPin = 13;
int speakerOut = 7;               
byte names[] = {'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C'};  
int tones[] = {1915, 1700, 1519, 1432, 1275, 1136, 1014, 956};
byte melody[] = "2d2a1f2c2d2a2d2c2f2d2a2c2d2a1f2c2d2a2a2g2p8p8p8p";
// count length: 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
//                                10                  20                  30
int count = 0;
int count2 = 0;
int count3 = 0;
int MAX_COUNT = 24;
int statePin = LOW;

void setup() {
 pinMode(ledPin, OUTPUT); 
 pinMode(speakerOut, OUTPUT);
}

void loop() {
  digitalWrite(speakerOut, LOW);     
  for (count = 0; count < MAX_COUNT; count++) {
    statePin = !statePin;
    digitalWrite(ledPin, statePin);
    for (count3 = 0; count3 <= (melody[count*2] - 48) * 30; count3++) {
      for (count2=0;count2<8;count2++) {
        if (names[count2] == melody[count*2 + 1]) {       
          digitalWrite(speakerOut,HIGH);
          delayMicroseconds(tones[count2]);
          digitalWrite(speakerOut, LOW);
          delayMicroseconds(tones[count2]);
        } 
        if (melody[count*2 + 1] == 'p') {
          // make a pause of a certain size
          digitalWrite(speakerOut, 0);
          delayMicroseconds(500);
        }
      }
    }
  }
}



Play your own Melody

/* Sound Serial (aka Keyboard Serial)
 * ------------
 *
 * Program to play tones depending on the data coming from the serial port.
 *
 * The calculation of the tones is made following the mathematical
 * operation:
 *
 *       timeHigh = 1/(2 * toneFrequency) = period / 2
 *
 * where the different tones are described as in the table:
 *
 * note 	frequency 	period 	PW (timeHigh)	
 * c 	        261 Hz 	        3830 	1915 	
 * d 	        294 Hz 	        3400 	1700 	
 * e 	        329 Hz 	        3038 	1519 	
 * f 	        349 Hz 	        2864 	1432 	
 * g 	        392 Hz 	        2550 	1275 	
 * a 	        440 Hz 	        2272 	1136 	
 * b 	        493 Hz 	        2028	1014	
 * C	        523 Hz	        1912 	956
 *
 * (cleft) 2005 D. Cuartielles for K3
 *
 * Updated by Tod E. Kurt <tod@todbot.com> to use new Serial. commands
 * and have a longer cycle time.
 *
 */

int ledPin = 13;
int speakerPin = 7;

// note names and their corresponding half-periods  
byte names[] ={ 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C'};  
int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956};
  
int serByte = -1;
int ledState = LOW;
int count = 0;

void setup() {
  pinMode(ledPin, OUTPUT); 
  pinMode(speakerPin, OUTPUT); 
  beginSerial(9600);
  Serial.println("ready");
}

void loop() {
  digitalWrite(speakerPin, LOW);
  serByte = Serial.read();
  if (serByte != -1) {
    Serial.print(serByte,BYTE);
    ledState = !ledState;           // flip the LED state
    digitalWrite(ledPin, ledState); // write to LED
  }
  for (count=0;count<=8;count++) {  // look for the note
    if (names[count] == serByte) {  // ahh, found it
      for( int i=0; i<50; i++ ) {   // play it for 50 cycles
        digitalWrite(speakerPin, HIGH);
        delayMicroseconds(tones[count]);
        digitalWrite(speakerPin, LOW);
        delayMicroseconds(tones[count]);
      }
    }
  }
}


Build a theremin

A therimin is a musical instrument created by Leon Theremin. It works by responding to the body's electric field. Make a circuit for a Theremin by adding a photocell
therimin_circuit.png
/* Theremin
 * --------
 *
 *
 * Created 24 October 2006
 * copyleft 2006 Tod E. Kurt <tod@todbot.com
 * http://todbot.com/
 */

int photoCell = 0;    // select the input pin for the potentiometer
int speakerPin = 7;

int val = 0;

void setup() {
  pinMode(speakerPin, OUTPUT); 
  beginSerial(9600);
  Serial.println("ready");
}

void loop() {
  digitalWrite(speakerPin, LOW);
  
  val = analogRead(photoCell);    // read value from the sensor
  val = val*2;                 // process the value a little
  //val = val/2;                 // process the value a little
   
  for( int i=0; i<500; i++ ) {  // play it for 50 cycles
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(val);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(val);
  }
}