Wednesday 9/28 – Lab 5: Output: Piezo speakers

Before the Lab

You should have experiments with the force sensitive resistor and photosensor to control your LEDs. You should have also used the force sensitive resistor and photosensor to control a Processing program on your computer. Congratulations!

In Lab Exercise

Special Note

If you finish early, please use the extra time to solder some wires onto your motor, which we will be using in the near future.

Objective

Using the piezo to make sound.

Activities

Part 1 – The Piezo Buzzer

1. Connect the Arduino to the Piezo Buzzer.

2. There are two sample programs on the course website. Give them a shot:

This sample code plays a song on your speaker:


/* 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); } } } } }

This sample code lets you control the note using Serial input:

/* 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 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'};
unsigned int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956};

int ledState = LOW;
int count = 0;

// what we read in from serial
char serInString[100]; // array that will hold the different bytes of the string. 100=100characters;
// -> you must state how long the array will be else it won't work properly
char serNote;

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

void loop() {
// Read data from Serial /////////////////
// clear the string
memset(serInString, 0, 100);
//read the serial port and create a string out of what you read
readSerialString(serInString);

// Reset speaker to not play anything
digitalWrite(speakerPin, LOW);

// if your note plays forever, uncomment this section
// by deleting the "/*" and "*/"
/*
// if there is no new input over Serial, then just skip the rest of the
// loop() and check again
if (serInString[0] == 0) {
return;
}
*/

// if we get any new input over the Serial port
if (serInString[0] != 0) {
ledState = !ledState; // flip the LED state
digitalWrite(ledPin, ledState); // write to LED
// remember what the note is we should be playing
serNote = serInString[0];
Serial.println(serNote);
}

for (count=0;count<=8;count++) { // look for the note if (names[count] == serNote) { // ahh, found it Serial.print(serNote); Serial.print(" is a note we can play. tones[count] = "); Serial.print(tones[count]); Serial.println(); for( int i=0; i<50; i++ ) { // play it for 50 cycles //Serial.print(i); Serial.print(" "); digitalWrite(speakerPin, HIGH); delayMicroseconds(tones[count]); digitalWrite(speakerPin, LOW); delayMicroseconds(tones[count]); } } } } //read a string from the serial and store it in an array //you must supply the array variable void readSerialString (char *strArray) { int i = 0; if(!Serial.available()) { return; } while (Serial.available()) { strArray[i] = Serial.read(); i++; } }

3. If you want to reduce the volume of the piezo speaker, you can add a resistor in series with the speaker:

Part 2 –Make a Theremin

A Theremin is an instrument designed to be played without being touched. You will make one here using your piezo buzzer and the photosensor.

1. Build the Theremin circuit. Note that this is just the photocell circuit and the piezo circuit combined.

2. The software to control the Theremin is here:

/* Theremin
* --------
*
*
* Created 24 October 2006
* copyleft 2006 Tod E. Kurt <tod@todbot.com
* http://todbot.com/
*/

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

int val = 0;

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

void loop() {
digitalWrite(speakerPin, LOW);

val = analogRead(potPin); // 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);
}
}

Homework

Input output coincidence exercise. Design an artifact where both input and output occur at the same place. Use any combination of your input transducers and output transducers (pot, photocell, FSR, LEDs, piezo, screen). E.g., a ball that changes colors and/or plays different sound/melody depending on the pressure being applied. A stick you can twist to color or sound differently... These are just examples to spark your imagination. Be creative!