This time, we’ll examine “sound” using Arduino with speakers. Arduino comes with a “tone” function and it’s relatively easy to get started with. Let’s see how sound works with Arduino by creating a simple instrument gadget.
Expected time to complete: 90 minutes
Parts needed:
This time, we’ll be dealing with speakers. But electronically speaking, what exactly is a speaker? Everyone has a general sense that electricity flows through them, causing vibrations that lead to the sound generation, but let’s look into the process of sound creation in more detail.
When it comes to classifying speakers, there are many types of shapes. But regarding how electric signals are processed, they can be classified as: dynamic, condenser, piezoelectric, discharge (ion), magnetic, and ribbon.
The piezoelectric type that we’ll be using is shown in figure 1.
Figure 1 Piezoelectric speaker mechanism
On figure 2, you can see the general mechanism of a dynamic speaker. In both cases, by supplying a current in accordance with a signal of the sound to be output, the speaker causes vibrations in the air, and produces sound.
Figure 2 Dynamic speaker mechanism
We’ll be working with speakers this time. But, let’s take a step back first and consider how a microphone works. Roughly speaking, a mic is a type of speaker. A speaker converts current to vibrations in the air, and a mic takes vibrations in the air and converts them into current for use as an audio signal.
Let’s try an experiment.
The speaker that we’ll be using this time takes an electric current to excite the piezoelectric elements and cause a metal plate to vibrate thus producing sound. But with an LED connected to the speaker, try bending the speaker. By the way, speakers don’t have a positive/negative direction.
Picture 1 Bending the speaker causes the LED to light up
By doing this, we can see that the LED lights up. Using the same mechanism as a microphone, we have proof that bending a piezoelectric speaker (in the case of a mic this is equal to receiving a vibration in the air) results in the creation of a current. The amount of current generated by bending a speaker is extremely small and short, so there isn’t much that we can do with it, but it’s an interesting experiment.
Let’s dive right in and create a tone using Arduino and a speaker. To make it easy, Arduino comes with a tone function designed to create sound.
Tone function
Tone (output pin number, output frequency, length);
Let’s connect a speaker to Arduino and upload a program to it.
Picture 2 Tone function circuit
Figure 3 Tone function circuit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
//***************************************/ //Program 1 for generating sound using the tone function //***************************************/ #define BEATTIME 200 //Length of the generated tone (msec) #define SPEAKER 12 //Pin number of the speaker void setup() { } void loop() { tone(SPEAKER,262,BEATTIME) ; // Do delay(BEATTIME) ; tone(SPEAKER,294,BEATTIME) ; // Re delay(BEATTIME) ; tone(SPEAKER,330,BEATTIME) ; // Mi delay(BEATTIME) ; tone(SPEAKER,349,BEATTIME) ; // Fa delay(BEATTIME) ; tone(SPEAKER,392,BEATTIME) ; // So delay(BEATTIME) ; tone(SPEAKER,440,BEATTIME) ; // La delay(BEATTIME) ; tone(SPEAKER,494,BEATTIME) ; // Si delay(BEATTIME) ; tone(SPEAKER,523,BEATTIME) ; // Do delay(BEATTIME) ; } |
A major scale plays repeatedly. Next, let’s try the following program. Let’s play a “Do” and a “Mi” together.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//***************************************/ //Program 2 for generating sound using the tone function //***************************************/ #define BEATTIME 100 //Length of the generated tone (msec) #define SPEAKER 12 //Pin number of the speaker void setup() { } void loop() { tone(SPEAKER,262,BEATTIME) ; // Do tone(SPEAKER,330,BEATTIME) ; // Mi delay(BEATTIME) ; } |
What was the result? It didn’t work as expected. The tone function, in accordance with the program, plays a “Do” and then immediately tries to play a “Mi” for the specified length in milliseconds, so the vibrations of the speaker stack up and noise is produced, contrary to what we expected. The Arduino tone function can only accept one tone at a time.
Well then, how can we create a chord? Let’s look into the mechanism for creating tones.
Figure 4 Waveform of “La”
Sounds vibrations in the air take the form of a wave. In the case of a simple wave, take for example a tuning fork that is used for tuning instruments. It produces a “La” that is 440Hz. Putting it simply, this causes 440 vibrations per second in the air. This is shown in the figure 5 below.
Well then, what happens when we play another tone along with this “La?”
Figure 5 Waveforms for two tones
The red line in the graph is the newly added tone. If we had two speakers then they could each generate one of the tones. But with only one speaker, it’s necessary to combine the waveforms to create the tones. The result is shown in the figure 6 below.
Figure 6 Combining two tones (green line)
The green line in the graph shows the wave of the tone that we need to generate to reproduce the two tones. When using one speaker, this method is required for combining the 2 tones.
We could create a program that calculates the waveforms to combine every notes. But to do this kind of calculations would be complicated.
Here is an example that uses a program to calculate the sound wave without using the tone function. You can give it a try if you’re interested.
Now, we understand a bit about generating tones with Arduino. So, let’s try to create a simple instrument gadget. Using the tone function and a tactile switch, let’s make a simple electric organ. It wouldn’t be good if we attached each of the seven keys to its own analog pin, so let’s set a different resistance value for each key (10K, 12K, 15K, 18K, 20K, 22K, 25K) and use an “if” statement in the program to judge the AnalogInput and determine which note of the scale it should reproduce.
Figure 7 Judging analog input based on resistance value (while pushing the tactile switch)
In this case, one AnalogInput pin will be sufficient.
Figure 8 Circuit for a simple instrument gadget
Picture 3 Circuit for a simple instrument gadget
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
//***************************************/ //Simple instrument gadget program //***************************************/ int s = 0; int speaker = 12; int sounds[] = {262,294,330,349,392,440,494}; int BEATTIME = 100; void setup() { Serial.begin(9600); pinMode(0,INPUT); pinMode(1,INPUT); } void loop() { s = analogRead(0); int p = analogRead(1); //Reset the sound noTone(12); if(550 < s){ tone(speaker,sounds[0],BEATTIME); } else if(530 < s){ tone(speaker,sounds[1],BEATTIME); } else if(510 < s){ tone(speaker,sounds[2],BEATTIME); } else if(490 < s){ tone(speaker,sounds[3],BEATTIME); } else if(470 < s){ tone(speaker,sounds[4],BEATTIME); } else if(450 < s){ tone(speaker,sounds[5],BEATTIME); } else if(430 < s){ tone(speaker,sounds[6],BEATTIME); } else if(200 < s){ tone(speaker,sounds[7],BEATTIME); } delay(100); Serial.println(s); Serial.println(p); } |
Let’s hack this a bit.
It worked well, but let’s see what else we can improve. Let’s use the photoreflector that we used previously to create something that will change the tone as we move our finger closer to it. For guitarists, this method would be similar to “choking.” By adding the value input from the photo-reflector we can change the value of the tone.
Picture 4 Improved circuit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
//***************************************/ //Improved program for creating of a simple instrument gadget //***************************************/ int s = 0; int speaker = 12; int sounds[] = {262,294,330,349,392,440,494}; int BEATTIME = 200; void setup() { Serial.begin(9600); pinMode(0,INPUT); pinMode(1,INPUT); } void loop() { s = analogRead(0); int p = 1023 - analogRead(1); //Pitch p = p * 2; //Reset the sound noTone(12); if(550 < s){ tone(speaker,sounds[0]+p,BEATTIME); } else if(530 < s){ tone(speaker,sounds[1]+p,BEATTIME); } else if(510 < s){ tone(speaker,sounds[2]+p,BEATTIME); } else if(490 < s){ tone(speaker,sounds[3]+p,BEATTIME); } else if(470 < s){ tone(speaker,sounds[4]+p,BEATTIME); } else if(450 < s){ tone(speaker,sounds[5]+p,BEATTIME); } else if(430 < s){ tone(speaker,sounds[6]+p,BEATTIME); } else if(200 < s){ tone(speaker,sounds[7]+p,BEATTIME); } delay(50); Serial.println(p); } |
Next, we’ll delve further into sound creation by using a stereo jack with Arduino to produce tone through speakers. More than just the “beeps” that can be obtained using the tone function, we’ll use an open-source library called “Mozzi” to create a rich set of sounds like those found in synthesizers using Arduino alone for sound production.