Chapter 15. Sound

Having looked at movement, light, heat, and displays, it’s time to turn our attention to making sound.

High-quality audio is easy on the Raspberry Pi because powered speakers can be attached to the audio jack, but things are a little more difficult with the Arduino. 

 

Experiment: Unamplified Speaker and Arduino

Ultimately, if you want to make any kind of complex sound, you are going to need some kind of loudspeaker. Loudspeakers have been around for almost 100 years and work a little like a solenoid (see “Solenoids”) that pushes a rigid cone at a high enough frequency to make sound waves.

Loudspeakers are generally marked with a value in ohms. This value is like their resistance but is actually their impedance. Impedance, as the word suggests, is like resistance but applies to things that are not pure resistors and the coil of wire in the speaker (like any coil) does not act quite like a resistor. If you are interested in such things, read up on inductance

Common values for a loudspeaker are 4Ω or 8Ω. If you were to connect an 8Ω speaker to the 5V output of an Arduino, you could reasonably expect a current of I = V / R = 5 / 8 = 625mA. That’s a lot more than the 40mA recommended for an Arduino output pin. It looks like we need a resistor!

In this experiment, you will connect up a speaker to an Arduino via a resistor and then use the Serial Monitor to instruct the Arduino to produce sound of a particular frequency.

Parts List

You really don’t need much for this experiment, just a speaker and resistor, although some breadboard and jumper wires make it easier to connect things up:

Part Sources
Small 8Ω speaker

Adafruit: 1891

270Ω 1/4 W resistor Mouser: 291-270-RC
400-point solderless breadboard

Adafruit: 64

Male-to-male jumper wires Adafruit: 758

The speaker that I used was scavenged from an old radio receiver and had a connector on the end into which a male-to-male jumper wire could be inserted. You may find a speaker with wires attached that will push into the breadboard or Arduino sockets, or you might have to solder some leads on with wires that are thin enough to fit into breadboard holes.

Breadboard Layout

Figure 15-1 shows the setup for the experiment. 

Figure 15-1. Arduino and speaker

One connection to the speaker is connected to an Arduino GND socket and the other is connected via the resistor to pin D11.

Arduino Software

Here’s the sketch for this project, which you will find in /arduino/experiments/ex_speaker (for information on installing the Arduino sketches for this book, see “The Book Code” in Chapter 2):

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
  }
}

The part of this code that might look unfamiliar to you is inside loop().

1

tone sets one of the output pins of the Arduino to play a tone at the frequency specified (in this case, the frequency that you typed into the Serial Monitor).

2

After a two-second delay, the noTone command cancels to tone, restoring a restful silence.

Arduino Experimentation

Upload the program and then open the Serial Monitor.  Try entering 1000. This should produce a not particularly pleasant sound, at a reasonable volume, but not loud enough to be heard in a noisy room.

Experiment entering different frequencies and see how the note changes.

Although it might be tempting to try and test the frequency range of your hearing with this setup, sadly this won’t work because the speaker is quite likely to have a restricted range itself. At frequencies over about 10kHz, the level of sound it produces will fall off very sharply. Similarly, a small speaker will not normally be able to produce sound below about 100Hz. 

Amplifiers

If you  need your sound to be louder, then you need to supply more power to your speaker. In other words, you need to amplify the signal so that more power reaches the loudspeaker.

In the kind of setup you had in “Experiment: Unamplified Speaker and Arduino”, you could get a lot more power into the speaker using a single transistor as if you were switching a relay or motor on and off. Your ugly noise will still be an ugly noise, but a much louder ugly noise.

If you need to generate a nicer waveform (say for music or speech), then the on/off approach is going to sound pretty awful and you would need to look at using a proper audio amplifier.

While you could make your amplifier from scratch, it’s a lot easier to use a ready-made module or even just a set of powered speakers intended to sit next to your PC. Using powered (amplified) speakers is especially attractive when it comes to the Raspberry Pi, as the aux lead can just plug into the Raspberry Pi’s audio socket.

You will use this approach later in this chapter when you give  Pepe the Puppet (from “Project: Pepe, the Dancing Raspberry Pi Puppet”) a voice in “Project: Pepe the Puppet Gets a Voice”.

Experiment: Playing Sound Files on an Arduino

You can actually play WAV sound files on an Arduino using the hardware from “Experiment: Unamplified Speaker and Arduino” and an Arduino library called PCM (pulse code modulation). This uses a technique a bit like PWM to generate an approximation to the sound. The Arduino only has enough flash memory for about 4 seconds of recording. If you want to play longer sound clips than this, you will need to add an SD card reader to the Arduino and use an approach like the one described on the Arduino website.

You can record the sound onto your computer using the software package Audacity and then run a utility program to convert the sound file into a series of numbers that represent the sound and can be pasted into an Arduino sketch and then played back. 

The original article that describes this approach is at High-Low Tech. This experiment differs a little in that it uses the free Audacity software package to record an audio clip.

Parts List

The hardware for this experiment is just the same as “Experiment: Unamplified Speaker and Arduino”. However, you will need to install the following software on your computer to be able to record and process an audio clip:

Creating the Sound Data

If you do not want to record your own sound clip, you can jump ahead to “Arduino Experimentation” and run the ex_wav_arduino sketch that has a short message encoded in it.

To create the sound file, you first need to start Audacity. Before making your recording, set the recording mode to Mono and the Project Rate to 8000Hz. These options are highlighted in Figure 15-3.

Figure 15-3. Recording a sound clip

Click the red Record button to start recording and record your message. Note that this cannot be longer than about 4 seconds. Once you have recorded the message, you will see the sound wave in Audacity. You can select any silent area at the start or end and delete it, to just leave the part of the message that you want.

The next step is to export the sound file. Again this requires certain options to be set. From the File menu, select Export. Then in the Format dropdown, select “Other uncompressed files,” and click Options, and select WAV (Microsoft) and Unsigned 8 bit PCM (Figure 15-4). Select a filename and continue past the screen that prompts you for details of the artist.

The file that you have just generated is binary data. This needs to be converted into a list of text numbers, each separated by commas, that can be pasted into your sketch. To do this, run the Audio Encoder utility that you downloaded from highlowtech.org. This will prompt you to select the file you want to convert, so select the file that you just exported from Audacity.

After a few moments, you will be shown a dialog window confirming that all the data is in your clipboard.

Open up the sketch /arduino/experiments/wav_arduino. You are going to replace the whole of the line that starts with 125, 119, 115 with the data in the clipboard. This is a very long line, so the best way to select it is to put the cursor at the start of the line, and then hold the Shift key down while you cursor down and then left one place. Use the Paste option to replace the selected text with the data in your clipboard.

Figure 15-4. Setting export options

If you plotted each of those numbers on a chart, the shape you would see would be the same as you saw in Audacity when you were recording a sound clip.

Arduino Code

Before you can compile and run the sketch, you will need to install the PCM library. Download the ZIP archive for the file from GitHub; unzip it, rename the folder to just PCM, and move it into your Arduino libraries folder, as described in “Installing Arduino Libraries” in Chapter 12.

The Arduino sketch (if you ignore the sound data) is tiny:

#include <PCM.h>

const unsigned char sample[] PROGMEM = {   // 1
125, 119, 115, 115, 112, 116, 114, 113, 124, 126, 136, 145, 139, 
}; 

void setup() {
  startPlayback(sample, sizeof(sample));  // 2
}

void loop() { // 3
}

However, that array of data is a very long line!

1

The data is held in an array of type char, which contains 8-bit unsigned numbers. The PROGMEM command ensures that the data is stored in the flash memory of the Arduino (there should be about 32kB available).

2

The PCM library plays the sample. startPlayback is passed the array of data to be played and the size of that data in bytes.

3

The sound clip is played once each time the Arduino resets, so the loop() function is empty. 

Arduino Experimentation

Install the sketch onto your Arduino and as soon as it installs, the sound clip will play!

As you upload the sketch, you will see a message at the bottom of the Arduino IDE that tells you how much of the Arduino’s flash memory was used. It will say something like “Binary sketch size: 11,596 bytes (of a 32,256 byte maximum).” If the sound file gets too big, you will get an error message.

Connecting an Arduino to an Amplifier

The previous experiment works surprisingly well, given that it is only running on a humble Arduino.

The audio signal coming from the Arduino may be fed through a resistor to keep the current low, but the Arduino pin is operating at 5V, which is too high to act as the input to a typical audio amplifier. So to connect an Arduino to a set of powered speakers to make the sound louder, ironically we first need to reduce its output voltage.

A very convenient way of doing that is to use a pair of resistors as a voltage divider.

Figure 15-5. A voltage divider

You can adapt the breadboard for “Experiment: Unamplified Speaker and Arduino”, placing one resistor above the other as shown in Figure 15-6, with the top of the 10kΩ resistor connected to D11 and the bottom of the bottom resistor connected to GND. You then just need a way of connecting GND and the breadboard row where the resistors meet to the amplifier.

Figure 15-6. Attaching an Arduino to an aux lead

One way to make this connection is to sacrifice an aux lead, cutting it in half and stripping the wires inside the lead to make the connection. Generally you will find three wires, as most leads are stereo. There will be one ground wire, and separate wires for the left and right audio channels. The left and right channels are often red and white. 

The only lead that you really need to identify is the ground lead, because the left and right leads are best connected together so that the mono signal from the Arduino is heard from both speakers. You can identify the ground lead using a multimeter set to its continuity (or buzzer) mode (Figure 15-7).

Figure 15-7. Testing the aux lead

Clip or touch one of the multimeter leads to the connection of the plug furthest from the plug tip. Then try each of the three leads in turn until the multimeter beeps (or otherwise indicates that there is a connection). That lead is the ground lead and can push into the ground row of the breadboard. The other two leads can be twisted together and go into the output row of the breadboard where the two resistors meet.

Try re-running one of the Arduino experiments earlier in this chapter and you should have a much louder and clearer result.

Playing Sound Files on Raspberry Pi

The Raspberry Pi is a fully fledged computer with an audio output jack. So, playing a sound file on a Raspberry Pi is a matter of finding the right software package to play a sound file. 

There are various methods for doing this, but a StackExchange discussion covers pretty much all of them.

The method I use here is to use the pygame Python library that is already installed on the Raspberry Pi.

WAV files, while a lot bigger in file size than MP3s, have the great advantage that they are very easy for a Raspberry Pi to decode and so don’t slow down your Pi much. Whereas “Arduino Experimentation” was quite fussy about the WAV files that it will play, the Raspberry Pi is not limited by memory or processor speed when it come to playing a sound file, so almost any WAV file should play OK.

You can try this out from the Python command line using the sound file that you will use in “Project: Pepe the Puppet Gets a Voice”. On your Raspberry Pi command line, change directory to the file downloads for the book and within that to the python/projects/puppet_voice folder. In there you will find a file called pepe_1.wav. To play this file, connect powered speakers or headphones to the audio socket on your Raspberry Pi and then start the Python console using the command python:

>>> from pygame import mixer
>>> mixer.init()
>>> mixer.music.load("pepe_1.wav")
>>> mixer.music.play()

You should hear a short message from Pepe.

Project: Pepe the Puppet Gets a Voice

Now that you can make your Raspberry Pi play sound files, you can combine this with “Project: Pepe, the Dancing Raspberry Pi Puppet” and a PIR sensor to make Pepe dance and talk whenever someone comes close to him (Figure 15-8).

Figure 15-8. Pepe with movement detection and voice

Parts List

To make this project, you will need all the parts from “Project: Pepe, the Dancing Raspberry Pi Puppet” and the following extra components:

Part Sources
Passive infrared (PIR) sensor module

eBay, Adafruit: 189

Female-to-male jumper wires

Adafruit: 826

Powered speakers  
400-point solderless breadboard Adafruit: 64

PIR sensors are used to detect movement in intruder alarms. This low-cost module is ideal for triggering Pepe when someone comes near. Adding the PIR sensor makes it worthwhile to add a breadboard to hold the servo driver board and wires to the PIR sensor.

Breadboard Layout

In this project, the breadboard provides a firm anchor for the wires to the PIR module and for the servo controller board that will plug directly into the breadboard. Most breadboards have a self-adhesive pad on the underside that you can use to stick it onto the servo chassis to make things a bit more permanent. Figure 15-9 illustrates the breadboard layout for the project, and Figure 15-10 shows the actual wiring of the project.

Figure 15-9. The breadboard layout for the talking puppet
Figure 15-10. The talking puppet 

The PIR sensor has a 3V digital output, but requires a 5V power supply. This makes it ideal for use with a Raspberry Pi.

Software

The software for this project is based on “Project: Pepe, the Dancing Raspberry Pi Puppet”, so you may want to look at that description of the code too.

You can find all the files for this project in the directory python/projects/puppet_voice. As well as the the Adafruit servo code and the program itself (puppet_voice.py), you will also find a sound file here called pepe_1.wav. This is the sound file that will be played when Pepe is triggered by movement:

from Adafruit_PWM_Servo_Driver import PWM  
import RPi.GPIO as GPIO
from pygame import mixer
import time

PIR_PIN = 23     1
GPIO.setmode(GPIO.BCM)
GPIO.setup(PIR_PIN, GPIO.IN)

pwm = PWM(0x40)
mixer.init()     2
mixer.music.load("pepe_1.wav")

servoMin = 150  # Min pulse length out of 4096     
servoMax = 600  # Max pulse length out of 4096

dance = [     
  #lh  lf  rf  rh
  [130, 20, 20, 130],
  [30, 160, 160, 30],    
  [90, 90, 90, 90]
]

delay = 0.2   
  
def map(value, from_low, from_high, to_low, to_high):  
  from_range = from_high - from_low
  to_range = to_high - to_low
  scale_factor = float(from_range) / float(to_range)
  return to_low + (value / scale_factor)
  
  
def set_angle(channel, angle):  
  pulse = int(map(angle, 0, 180, servoMin, servoMax))
  pwm.setPWM(channel, 0, pulse)
  
def dance_step(step):  
  set_angle(0, step[0])
  set_angle(1, step[1])
  set_angle(2, step[2])
  set_angle(3, step[3])
  
def dance_pupet():     3
    for i in range(1, 10):
        for step in dance:
            dance_step(step)
            time.sleep(delay)
    
pwm.setPWMFreq(60)   


while True:  
  if GPIO.input(PIR_PIN) == True:    4
      mixer.music.play()
      dance_pupet()
      time.sleep(2)
1

The first new bit of code is the code to set pin 23 to be a digital input.

2

There is also some initialization code to start the mixer ready to play the sound clip.

3

The new function dance_puppet is used to make the puppet repeat the dance steps 10 times.

4

If the PIR sensor is activated (pin 23 is True), then the music track playing and dancing is started. The music.play function does its work in the background.

Using the Talking Puppet

You can record a new sound clip to play using the Audacity software that you may have used in “Arduino Experimentation”. Just replace the file pepe_1.wav. You could also really go to town on this project and record a number of different sound clips to be played at random, or customized to the time of day.

Summary

In this chapter, you learned how to use sound with an Arduino and Raspberry Pi.

In the final chapter of this book, we will explore the use of Arduino and especially Raspberry Pi in the Internet of Things. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset