Playing The Imperial March
From Texas Instruments Embedded Processors Wiki
Contents |
Quick Start
- Get a piezo speaker, like the ones that can be found in an old computer.
- Get a 1KOhm resistor.
- Download Code/Build the circuit.
- Enjoy the John Williams' masterpiece!
Development
Schematic
The circuit is really simple to build. Solder the 1KOhm resistor to the positive lead of the speaker (red wire) and connect it to P1.2 on the Launchpad. Then connect the black wire to the GND pin on the board. You can even remove the R1, but the sound will be very loud and annoying, and the speaker may be damaged. You can add a 1K trimmer instead of the resistor to make the volume adjustable.
Code
Here is the fully commented code for this tutorial. I have ported it to the MSP430G2231 from an Arduino example made by naneau.
File:Lauchpad Imperial March.zip
#include "msp430g2231.h" //Definition of the notes' frequecies in Hertz. #define c 261 #define d 294 #define e 329 #define f 349 #define g 391 #define gS 415 #define a 440 #define aS 455 #define b 466 #define cH 523 #define cSH 554 #define dH 587 #define dSH 622 #define eH 659 #define fH 698 #define fSH 740 #define gH 784 #define gSH 830 #define aH 880 /* This two functions stop the main thread for a certain number of milli -or- microseconds. They are based on trial and error, but they work fine for the out-of-the-box Launchpad board. TI should really add this types of functions as default, just like Arduino does :) . */ void delay_ms(unsigned int ms ) { unsigned int i; for (i = 0; i<= ms; i++) __delay_cycles(500); //Built-in function that suspends the execution for 500 cicles } void delay_us(unsigned int us ) { unsigned int i; for (i = 0; i<= us/2; i++) __delay_cycles(1); } //This function generates the square wave that makes the piezo speaker sound at a determinated frequency. void beep(unsigned int note, unsigned int duration) { int i; long delay = (long)(10000/note); //This is the semiperiod of each note. long time = (long)((duration*100)/(delay*2)); //This is how much time we need to spend on the note. for (i=0;i<time;i++) { P1OUT |= BIT2; //Set P1.2... delay_us(delay); //...for a semiperiod... P1OUT &= ~BIT2; //...then reset it... delay_us(delay); //...for the other semiperiod. } delay_ms(20); //Add a little delay to separate the single notes } //This is the Imperial March code. //As you can see, there are lots of beeps at different frequencies and durations, and some delays to separate the various bits of this wonderful song. void play() { beep(a, 500); beep(a, 500); beep(a, 500); beep(f, 350); beep(cH, 150); beep(a, 500); beep(f, 350); beep(cH, 150); beep(a, 650); delay_ms(150); //end of first bit beep(eH, 500); beep(eH, 500); beep(eH, 500); beep(fH, 350); beep(cH, 150); beep(gS, 500); beep(f, 350); beep(cH, 150); beep(a, 650); delay_ms(150); //end of second bit... beep(aH, 500); beep(a, 300); beep(a, 150); beep(aH, 400); beep(gSH, 200); beep(gH, 200); beep(fSH, 125); beep(fH, 125); beep(fSH, 250); delay_ms(250); beep(aS, 250); beep(dSH, 400); beep(dH, 200); beep(cSH, 200); beep(cH, 125); beep(b, 125); beep(cH, 250); delay_ms(250); beep(f, 125); beep(gS, 500); beep(f, 375); beep(a, 125); beep(cH, 500); beep(a, 375); beep(cH, 125); beep(eH, 650); //end of third bit... (Though it doesn't play well) //let's repeat it beep(aH, 500); beep(a, 300); beep(a, 150); beep(aH, 400); beep(gSH, 200); beep(gH, 200); beep(fSH, 125); beep(fH, 125); beep(fSH, 250); delay_ms(250); beep(aS, 250); beep(dSH, 400); beep(dH, 200); beep(cSH, 200); beep(cH, 125); beep(b, 125); beep(cH, 250); delay_ms(250); beep(f, 250); beep(gS, 500); beep(f, 375); beep(cH, 125); beep(a, 500); beep(f, 375); beep(cH, 125); beep(a, 650); //end of the song } int main( void ) { WDTCTL = WDTPW + WDTHOLD; //Disable Watchdog Timer P1DIR|=BIT2; // P1.2 output while(1) { play(); delay_ms(2000); //Add a 2 sec. delay to avoid replaying right after the end. } }
Theoretical Background
A Pulse Width Modulation (PWM) output can be used to play tones on a piezo speaker. With this, musical scales and simple songs can be played on the piezo speaker.
Piezo speakers operate by the converse piezoelectric effect: when a voltage is applied across the terminals, the piezoelectric material in the speaker deflects in one direction. Applying an alternating voltage, such as a square wave, will cause the material to vibrate and create a sound. A constant voltage will not produce a sound. Also sine, triangle and sawtooth waves can be used to drive a piezo speaker, resulting in different pitches of the notes.
As you can see from the code, the beep() function was used to provide the alternating voltage to drive the speaker. The period (do you remember delay_us() ?) of the sqare wave determines the note that will be played.
You can have some problems about the clock and timings with this project, I'm still figuring out the MSP430 Clock System as it is the first time I use them.
Future Ideas
- You might want to play sounds from an SD Card, like it has been done here. (I'm working on it, but the sound is really distorced, I'm still wondering why...)
References
- MSP430x2xx Family User Guide
- MSP430G2x31 Datasheet
- Naneau's Arduino Imperial March
- Make a talking MSP430 MCU
Related Projects
Leave a CommentComments
Comments on Playing The Imperial March
Misterhay said ...
DarthStigSr said ...
Very Cool! Got my lauchpad & extra MSP's today. Have turned this into a doorbell already (Just need to build and box it now!)
--DarthStigSr 03:45, 30 August 2011 (CDT)
Emgmiller said ...
Another project like this with the Imperial March can be seen here:
http://www.youtube.com/watch?v=-1l0ILEp3J4&feature=player_embedded
--Emgmiller 11:44, 28 December 2011 (CST)


Thanks for the project idea, I like it.
This worked for me with a regular (magnet and moving coil) loudspeaker from an old computer case.
--Misterhay 09:14, 8 September 2010 (CDT)