The Arduino Inventor's Guide (49 page)

BOOK: The Arduino Inventor's Guide
13.18Mb size Format: txt, pdf, ePub

Assemble the circuit as shown in the diagram. The circuit is fairly simple. First, connect 5 V and GND to the power and ground rails on the left side of the breadboard. Next, add the buzzer roughly 10 rows down from the top of the breadboard. Connect one leg of the buzzer to pin 9 of the Arduino and the other leg of the buzzer to the ground rail. Then, insert the SoftPot near the bottom of the breadboard. Connect the top pin of the SoftPot to the 5 V power rail, the lower pin to the ground rail, and the middle pin to the analog input pin A0 on the Arduino. Remember that the SoftPot requires a pull-down resistor between the wiper pin (middle pin) and the ground rail. Finally, add a 10 kΩ resistor between the middle pin and the ground rail.

Once you have it built, it’s time to try a couple of code examples.

PROGRAM THE TINY ELECTRIC PIANO

First, you’ll test the build by having the buzzer make noises and recognizable tones, and then you’ll map those noises and tones to the SoftPot. Once you know how to get your code making sounds, we’ll show you how to add functionality so that you can play up to eight distinct notes, like a small piano.

You’ve already seen that the Arduino can generate really fast pulses and react to split-second button presses. With your circuit wired up, you’ll use these capabilities to make some fun sounds and test the frequency response of the buzzer.

Test the Buzzer

Arduino has a few commands that make playing notes really simple. There are two functions that control making sounds with Arduino:
tone()
, which tells the buzzer to play a frequency you specify, and
noTone()
, which tells the buzzer to stop the sound so you can control the length of the note. Here’s how you use these two functions.

//creates a tone of
frequency
on
pin
for a
duration
in ms
tone
(
pin
,
frequency
,
duration
);
//stops the playing of a tone on the given pin
noTone
(
pin
);

The
tone()
function needs to be called with three parameters: the pin number the buzzer is connected to, a frequency you want to play, and the duration to play the note. When called,
tone()
creates a square wave at the frequency you provided on the defined pin for a specific duration. This square wave triggers the vibration of the disc inside the buzzer connected to this pin, creating a sound at that frequency. Once started,
tone()
continues for the duration specified or until you call either another
tone()
command with a different frequency or the
noTone()
command to stop the Arduino from playing.

Copy the code from
Listing 10-1
into the Arduino IDE or download the sketch from
https://www.nostarch.com/arduinoinventor/
. In this example, you’ll use the Serial Monitor to choose a frequency, and the buzzer will play that tone for half a second.

LISTING 10-1:
Serial tone test code

  
//Serial Tone Test Example
  
//Upload this example and then open the Serial Monitor
  
int
freq;
  
void
setup
()
  {

   
pinMode
(9,
OUTPUT
);
    
Serial
.
begin
(9600);
    
Serial
.
println
(
"Type in a frequency to play."
);
  }
  
void
loop
()
  {

   if(
Serial
.
available
() > 0)  
//wait for a serial
                                
//input string
    {

    freq =
Serial
.
parseInt
();  
//parse out integer value
      
Serial
.
print
(
"Playing note: "
);  
//user feedback
      
Serial
.
println
(freq);

    
tone
(9, freq, 500);  
//play the note for 500 ms

    
delay
(500);  
//delay for the note duration
    }
    
else
    {
      
noTone
(9);
    }
  }

Let’s take a look at how this all works. In the
setup()
, the sketch sets the
pinMode

for the GPIO pin on the buzzer, initializes the serial communication on the Arduino, and prints a short message instructing the player on what to do.

Next, inside the
loop()
, the
if(Serial.available() > 0)
statement

checks for data sent over serial communication like so:
Serial.available()
returns the number of bytes received from the Serial Monitor, and the
if()
statement compares that value to zero; if the number of bytes is greater than zero, it means data was received, and the script reads the data

. The
Serial.parseInt()
function converts the data into an integer, which is then stored in the variable
freq
.

The code plays the frequency stored in
freq
for 500 ms using the
tone()
function

and then has a short
delay()

. The
delay()
ensures that the note plays for the full 500 ms before starting another note. The
tone()
command is a
nonblocking function
: it executes and then continues to the next instruction without waiting.

After uploading this sketch to your device, open the Serial Monitor (
CTRL
-
SHIFT
-M or
Tools

Serial Monitor
). Then, click the line-ending-character drop-down list (
Figure 10-10
), and select
No line ending
. When you send data between digital devices, an invisible
end-of-line (EOL)
character is sometimes used to indicate the end of a message. The two most commonly used EOL characters are the
new line (NL)
and
carriage return (CR)
. While the character may appear to be invisible, to the Arduino this character still reads in as a value. Selecting this option makes sure that it doesn’t send any extra characters.

Now, in the box at the very top, you can type any number and press
ENTER
, and the buzzer will play that note for half a second (500 ms). The range of human hearing is about 20 Hz to 20,000 Hz, so play around with some different frequencies, but keep them within that range.

FIGURE 10-10:
Open the Serial Monitor, and change this option to
No line ending
.

The serial communication on the Arduino has a buffer 64 bytes long. A
buffer
is like a waiting line for the data as it goes into the device, and in this case it allows you to send several notes at a time using the Serial Monitor. For example, you can play the song “Twinkle, Twinkle, Little Star” by typing in the following numbers, separated by commas without spaces. The last comma is important, too. The
Serial.parseInt()
command looks for numeric characters that are separated by non-numeric characters like commas. The Arduino needs to see that last token (the final comma) to parse out the final note.

262,262,392,392,440,440,392,392,349,349,330,330,294,294,262,262,

Make sure to omit the spaces here. Each character is equal to 1 byte of data, and if you try to send more than the maximum 64 bytes at a time, the last few pieces of data will get cut off.

Lastly, the buzzer is optimized at 2,047 Hz. You may notice that when you try this frequency the buzzer is very,
very
loud and can be annoying, so be warned: people around you may not appreciate the high-pitched tones that come out of this buzzer at 2,047 Hz!

Create Specific Notes

If you want to try something more traditional, you can correlate actual musical notes to frequencies. Many instruments use a reference point of middle C, which has a frequency of about 262 Hz.
Table 10-1
shows a short table of frequencies for an octave of the C major scale.

TABLE 10-1:
Notes and frequencies of the C major scale

NOTE

APPROXIMATE FREQUENCY

C

262

D

294

E

330

F

349

G

392

A

440

B

494

C

524

Experiment and see if you can play a song. To start you off, “Twinkle, Twinkle, Little Star” begins with the notes CC, GG, AA, GG, FF, EE, DD, CC. You may notice that the sounds the Arduino makes aren’t the most melodic. This is because the Arduino can only turn the pin either
HIGH
(on) or
LOW
(off). This creates a square wave, which has a tinny pitch. There are some tricks you can do using capacitors to create a noise filter to soften this sound, but that’s a topic for another book!

Generate Sound with the SoftPot

Making music with frequencies is fun, but typing them over and over gets really tedious. Instead, you can use the SoftPot as a sensor whose values will correspond to frequencies for the buzzer.

The SoftPot is wired up with a simple voltage divider so that a pressure on the length of the strip will be translated into a voltage
from 0 to 5 V. Remember that the Arduino can translate an analog voltage from 0 to 5 V to a value of
0
to
1023
using the
analogRead()
function. Using the simple sketch in
Listing 10-2
, you can send frequencies to the buzzer by pressing the SoftPot. When the SoftPot is not pressed, the value defaults to
0
because of the pull-down resistor, so no sound is produced.

Start a new Arduino sketch, copy the code example from Listing 10-2, and upload it to your device.

LISTING 10-2:
Noisemaker example code

  
//Noisemaker Example
  
//upload this example, open the Serial Monitor,
  
//and then squeeze the SoftPot

int
sensorValue;
  
void
setup
()
  {
    
pinMode
(9, OUTPUT);
    
Serial
.
begin
(9600);
  }
  
void
loop
()
  {

   sensorValue =
analogRead
(A0);

   
if
(sensorValue > 0)    
//if there's a press on sensor,
                            
//play note
    {

    
Serial
.
print
(
"Raw sensor reading: "
);
     
Serial
.
println
(sensorValue);

    
tone
(9, sensorValue,

50);
     
delay
(

50);
    }

    
else
    {
      
noTone
(9);
    }
  }

Let’s take a look at what’s going on in this sketch. You again start by declaring a variable to store the raw sensor reading

. In the loop, the
analogRead()
function reads the voltage on pin A0

and assigns this value to the variable
sensorValue
. This value will be 0 V when no pressure is applied. You use an
if()
statement

to check if the input value is greater than
0
, and if it is, the sketch prints the raw sensor value

and uses the
tone()
command

to play the value stored in
sensorValue
. If the sketch is getting stuck playing a note, try changing the
0
in the
if()
statement to a larger number
like
10
or
20

. This is a technique called
setting a deadband range
. Some sensors don’t always go back to a zero value, so this deadband sets a range of values that the program can still consider to be zero. Each sensor may be slightly different.

Other books

Six Dead Men by Rae Stoltenkamp
A Stranger's Touch by Anne Herries
Entangled by Cat Clarke
The Girl in the Glass Tower by Elizabeth Fremantle
Bad Moon Rising by Ed Gorman
The Machine Awakes by Adam Christopher