LilyPad ProtoSnap Plus Activity Guide
5: Play a Tune
The microcontroller on the LilyPad USB Plus can turn its outputs on and off very quickly. If you carefully choose the frequency at which you're turning an output on and off, and send that signal to the buzzer on the LilyPad ProtoSnap Plus, you can create tones and simple musical tunes.
LilyPad Boards Used in This Activity
- LilyPad USB Plus
- LilyPad Buzzer
Inside the LilyPad Buzzer's plastic housing is a coil of wire and a small magnet. When current flows through this coil, it becomes magnetized and pulls towards the magnet, which makes a tiny “click”. When done thousands of times per second, the clicks create tones. In this activity, you’ll pulse the buzzer at specific frequencies to create musical notes. The buzzer can also be used to make alert sounds, robot beeps and boops, etc.
New Concepts Introduced in This Activity
Making Tones
You'll use the tone()
and noTone()
commands to drive the buzzer at specific frequencies.
A tone’s pitch is what we perceive when we think of a note as being very high (screams, forks scratching plates, etc.) versus very low (like earth-rumbling bass). The pitch of a tone is very closely related to the frequency played through a speaker. If we toggle a pin from HIGH-to-LOW then LOW-to-HIGH 440 times per second, for example, it produces a 440 Hz (hertz) frequency - a “middle A” pitch. Humans can hear frequencies ranging from 20 (low-pitch, bass) to 20,000 Hz (high-pitch, “ow, my ears”).
Example Code
To open the code, go to:
File > Examples > LilyPadProtoSnapPlus > LPP_05_Tune
You can also copy and paste the following code into the Arduino IDE. Hit upload, and see what happens!
language:c
/*
LilyPad ProtoSnap Plus Activity 5: Play a Tune
SparkFun Electronics
https://www.sparkfun.com/products/14346
Play musical notes through the buzzer on the LilyPad ProtoSnap Plus
Follow the tutorial at:
https://learn.sparkfun.com/tutorials/lilypad-protosnap-plus-activity-guide#5-play-a-tune
Uses frequencies from "melody" by Tom Igoe: https://www.arduino.cc/en/Tutorial/toneMelody
This code is released under the MIT License: (http://opensource.org/licenses/MIT)
******************************************************************************/
// Create an integer variable naming the pin we'll use for the buzzer.
// On the ProtoSnap Plus, it's on A3.
int buzzer = A3;
// Map musical notes to their frequencies by creating variables for them.
// You can find the frequencies for higher and lower notes at:
// https://www.arduino.cc/en/Tutorial/toneMelody
int NOTE_C5 = 523;
int NOTE_CS5 = 554;
int NOTE_D5 = 587;
int NOTE_DS5 = 622;
int NOTE_E5 = 659;
int NOTE_F5 = 698;
int NOTE_FS5 = 740;
int NOTE_G5 = 784;
int NOTE_GS5 = 831;
int NOTE_A5 = 880;
int NOTE_AS5 = 932;
int NOTE_B5 = 988;
int NOTE_C6 = 1047;
// We'll also create a variable for how long to play each note in milliseconds.
// If you make this smaller, the notes will play faster.
int tempo = 500;
void setup()
{
// Set the buzzer pin to be an output:
pinMode(buzzer, OUTPUT);
}
void loop()
{
// This code will play a simple scale from C5 to C6.
// The tone command takes two parameters: a pin number and a frequency.
// The tone will play until we stop it with the noTone command.
// Each of the below blocks plays one note; the note plays during the delay command.
tone(buzzer,NOTE_C5);
delay(tempo);
tone(buzzer,NOTE_D5);
delay(tempo);
tone(buzzer,NOTE_E5);
delay(tempo);
tone(buzzer,NOTE_F5);
delay(tempo);
tone(buzzer,NOTE_G5);
delay(tempo);
tone(buzzer,NOTE_A5);
delay(tempo);
tone(buzzer,NOTE_B5);
delay(tempo);
tone(buzzer,NOTE_C6);
delay(tempo);
// A longer delay at the end pauses the sound before looping again.
// Here we're delaying four times the "tempo" value:
noTone(buzzer);
delay(tempo * 4);
// Try writing your own song using the noted defined at the top of the program!
// You can change the note duration by multiplying or dividing the "tempo" value
}
What You Should See
Once the code uploads, the buzzer will begin playing a simple musical scale over one octave, pause, and repeat.
Understanding Your Program
Program Overview
- Define variables for the audio frequencies we'll be using, and the tempo (speed at which we'll be playing).
- Configure the sew tab connected to the buzzer to be an output.
- Play a series of notes using the
tone
command. - Pause and repeat.
Code to Note
Code | Description |
---|---|
int NOTE_C5 = 523; int NOTE_CS5 = 554; int NOTE_D5 = 587; int NOTE_DS5 = 622; int NOTE_E5 = 659; int NOTE_F5 = 698; int NOTE_FS5 = 740; int NOTE_G5 = 784; int NOTE_GS5 = 831; int NOTE_A5 = 880; int NOTE_AS5 = 932; int NOTE_B5 = 988; int NOTE_C6 = 1047; |
Frequency and Notes:To play a specific note you need to know its audio frequency (how fast the output needs to turn on and off). At the top of this program we've included variables for one octave (C5 to C6). These frequencies come from the Tone Melody tutorial on Arduino's site. If you want to play higher or lower notes you can find many more frequencies there. |
int tempo = 500; |
Setting Tempo:Another variable we've created is calledtempo . We'll use this to control the duration of all the notes, allowing you to change the speed of the tune from one place.
|
tone(buzzer,NOTE_C5); |
Making Tones:To actually make noise, we use thetone() command. It takes two parameters; the pin which has the buzzer attached to it, and the audio frequency to output.
|
tone(buzzer,NOTE_B5); delay(tempo); |
Setting Duration:Once you run thetone() command, the buzzer will keep making sound forever, even while the program continues on to other things. To control the duration of the tone, we'll use delay() along with our tempo variable to pause while the tone is playing.
|
tone(buzzer,NOTE_B5); delay(tempo); tone(buzzer,NOTE_C6); delay(tempo); noTone(buzzer); |
Changing and Stopping Sounds:To actually stop the tone, you can run anothertone() command with a different note, or use the noTone() command to turn off the sound. The noTone() command only needs one parameter, the pin number it is controlling. We use both methods in this program.
|
delay(tempo * 4); |
Pauses and Tempo:To pause before theloop() function repeats the scale, we're using another delay() at the end of the program. But to make it pause a bit longer, we multiply our tempo variable by four. This makes it pause for four times as long as each note plays. Half of music is the duration of the notes; you can use multiplication and division to turn individual notes into half notes, quarter notes, create rests, etc. Soon you'll be making real music!
|
Coding Challenges
This program plays a simple scale. Can you change the program to play an actual song?
In this program we used a variable called
tempo
to change the durations of all the notes. In actual music, notes have different durations, and rests (periods of no sound) are important as well. Can you change the durations of individual notes by adding math to the delay values? Hint: Iftempo
is the duration of a whole note,tempo / 2
would be the duration of a half note, etc.