Introduction: Vibration Foam Speaker!
Concept: Very simple, using an arduino and the play melody basic program, create a music playing speaker out of a vibration motor and a piece of flexible foam. Instead of pulsing signal to a speaker, signal is pulsed to a motor varying how fast it can spin and when it spins.
Science behind it (this might not be super correct but it is my basic understanding of how it works): As the motor vibrates (uses an imbalanced shaft) it transfer the kinetic energy into the foam which has many air pockets throughout its structure. As the foam absorbs all this kinetic energy into all the air pockets it spreads out the rough vibrations throughout into little air vibrations everywhere within the foam and smoothing it out. All the air pockets now vibrate at the same frequency and each acts as a small speaker using compression of air to produce sound. Think of it like a 100 little piezo speakers all playing the same song tied together on a hammock, this is essentially what the foam is, lots of little air pockets connected on a web which allows many of them to vibrate almost independently.
Tools Required:
Scissors
Materials Required:
Arduino (uno used for this) and jumper wires
Vibration Motor (Radio Shack http://www.radioshack.com/product/index.jsp?productId=2914700)
LED (not necessary but fun)
1" x 3" of Foam (can try many different materials here) (http://tinyurl.com/9b6cohq)
Small piece of scotch tape
Science behind it (this might not be super correct but it is my basic understanding of how it works): As the motor vibrates (uses an imbalanced shaft) it transfer the kinetic energy into the foam which has many air pockets throughout its structure. As the foam absorbs all this kinetic energy into all the air pockets it spreads out the rough vibrations throughout into little air vibrations everywhere within the foam and smoothing it out. All the air pockets now vibrate at the same frequency and each acts as a small speaker using compression of air to produce sound. Think of it like a 100 little piezo speakers all playing the same song tied together on a hammock, this is essentially what the foam is, lots of little air pockets connected on a web which allows many of them to vibrate almost independently.
Tools Required:
Scissors
Materials Required:
Arduino (uno used for this) and jumper wires
Vibration Motor (Radio Shack http://www.radioshack.com/product/index.jsp?productId=2914700)
LED (not necessary but fun)
1" x 3" of Foam (can try many different materials here) (http://tinyurl.com/9b6cohq)
Small piece of scotch tape
Step 1: Wrap Vibration Motor With Foam
Cut a piece of the blue foam (or other foam, try different things) to approximately 1" x 3". Wrap the foam around the motor and secure with tape.
Step 2:
Wiring the motor and LED:
The motor and LED are wired in parallel so they receive the same outputs from the Arduino for the music. Pin 9 on the Arduino is what outputs the music signal so that will be the lead to the positive for the LED and motor. Both the negative leads on the LED and motor will goto ground. Plug in the components into a breadboard (or wired together directly if desired) following the pictures and schematics.
*Note: Depending on what LED is used, a resistor may be needed (but will probably not burn out without it)
Wiring diagram courtesy of Arduino example projects (Great resource, check it out!) http://arduino.cc/en/Tutorial/Tone
The motor and LED are wired in parallel so they receive the same outputs from the Arduino for the music. Pin 9 on the Arduino is what outputs the music signal so that will be the lead to the positive for the LED and motor. Both the negative leads on the LED and motor will goto ground. Plug in the components into a breadboard (or wired together directly if desired) following the pictures and schematics.
*Note: Depending on what LED is used, a resistor may be needed (but will probably not burn out without it)
Wiring diagram courtesy of Arduino example projects (Great resource, check it out!) http://arduino.cc/en/Tutorial/Tone
Step 3: Upload Code and Play Vibrational Music!
Last step is to upload the code (currently has Star Wars theme and Mario themes, remove commenting on the mario theme and comment out the Star Wars theme to play different melodies).
Special thanks to R-Team Robotics club for posting their arduino code with the melodies programmed in!
http://www.phys-x.org/rbots/index.php?option=com_content&view=article&id=66:lesson-5-play-melody-with-piezo&catid=41:kits&Itemid=70
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/* Play Melody
* -----------
*
* Program to play a simple melody
*
* Tones are created by quickly pulsing a speaker on and off
* using PWM, to create signature frequencies.
*
* Each note has a frequency, created by varying the period of
* vibration, measured in microseconds. We'll use pulse-width
* modulation (PWM) to create that vibration.
* We calculate the pulse-width to be half the period; we pulse
* the speaker HIGH for 'pulse-width' microseconds, then LOW
* for 'pulse-width' microseconds.
* This pulsing creates a vibration of the desired frequency.
*
* (cleft) 2005 D. Cuartielles for K3
* Refactoring and comments 2006 clay.shirky@nyu.edu
* See NOTES in comments at end for possible improvements
*/
// TONES ==========================================
// Start by defining the relationship between
// note, period, & frequency.
// period is in microsecond so P = 1/f * (1E6)
#define c3 7634
#define d3 6803
#define e3 6061
#define f3 5714
#define g3 5102
#define a3 4545
#define b3 4049
#define c4 3816 // 261 Hz
#define d4 3401 // 294 Hz
#define e4 3030 // 329 Hz
#define f4 2865 // 349 Hz
#define g4 2551 // 392 Hz
#define a4 2272 // 440 Hz
#define a4s 2146
#define b4 2028 // 493 Hz
#define c5 1912 // 523 Hz
#define d5 1706
#define d5s 1608
#define e5 1517
#define f5 1433
#define g5 1276
#define a5 1136
#define a5s 1073
#define b5 1012
#define c6 955
// Define a special note, 'R', to represent a rest
#define R 0
// SETUP ============================================
// Set up speaker on a PWM pin (digital 9, 10 or 11)
int speakerOut = 9;
// Do we want debugging on serial out? 1 for yes, 0 for no
int DEBUG = 1;
void setup() {
pinMode(speakerOut, OUTPUT);
if (DEBUG) {
Serial.begin(9600); // Set serial out if we want debugging
}
}
// MELODY and TIMING =======================================
// melody[] is an array of notes, accompanied by beats[],
// which sets each note's relative length (higher #, longer note)
// star wars theme
int melody[] = { f4, f4, f4, a4s, f5, d5s, d5, c5, a5s, f5, d5s, d5, c5, a5s, f5, d5s, d5, d5s, c5};//
int beats[] = { 21, 21, 21, 128, 128, 21, 21, 21, 128, 64, 21, 21, 21, 128, 64, 21, 21, 21, 128 };
// note debug
//int melody[] = { c4, d4, e4, f4, g4, a4, b4, c5 };
//int beats[] = { 63, 64, 64, 64, 64, 64, 64, 64 };
//super mario theme
//int melody[] = {e5, e5, R, e5, R, c5, e5, R, g5, R, R, R, g4, R, R, R, c5, R, R, g4, R, R, e4};
//int beats[] = {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 , 16, 16, 16, 16, 16, 16, 8, 16, 8, 16, 16};
int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping.
// Set overall tempo
long tempo = 10000;
// Set length of pause between notes
int pause = 1000;
// Loop variable to increase Rest length
int rest_count = 50; //<-BLETCHEROUS HACK; See NOTES
// Initialize core variables
int toneM = 0;
int beat = 0;
long duration = 0;
// PLAY TONE ==============================================
// Pulse the speaker to play a tone for a particular duration
void playTone() {
long elapsed_time = 0;
if (toneM > 0) { // if this isn't a Rest beat, while the tone has
// played less long than 'duration', pulse speaker HIGH and LOW
while (elapsed_time < duration) {
digitalWrite(speakerOut,HIGH);
delayMicroseconds(toneM / 2);
// DOWN
digitalWrite(speakerOut, LOW);
delayMicroseconds(toneM / 2);
// Keep track of how long we pulsed
elapsed_time += (toneM);
}
}
else { // Rest beat; loop times delay
for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
delayMicroseconds(duration);
}
}
}
// LET THE WILD RUMPUS BEGIN =============================
void loop() {
// Set up a counter to pull from melody[] and beats[]
for (int i=0; i<MAX_COUNT; i++) {
toneM = melody[i];
beat = beats[i];
duration = beat * tempo; // Set up timing
playTone();
// A pause between notes...
delayMicroseconds(pause);
if (DEBUG) { // If debugging, report loop, tone, beat, and duration
Serial.print(i);
Serial.print(":");
Serial.print(beat);
Serial.print(" ");
Serial.print(toneM);
Serial.print(" ");
Serial.println(duration);
}
}
}
/*
* NOTES
* The program purports to hold a tone for 'duration' microseconds.
* Lies lies lies! It holds for at least 'duration' microseconds, _plus_
* any overhead created by incremeting elapsed_time (could be in excess of
* 3K microseconds) _plus_ overhead of looping and two digitalWrites()
*
* As a result, a tone of 'duration' plays much more slowly than a rest
* of 'duration.' rest_count creates a loop variable to bring 'rest' beats
* in line with 'tone' beats of the same length.
*
* rest_count will be affected by chip architecture and speed, as well as
* overhead from any program mods. Past behavior is no guarantee of future
* performance. Your mileage may vary. Light fuse and get away.
*
* This could use a number of enhancements:
* ADD code to let the programmer specify how many times the melody should
* loop before stopping
* ADD another octave
* MOVE tempo, pause, and rest_count to #define statements
* RE-WRITE to include volume, using analogWrite, as with the second program at
* http://www.arduino.cc/en/Tutorial/PlayMelody
* ADD code to make the tempo settable by pot or other input device
* ADD code to take tempo or volume settable by serial communication
* (Requires 0005 or higher.)
* ADD code to create a tone offset (higer or lower) through pot etc
* REPLACE random melody with opening bars to 'Smoke on the Water'
*/
Special thanks to R-Team Robotics club for posting their arduino code with the melodies programmed in!
http://www.phys-x.org/rbots/index.php?option=com_content&view=article&id=66:lesson-5-play-melody-with-piezo&catid=41:kits&Itemid=70
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/* Play Melody
* -----------
*
* Program to play a simple melody
*
* Tones are created by quickly pulsing a speaker on and off
* using PWM, to create signature frequencies.
*
* Each note has a frequency, created by varying the period of
* vibration, measured in microseconds. We'll use pulse-width
* modulation (PWM) to create that vibration.
* We calculate the pulse-width to be half the period; we pulse
* the speaker HIGH for 'pulse-width' microseconds, then LOW
* for 'pulse-width' microseconds.
* This pulsing creates a vibration of the desired frequency.
*
* (cleft) 2005 D. Cuartielles for K3
* Refactoring and comments 2006 clay.shirky@nyu.edu
* See NOTES in comments at end for possible improvements
*/
// TONES ==========================================
// Start by defining the relationship between
// note, period, & frequency.
// period is in microsecond so P = 1/f * (1E6)
#define c3 7634
#define d3 6803
#define e3 6061
#define f3 5714
#define g3 5102
#define a3 4545
#define b3 4049
#define c4 3816 // 261 Hz
#define d4 3401 // 294 Hz
#define e4 3030 // 329 Hz
#define f4 2865 // 349 Hz
#define g4 2551 // 392 Hz
#define a4 2272 // 440 Hz
#define a4s 2146
#define b4 2028 // 493 Hz
#define c5 1912 // 523 Hz
#define d5 1706
#define d5s 1608
#define e5 1517
#define f5 1433
#define g5 1276
#define a5 1136
#define a5s 1073
#define b5 1012
#define c6 955
// Define a special note, 'R', to represent a rest
#define R 0
// SETUP ============================================
// Set up speaker on a PWM pin (digital 9, 10 or 11)
int speakerOut = 9;
// Do we want debugging on serial out? 1 for yes, 0 for no
int DEBUG = 1;
void setup() {
pinMode(speakerOut, OUTPUT);
if (DEBUG) {
Serial.begin(9600); // Set serial out if we want debugging
}
}
// MELODY and TIMING =======================================
// melody[] is an array of notes, accompanied by beats[],
// which sets each note's relative length (higher #, longer note)
// star wars theme
int melody[] = { f4, f4, f4, a4s, f5, d5s, d5, c5, a5s, f5, d5s, d5, c5, a5s, f5, d5s, d5, d5s, c5};//
int beats[] = { 21, 21, 21, 128, 128, 21, 21, 21, 128, 64, 21, 21, 21, 128, 64, 21, 21, 21, 128 };
// note debug
//int melody[] = { c4, d4, e4, f4, g4, a4, b4, c5 };
//int beats[] = { 63, 64, 64, 64, 64, 64, 64, 64 };
//super mario theme
//int melody[] = {e5, e5, R, e5, R, c5, e5, R, g5, R, R, R, g4, R, R, R, c5, R, R, g4, R, R, e4};
//int beats[] = {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 , 16, 16, 16, 16, 16, 16, 8, 16, 8, 16, 16};
int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping.
// Set overall tempo
long tempo = 10000;
// Set length of pause between notes
int pause = 1000;
// Loop variable to increase Rest length
int rest_count = 50; //<-BLETCHEROUS HACK; See NOTES
// Initialize core variables
int toneM = 0;
int beat = 0;
long duration = 0;
// PLAY TONE ==============================================
// Pulse the speaker to play a tone for a particular duration
void playTone() {
long elapsed_time = 0;
if (toneM > 0) { // if this isn't a Rest beat, while the tone has
// played less long than 'duration', pulse speaker HIGH and LOW
while (elapsed_time < duration) {
digitalWrite(speakerOut,HIGH);
delayMicroseconds(toneM / 2);
// DOWN
digitalWrite(speakerOut, LOW);
delayMicroseconds(toneM / 2);
// Keep track of how long we pulsed
elapsed_time += (toneM);
}
}
else { // Rest beat; loop times delay
for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
delayMicroseconds(duration);
}
}
}
// LET THE WILD RUMPUS BEGIN =============================
void loop() {
// Set up a counter to pull from melody[] and beats[]
for (int i=0; i<MAX_COUNT; i++) {
toneM = melody[i];
beat = beats[i];
duration = beat * tempo; // Set up timing
playTone();
// A pause between notes...
delayMicroseconds(pause);
if (DEBUG) { // If debugging, report loop, tone, beat, and duration
Serial.print(i);
Serial.print(":");
Serial.print(beat);
Serial.print(" ");
Serial.print(toneM);
Serial.print(" ");
Serial.println(duration);
}
}
}
/*
* NOTES
* The program purports to hold a tone for 'duration' microseconds.
* Lies lies lies! It holds for at least 'duration' microseconds, _plus_
* any overhead created by incremeting elapsed_time (could be in excess of
* 3K microseconds) _plus_ overhead of looping and two digitalWrites()
*
* As a result, a tone of 'duration' plays much more slowly than a rest
* of 'duration.' rest_count creates a loop variable to bring 'rest' beats
* in line with 'tone' beats of the same length.
*
* rest_count will be affected by chip architecture and speed, as well as
* overhead from any program mods. Past behavior is no guarantee of future
* performance. Your mileage may vary. Light fuse and get away.
*
* This could use a number of enhancements:
* ADD code to let the programmer specify how many times the melody should
* loop before stopping
* ADD another octave
* MOVE tempo, pause, and rest_count to #define statements
* RE-WRITE to include volume, using analogWrite, as with the second program at
* http://www.arduino.cc/en/Tutorial/PlayMelody
* ADD code to make the tempo settable by pot or other input device
* ADD code to take tempo or volume settable by serial communication
* (Requires 0005 or higher.)
* ADD code to create a tone offset (higer or lower) through pot etc
* REPLACE random melody with opening bars to 'Smoke on the Water'
*/