Let's break it down step by step: Having figured out how to control motion, lighting, temperature, and displays, it's time to focus on creating sounds.
Obtaining high-quality sound on a Raspberry Pi is easier because you can connect active speakers to its audio jack, while on an Arduino, this task is a bit more challenging.
Sound
To reproduce a more or less complex sound, you'll need some kind of loudspeaker. Loudspeakers, which emerged almost a century ago, mostly operate based on a solenoid (see the "Solenoids" section), containing an electromagnetic coil with a sufficiently high frequency that vibrates a rigid cone, creating sound waves.
Loudspeakers typically have impedance marked in ohms. Although this unit measures resistive resistance, concerning loudspeakers, it's referred to as their impedance. In essence, this term also signifies resistance, but it is applied to devices that are not resistors in the full sense of the word, and the wire coil present in a loudspeaker (as any such coil) does not act as a simple resistor. If you're interested in this topic, you can read articles dedicated to inductance.
Usually, loudspeakers come in 4 or 8 ohm values. If you plan to connect an 8-ohm loudspeaker to an Arduino output with a voltage of 5V, you can expect a current of:
I = V / R = 5 / 8 = 625 mA
So, the current is much higher than the recommended 40 mA for the Arduino output. It seems like we'll need a matching resistor here as well! So, in this experiment, we will connect the loudspeaker to Arduino via a resistor and then use the serial monitor to teach Arduino to reproduce sound of a specific frequency.
SOUND FREQUENCIES
The frequency of a sound wave, in musical terms, is called a pitch and is expressed in the number of sound waves reaching your ears in one second. I like to envision sound waves as ripples on a pond. A high-frequency sound - say, 10 kHz (kilohertz) - creates 10,000 sound waves per second, while a low-frequency sound (say, 100 Hz) only produces 100 sound waves per second. Humans usually hear sounds in the range of 20 Hz to 20 kHz, but the upper limit decreases with age. Sounds above 20 kHz are typically referred to as ultrasound.
Different animals have different ranges of audible sounds. For example, cats can hear frequencies up to 55-79 kHz, and bats are known to use ultrasound echolocation.
In music, the lowest note "C" on a standard piano corresponds to a frequency of 32.7 Hz, while the highest note is at 4186 Hz. The concept of an octave, known to anyone with even a passing connection to music, involves doubling the frequency. So, if you make a piano keyboard play two adjacent octaves of "C," the second note will sound with twice the frequency of the first note.
Components
For this experiment, you won't need many components, just a loudspeaker and a resistor. However, if you use a breadboard and jumper wires, you can simplify the connection.
Components for working with Arduino in the loudspeaker experiment include:
- A small loudspeaker with an impedance of 8 ohms
- A 270-ohm, 0.25-watt resistor
- A 400-point solderless breadboard
- "Male-to-Male" jumper wires
I salvaged the loudspeaker from an old radio receiver, and it had a socket where I could insert the plug ends of the jumper wires. You may get a loudspeaker with soldered wires that can be plugged into the Arduino pins, or you might need to solder wires to it with a thickness that allows them to be inserted into the breadboard sockets.
Experimental Circuit Diagram
The circuit assembled for the experiment on the breadboard is shown in the image below. One wire from the loudspeaker is connected to the GND (ground) pin of the Arduino, and the other is connected to pin D11 through the resistor.
Arduino Program
The Arduino sketch for this experiment:
The unfamiliar part of the code may be inside the loop():
1. `tone` sets one of the Arduino output pins to play sound at the specified frequency (in this case, the frequency entered in the serial monitor).
2. After a two-second delay, the `noTone` command stops the sound, returning to peaceful silence.
Uploading and Running the Program
Upload the program to the device, and then open the serial monitor. Try entering the value 1000 - you should hear a moderately loud but not overwhelmingly loud sound.
Continue the experiment by inputting different frequencies and observing how the sound changes. If you attempt to achieve frequencies at the limits of audibility in this experiment, you may be disappointed because the loudspeaker likely has its own, even narrower range of sound production, and sound volume sharply declines at frequencies exceeding about 10 kHz. Small loudspeakers also usually cannot reproduce sounds with a frequency lower than 100 Hz.
SINE WAVE AND SQUARE WAVE
The sound emitted by the loudspeaker when connected directly to the Arduino output is harsh and unnatural. This is because the digital output can only be in an on or off state, and the resulting sound wave is square in shape. Compared to the smoother and more sinusoidal sound wave of a musical instrument, a square wave sound wave is considered quite unnatural (see image below).
Loudspeakers typically have impedance marked in ohms. Although this unit measures resistive resistance, concerning loudspeakers, it's referred to as their impedance. In essence, this term also signifies resistance, but it is applied to devices that are not resistors in the full sense of the word, and the wire coil present in a loudspeaker (as any such coil) does not act as a simple resistor. If you're interested in this topic, you can read articles dedicated to inductance.
Usually, loudspeakers come in 4 or 8 ohm values. If you plan to connect an 8-ohm loudspeaker to an Arduino output with a voltage of 5V, you can expect a current of:
I = V / R = 5 / 8 = 625 mA
So, the current is much higher than the recommended 40 mA for the Arduino output. It seems like we'll need a matching resistor here as well! So, in this experiment, we will connect the loudspeaker to Arduino via a resistor and then use the serial monitor to teach Arduino to reproduce sound of a specific frequency.
SOUND FREQUENCIES
The frequency of a sound wave, in musical terms, is called a pitch and is expressed in the number of sound waves reaching your ears in one second. I like to envision sound waves as ripples on a pond. A high-frequency sound - say, 10 kHz (kilohertz) - creates 10,000 sound waves per second, while a low-frequency sound (say, 100 Hz) only produces 100 sound waves per second. Humans usually hear sounds in the range of 20 Hz to 20 kHz, but the upper limit decreases with age. Sounds above 20 kHz are typically referred to as ultrasound.
Different animals have different ranges of audible sounds. For example, cats can hear frequencies up to 55-79 kHz, and bats are known to use ultrasound echolocation.
In music, the lowest note "C" on a standard piano corresponds to a frequency of 32.7 Hz, while the highest note is at 4186 Hz. The concept of an octave, known to anyone with even a passing connection to music, involves doubling the frequency. So, if you make a piano keyboard play two adjacent octaves of "C," the second note will sound with twice the frequency of the first note.
Components
For this experiment, you won't need many components, just a loudspeaker and a resistor. However, if you use a breadboard and jumper wires, you can simplify the connection.
Components for working with Arduino in the loudspeaker experiment include:
- A small loudspeaker with an impedance of 8 ohms
- A 270-ohm, 0.25-watt resistor
- A 400-point solderless breadboard
- "Male-to-Male" jumper wires
I salvaged the loudspeaker from an old radio receiver, and it had a socket where I could insert the plug ends of the jumper wires. You may get a loudspeaker with soldered wires that can be plugged into the Arduino pins, or you might need to solder wires to it with a thickness that allows them to be inserted into the breadboard sockets.
Experimental Circuit Diagram
The circuit assembled for the experiment on the breadboard is shown in the image below. One wire from the loudspeaker is connected to the GND (ground) pin of the Arduino, and the other is connected to pin D11 through the resistor.
Arduino Program
The Arduino sketch for this experiment:
Code: Select all
const int soundPin = 11;
void setup() {
pinMode(soundPin, OUTPUT);
Serial.begin(9600);
Serial.println("Enter frequency");
}
void loop() {
if (Serial.available()) {
int f = Serial.parseInt();
tone(soundPin, f); // (1)
delay(2000);
noTone(soundPin); // (2)
}
}
1. `tone` sets one of the Arduino output pins to play sound at the specified frequency (in this case, the frequency entered in the serial monitor).
2. After a two-second delay, the `noTone` command stops the sound, returning to peaceful silence.
Uploading and Running the Program
Upload the program to the device, and then open the serial monitor. Try entering the value 1000 - you should hear a moderately loud but not overwhelmingly loud sound.
Continue the experiment by inputting different frequencies and observing how the sound changes. If you attempt to achieve frequencies at the limits of audibility in this experiment, you may be disappointed because the loudspeaker likely has its own, even narrower range of sound production, and sound volume sharply declines at frequencies exceeding about 10 kHz. Small loudspeakers also usually cannot reproduce sounds with a frequency lower than 100 Hz.
SINE WAVE AND SQUARE WAVE
The sound emitted by the loudspeaker when connected directly to the Arduino output is harsh and unnatural. This is because the digital output can only be in an on or off state, and the resulting sound wave is square in shape. Compared to the smoother and more sinusoidal sound wave of a musical instrument, a square wave sound wave is considered quite unnatural (see image below).
To make the generated sound louder, you need to increase the power delivered to the loudspeaker. In other words, the signal needs amplification.
In the setup described in the "Experiment: Loudspeaker Without an Amplifier on Arduino" section, you can significantly boost the sound's power emitted by the loudspeaker using a transistor. This allows you to make the sound louder and more pleasant.
However, if you need to create a smoother sound wave, for instance, for music or speech, the principle of toggling the sound signal on and off, which may lead to unpleasant sound, is no longer suitable. In such cases, a real sound amplifier is required.
You can build an amplifier yourself, but it's much easier to use ready-made devices or a pair of speakers with a built-in amplifier, such as those used with personal computers. This is especially convenient when working with a Raspberry Pi since you can easily connect them to the Raspberry Pi's audio jack.
We will delve further into this approach later when Pepe the Doll (from the "Project: Dancing Pepe Doll on Raspberry Pi" section) gains a voice.
In the setup described in the "Experiment: Loudspeaker Without an Amplifier on Arduino" section, you can significantly boost the sound's power emitted by the loudspeaker using a transistor. This allows you to make the sound louder and more pleasant.
However, if you need to create a smoother sound wave, for instance, for music or speech, the principle of toggling the sound signal on and off, which may lead to unpleasant sound, is no longer suitable. In such cases, a real sound amplifier is required.
You can build an amplifier yourself, but it's much easier to use ready-made devices or a pair of speakers with a built-in amplifier, such as those used with personal computers. This is especially convenient when working with a Raspberry Pi since you can easily connect them to the Raspberry Pi's audio jack.
We will delve further into this approach later when Pepe the Doll (from the "Project: Dancing Pepe Doll on Raspberry Pi" section) gains a voice.
WAV audio files can be played on Arduino using the hardware described in the "Experiment: Loudspeaker Without an Amplifier on Arduino" section and the Arduino library called PCM (Pulse Code Modulation). This library employs a technology somewhat akin to Pulse Width Modulation (PWM) to generate vibrations capable of producing sound.
The Arduino's flash memory allows for approximately 4 seconds of recording. If you need to play longer audio clips, you'll need to add an SD card reader to the Arduino and follow the recommendations provided on the Arduino website at [https://www.arduino.cc/en/Tutorial/SimpleAudioPlayer](https://www.arduino.cc/en/Tutorial/SimpleAudioPlayer).
We will record the sound on a computer using the Audacity software package, and then run a utility that converts the audio file into a series of numbers corresponding to the sound. This data can then be inserted into an Arduino program for playback.
The original article describing this approach to sound playback can be found on the High-Low Tech website ([http://highlowtech.org/?p=1963](http://highlowtech.org/?p=1963)). Our experiment differs slightly from this description as we use the freely available Audacity application for audio recording.
Hardware and Software
In this experiment, you will use the same hardware as described in the "Experiment: Loudspeaker Without an Amplifier on Arduino" section. However, you will need to install the following software on your computer to record and process audio clips:
- Audacity application: [audacityteam.org](https://www.audacityteam.org/).
- Audio Encoder utility - you can find a link to the version for your operating system on the website [highlowtech.org/?p=1963](http://highlowtech.org/?p=1963).
Creating an Audio File
Note: If you don't wish to record your own audio clip, you can skip ahead to the "Uploading and Running the Program" section included in this experiment, which contains a pre-encoded small audio block.
To create an audio file, launch the Audacity program, set the recording mode to mono and select a project rate of 8000 Hz.
Click the red "Record" button to start recording, and record your message. Note that the recording should not exceed one second. Once the recording is completed, you will see a waveform image in the Audacity window. You can select any "silent" portion at the beginning or end of the recording and delete it, leaving only the desired part of the audio block.
The recorded sound needs to be exported to the correct format, and this requires specific settings. Choose "File" from the menu, then select "Export Audio." In the drop-down menu, choose "Other uncompressed files," go to the "Format options" section, and set the format to "WAV (Microsoft)" and "Unsigned 8-bit PCM" as shown in the image below. Give the file a name and skip the page prompting you for artist information.
The file you've just generated is in binary format. It needs to be converted into a list of comma-separated numbers in text form so that it can be inserted into our program. To do this, run the Audio Encoder utility downloaded from the website [highlowtech.org](http://highlowtech.org). It will prompt you to select the file for conversion - choose the file that was just exported from Audacity.
After a few seconds, a dialog will appear, confirming that all the data is in your clipboard. Open the /arduino/experiments/wav_arduino program and replace the entire line starting with the sequence 125, 119, 115, with the data from your clipboard. This is a very long line, so it's best to select it by placing the cursor at the beginning of the line and, while holding the Shift key, move the cursor down to the end of the line. To replace the selected text with the data from the clipboard, use the "Insert" option from the context menu. If you were to graph all the inserted numbers, the shape would resemble what you saw in Audacity when recording the audio clip.
Arduino Program
Before compiling and running the program, you need to install the PCM library. Download the ZIP archive from GitHub (https://github.com/damellis/PCM/zipball/master), unzip it, rename the folder to "PCM," and move it to your Arduino libraries directory.
The Arduino program (excluding the sound data) has a very modest size, but the data array is represented by a very long line!
Let's clarify some points about this sketch using the line markup provided in the comments:
1. The data is stored in an array of type `unsigned char`, consisting of eight-bit unsigned numbers. The `PROGMEM` command ensures that the data is stored in the Arduino's flash memory (which should have approximately 32 KB available).
2. Sound playback of the sample is accomplished using the PCM library. The `startPlayback` function is given the array of data to be played and the size of the data in bytes.
3. The sound clip is played once each time the Arduino is restarted, so the `loop` function remains empty.
Uploading and Running the Program
Upload the program to your Arduino, and as soon as the upload is complete, the sound clip will be played!
Right after uploading the program, in the bottom part of the Arduino IDE, you'll see a message showing how much of the Arduino's flash memory was used, roughly similar to the following: "Binary sketch size: 11,596 bytes (of a 32,256 byte maximum)." If the sound file is too large, you'll receive an error message.
The Arduino's flash memory allows for approximately 4 seconds of recording. If you need to play longer audio clips, you'll need to add an SD card reader to the Arduino and follow the recommendations provided on the Arduino website at [https://www.arduino.cc/en/Tutorial/SimpleAudioPlayer](https://www.arduino.cc/en/Tutorial/SimpleAudioPlayer).
We will record the sound on a computer using the Audacity software package, and then run a utility that converts the audio file into a series of numbers corresponding to the sound. This data can then be inserted into an Arduino program for playback.
The original article describing this approach to sound playback can be found on the High-Low Tech website ([http://highlowtech.org/?p=1963](http://highlowtech.org/?p=1963)). Our experiment differs slightly from this description as we use the freely available Audacity application for audio recording.
Hardware and Software
In this experiment, you will use the same hardware as described in the "Experiment: Loudspeaker Without an Amplifier on Arduino" section. However, you will need to install the following software on your computer to record and process audio clips:
- Audacity application: [audacityteam.org](https://www.audacityteam.org/).
- Audio Encoder utility - you can find a link to the version for your operating system on the website [highlowtech.org/?p=1963](http://highlowtech.org/?p=1963).
Creating an Audio File
Note: If you don't wish to record your own audio clip, you can skip ahead to the "Uploading and Running the Program" section included in this experiment, which contains a pre-encoded small audio block.
To create an audio file, launch the Audacity program, set the recording mode to mono and select a project rate of 8000 Hz.
Click the red "Record" button to start recording, and record your message. Note that the recording should not exceed one second. Once the recording is completed, you will see a waveform image in the Audacity window. You can select any "silent" portion at the beginning or end of the recording and delete it, leaving only the desired part of the audio block.
The recorded sound needs to be exported to the correct format, and this requires specific settings. Choose "File" from the menu, then select "Export Audio." In the drop-down menu, choose "Other uncompressed files," go to the "Format options" section, and set the format to "WAV (Microsoft)" and "Unsigned 8-bit PCM" as shown in the image below. Give the file a name and skip the page prompting you for artist information.
The file you've just generated is in binary format. It needs to be converted into a list of comma-separated numbers in text form so that it can be inserted into our program. To do this, run the Audio Encoder utility downloaded from the website [highlowtech.org](http://highlowtech.org). It will prompt you to select the file for conversion - choose the file that was just exported from Audacity.
After a few seconds, a dialog will appear, confirming that all the data is in your clipboard. Open the /arduino/experiments/wav_arduino program and replace the entire line starting with the sequence 125, 119, 115, with the data from your clipboard. This is a very long line, so it's best to select it by placing the cursor at the beginning of the line and, while holding the Shift key, move the cursor down to the end of the line. To replace the selected text with the data from the clipboard, use the "Insert" option from the context menu. If you were to graph all the inserted numbers, the shape would resemble what you saw in Audacity when recording the audio clip.
Arduino Program
Before compiling and running the program, you need to install the PCM library. Download the ZIP archive from GitHub (https://github.com/damellis/PCM/zipball/master), unzip it, rename the folder to "PCM," and move it to your Arduino libraries directory.
The Arduino program (excluding the sound data) has a very modest size, but the data array is represented by a very long line!
Code: Select all
#include <PCM.h>
const unsigned char sample[] PROGMEM = {125, 119, 115, 115, 112, 116, 114, 113, 124, 126, 136, 145, 139}; //1
void setup() {
startPlayback(sample, sizeof(sample)); //2
}
void loop() { //3
}
Let's clarify some points about this sketch using the line markup provided in the comments:
1. The data is stored in an array of type `unsigned char`, consisting of eight-bit unsigned numbers. The `PROGMEM` command ensures that the data is stored in the Arduino's flash memory (which should have approximately 32 KB available).
2. Sound playback of the sample is accomplished using the PCM library. The `startPlayback` function is given the array of data to be played and the size of the data in bytes.
3. The sound clip is played once each time the Arduino is restarted, so the `loop` function remains empty.
Uploading and Running the Program
Upload the program to your Arduino, and as soon as the upload is complete, the sound clip will be played!
Right after uploading the program, in the bottom part of the Arduino IDE, you'll see a message showing how much of the Arduino's flash memory was used, roughly similar to the following: "Binary sketch size: 11,596 bytes (of a 32,256 byte maximum)." If the sound file is too large, you'll receive an error message.
Surprisingly, a recent experiment proved to be successful, even though it was accomplished using only Arduino.
The current of the sound signal coming from the Arduino is limited by a resistor. However, the 5V voltage supplied to the Arduino's output pin is too high to connect to the standard input of a sound amplifier. Therefore, when the need arises to connect Arduino to speakers for sound amplification, the first step should be to reduce the voltage at the output.
For this purpose, two resistors connected in a voltage divider configuration are suitable.
Voltage Divider
A voltage divider is a device that utilizes two resistors to decrease voltage. Unlike variable voltage, which changes according to the amplitude of the sound signal, a voltage divider reduces voltage in a fixed proportion.
For example, the diagram illustrates a voltage divider used to lower the 5V voltage from Arduino to a level suitable for the sound amplifier input, approximately 0.5V. The voltage at the junction of the two resistors (V) is calculated using the formula:
In this case, with a high signal level (HIGH) on the digital output and (Vin = 5V), (Vout = 5 x 1 / (1 + 10) = 0.45V).
You can utilize the breadboard from the "Experiment: Speaker Without an Amplifier on Arduino" section to connect to the amplifier. Position one resistor above the other, as shown in the diagram below, and connect the upper 10 kΩ resistor to pin D11, and the lower one to ground. Then, you only need to choose how to connect the contact wire to the GND line and the line where both resistors connect to the amplifier.
For this, you can use an amplifier input cable, cut it in half, and expose the wires at the ends so that they can be inserted into the slots on the breadboard. Typically, such a cable has three wires since most sound systems are designed to work with stereo signals. This means it has a common wire (GND) and two separate wires for the left and right audio channels (usually they are insulated in red and white).
You only need to find the common (GND) wire because it's better to combine the wires for the left and right channels so that the mono audio signal from Arduino is audible in both speakers. The common (GND) wire can be identified using a multimeter set in continuity check mode (see the image below).
Attach one of the multimeter probes to the farthest contact at the end of the audio cable plug. Then, sequentially touch the other multimeter probe to each of the three wires of the cable until you hear a sound from the multimeter or detect signs of continuity. This will be the common wire, which should be inserted into the slot of the GND contact line on the breadboard. The other two wires should be connected and inserted into the slot of the motherboard contact line, which serves as the output, the line where both resistors are connected.
Now, repeat one of the experiments conducted earlier in this chapter with Arduino, and you'll get a significantly louder and clearer sound.
The current of the sound signal coming from the Arduino is limited by a resistor. However, the 5V voltage supplied to the Arduino's output pin is too high to connect to the standard input of a sound amplifier. Therefore, when the need arises to connect Arduino to speakers for sound amplification, the first step should be to reduce the voltage at the output.
For this purpose, two resistors connected in a voltage divider configuration are suitable.
Voltage Divider
A voltage divider is a device that utilizes two resistors to decrease voltage. Unlike variable voltage, which changes according to the amplitude of the sound signal, a voltage divider reduces voltage in a fixed proportion.
For example, the diagram illustrates a voltage divider used to lower the 5V voltage from Arduino to a level suitable for the sound amplifier input, approximately 0.5V. The voltage at the junction of the two resistors (V) is calculated using the formula:
In this case, with a high signal level (HIGH) on the digital output and (Vin = 5V), (Vout = 5 x 1 / (1 + 10) = 0.45V).
You can utilize the breadboard from the "Experiment: Speaker Without an Amplifier on Arduino" section to connect to the amplifier. Position one resistor above the other, as shown in the diagram below, and connect the upper 10 kΩ resistor to pin D11, and the lower one to ground. Then, you only need to choose how to connect the contact wire to the GND line and the line where both resistors connect to the amplifier.
For this, you can use an amplifier input cable, cut it in half, and expose the wires at the ends so that they can be inserted into the slots on the breadboard. Typically, such a cable has three wires since most sound systems are designed to work with stereo signals. This means it has a common wire (GND) and two separate wires for the left and right audio channels (usually they are insulated in red and white).
You only need to find the common (GND) wire because it's better to combine the wires for the left and right channels so that the mono audio signal from Arduino is audible in both speakers. The common (GND) wire can be identified using a multimeter set in continuity check mode (see the image below).
Attach one of the multimeter probes to the farthest contact at the end of the audio cable plug. Then, sequentially touch the other multimeter probe to each of the three wires of the cable until you hear a sound from the multimeter or detect signs of continuity. This will be the common wire, which should be inserted into the slot of the GND contact line on the breadboard. The other two wires should be connected and inserted into the slot of the motherboard contact line, which serves as the output, the line where both resistors are connected.
Now, repeat one of the experiments conducted earlier in this chapter with Arduino, and you'll get a significantly louder and clearer sound.