Intro to Physical Computing Syllabus

Research & Learning

Other Class pages

Shop Admin

ITP Help Pages
Tom's pcomp site
DanO's pcomp site


Tone Output using an Arduino

Overview

This lab is an introduction to generating simple tones on an Arduino using Brett Hagman's Tone library

1.  Parts

For this lab you'll need:

Solderless breadboard
Solderless breadboard
hookup wire
22-AWG hookup wire
Arduino module
Arduino Microcontroller
module


resistors
10Kohm resistors
photocell
photocell
(or a different
form of variable resistor)
speaker
8-ohm speaker


2.  Why not use AnalogOut()?

When you use analogOut() to create pulsewidth modulation (PWM) on an output pin, you can change the on-off ratio of the output (also known as the duty cycle) but not the frequency. If you have a speaker connected to an output pin running analogOut(), you'll get a changing loudness, but a constant tone. To change the tone, you need to change the frequency. The Tone library does this for you.

3.  Prepare the breadboard

Connect power and ground on the breadboard to power and ground from the microcontroller. On the Arduino module, use the 5V and any of the ground connections:


4.  Connect the sensors and the speaker

Connect two photoresistors to analog pin 0 in a voltage divider circuit as shown below. The 8-ohm speaker connects to pin 8 of the Arduino. You can use any digital I/O pin if you don't like 8. The other end of the speaker connects to ground.

NOTE: this sensor circuit is not the normal way of connecting an analog input. There is no fixed resistor. The two photocells act as a voltage divider together, ao you can change the value of the analog in by covering either one. if you are using variable resistors that can both go to 0 ohms, you should connect a fixed resistor in series from the junction of the two resistors to the input, to avoid a short.

5.  Check the sensor input range

Once you've got the circuit connected, check the range of the analog input with the following code:

 void setup() {
   Serial.begin(9600);
 }

 void loop() {
   int sensorValue = analogRead(0);
   Serial.println(sensorValue, DEC);
 }

Note the range that the sensors give you by alternately covering them up and giving them full light, with the serial monitor window all the time. You'll need the maximum and minimum sensor values for the next sketch.

6.  Download and install the Tone library

Download the Tone library. Quit the Arduino application, unzip the downloaded file, and put the unzipped folder in the /libraries folder of your Arduino sketch folder (it'll most likely be at ~/Documents/Arduino/libraries/, that's the default location).

Restart the arduino application. From the File menu, choose Examples, and you should see a new sub-menu for Tone. If not, check to make sure you downloaded and installed the Tone library in the right place, and restart Arduino.

7.  Play Tones

The sketch below takes input from the photocells and uses it to generate tones on the speaker. Upload it to your Arduino, and see the effect.

 /*
   Theremin
  
  Plays tones based on a sensor reading
  uses Tone library by Brett Hagman
  http://code.google.com/p/arduino-tone/
  
  circuit:
  * photoresistor from +5V to analog in 0
  * photoresistor from analog pin 0 to ground
  * 8-ohm speaker on digital pin 8
  
  created 10 Sep 2009
  by Tom Igoe 
  */

 #include <Tone.h>   
 Tone noiseMaker;    // instance of the tone library

 void setup() {
   // start the music:
   noiseMaker.begin(8);
 }

 void loop() {
   // get a sensor reading:
   int sensorReading = analogRead(0);
   // map the results from the sensor reading's range
   // to the desired pitch range:
   int pitch = map(sensorReading, 200, 900, 100, 1000);
   // change the pitch:
   noiseMaker.play(pitch);
 }

8.  A more complex example

The Tone library includes constants that give you the pitches for a standard western scale. Here's an example that uses them to play a simple melody:

 /*
   circuit:
   8-ohm speaker on digital pin 8
  */

 #include <Tone.h>   
 Tone noiseMaker;    // instance of the tone library
 int notes[] = {
   NOTE_D4, NOTE_E4,NOTE_C4,NOTE_C3,NOTE_G3 };
 int durations[] = {
   500, 500, 500, 500, 1000};
 void setup() {
   // start the music:
   noiseMaker.begin(8);
 }

 void loop() {
   for (int thisNote = 0; thisNote < 5; thisNote ++) {
     // play the next note:
     noiseMaker.play(notes[thisNote]);
     // hold the note:
     delay(durations[thisNote]);
     // stop for the next note:
     noiseMaker.stop();
   }
   // hold before repeating:
   delay(3000);
 }

Here's an example of how to use the note constants to make a simple keyboard:

The circuit:

This circuit uses the more traditional voltage divider circuit.

 /*
  
  circuit:
  * 3 force-sensing resistors from +5V to analog in 0 through 5
  * 3 10K resistors from analog in 0 through 5 to ground
  * 8-ohm speaker on digital pin 8
  
  */

 #include <Tone.h>   
 Tone noiseMaker;    // instance of the tone library
 const int threshold = 10;    // minimum reading of the sensors that generates a note

 // notes to play, corresponding to the 3 sensors:
 int notes[] = {
   NOTE_A4, NOTE_B4,NOTE_C4 };

 void setup() {
   // start the music:
   noiseMaker.begin(8);
 }

 void loop() {
   for (int thisSensor = 0; thisSensor < 3; thisSensor++) {
     // get a sensor reading:
     int sensorReading = analogRead(thisSensor);
     // if the sensor is pressed hard enough:
     if (sensorReading > threshold) {
       // play the note corresponding to this sensor:
       noiseMaker.play(notes[thisSensor]);
     } 
     else {
       // stop playing:
       noiseMaker.stop(); 
     }
   }
 }

9.  Make an Instrument

This is a suggestion for the Media Controller assignment. You can do any project you wish as long as it demonstrates your mastery of the lab exercises and good physical interaction. This is just one suggestion.

Now that you've got the basics, make a musical instrument. Consider a few things in designing yor instrument:

  • Do you want to play discrete notes (like a piano), or sliding pitches (like a theremin)? How do you program to achieve these effects?
  • Do you want to control the tempo and duration of a note?
  • Do you want the same physical action to set both the pitch and the velocity (volume) of a note?
  • Do you want to be able to play more than one note at a time (e.g. chords)?

All of these questions, and many more, will affect what sensors you use, how you read them, and how you design both the physical interface and the software.

  Edit | View | History | Print | Recent Changes | Search Page last modified on October 01, 2009, at 01:51 PM