Speaker

The speaker included in the Photon kit can be used to produce tones or play simple music (note by note).

The speaker is a polarized part, meaning it has to be connected in a certain way to work properly. Specifically, the speaker has a positive pin and a negative pin. These can be identified by markings printed on the bottom of the speaker next to each pin.

Line up the speaker pins different numbered rows on the breadboard (be sure to remember which row has the positive pin), and push down to insert the speaker into the breadboard. Then plug jumper wires into the two rows with the speaker pins and connect them to the Photon.

Speaker

Photon Pin

Positive (+) pin

any I/O pin with PWM

Negative (-) pin

GND

IMPORTANT: The speaker's positive pin must connect to an I/O pin that supports pulse-width modulation (PWM) output. Only the following pins on the Photon can act as PWM outputs: D0, D1, D2, D3, A4, A5, WKP, RX, TX.

Experiment 5 in the online SparkFun Photon Experiment Guide shows how to connect the speaker. Here is the connection diagram from Experiment 5:

Code for Speaker

Library

The speaker does not require any special code library.

Global Variables

In the global variables, you should declare which pin is being used as the speaker pin. The example below declares a variable called "speakerPin" (but you could use a different variable name).

// if necessary, change data pin number to match your wiring
int speakerPin = D2;

setup( ) function

Within the setup() function, you have to include a statement to set the pin mode for the speaker pin variable:

pinMode(speakerPin, OUTPUT);

Produce a Tone

Code for producing tones with the speaker could be placed within the setup() function (runs only once), within the loop() function, or within a custom function.

The speaker uses the tone() function to produce a sound of a specific frequency for a specific duration of time.

The speaker can produce tones ranging in frequency from 20Hz (very low pitch) to 20KHz (very high pitch), which covers the full range of sounds that humans can hear.

NOTE: There is no built-in function to change the volume of the sound. However, you will notice that certain frequencies (in the mid-range) will naturally seem louder.

The tone() function requires 3 values: speaker pin number, frequency, and duration. These values can be listed in the function as integer numbers or as integer variables.

int frequency = 2000;
int duration = 500;

tone(speakerPin, frequency, duration);

FREQUENCY

The frequency should be an integer value ranging from 20-20000 (20Hz to 20KHz). Lower numbers will have a lower pitch (more bass). High numbers will have a higher pitch (more treble).

int duration = 500;

// low-pitched sound
tone(speakerPin, 100, duration);

// medium-pitched sound
tone(speakerPin, 2000, duration);

// high-pitched sound
tone(speakerPin, 8000, duration);

Note: The range of sounds that humans can hear naturally diminishes with age (starting as early as 18). As people get older, they become less able to hear high-frequency sounds. Everyone (regardless of age) should be able to hear sounds up to a frequency of 8000Hz. However, sounds above this frequency may not be heard by certain adults depending on their age range (so keep this in mind when building a product that uses sound).

DURATION

The duration should be an integer value representing the number of milliseconds to play the tone (1000 milliseconds = 1 second). The Photon device will play the tone for the designated duration and then automatically turn the speaker off again.

Note: Using a duration of 0 (zero) will cause the speaker to produce a continuous tone.

int frequency = 2000;

// play sound for 0.1 seconds
tone(speakerPin, frequency, 100);

// play sound for 0.5 seconds
tone(speakerPin, frequency, 500);

// play sound for 2 seconds
tone(speakerPin, frequency, 2000);

// play continuous sound
tone(speakerPin, frequency, 0);

Stop Playing Tone

You can use the notone() function to turn the speaker off. This is not normally needed since a tone will automatically stop playing after the designated duration.

However, if you are playing a continuous tone (duration = 0) or simply want to turn off the speaker, use the notone() function.

// turn off speaker
notone(speakerPin);

Play Music Note by Note

Try out this example app that plays a song. Do you recognize the song?

If you can figure out the notes and beats to a song, you can change the code below for songNotes and songBeats to play that song. Be sure to update the songLength value, and adjust the tempo value if necessary.

int speakerPin = D2;

// "songNotes" is array of characters corresponding to notes in song (space = rest)
char songNotes[] = "cdfda ag cdfdg gf ";

// "songLength" must equal the total number of notes and rests in your "songNotes"
int songLength = 18;

// "songBeats" is array of values for each note and rest in your "songNotes"
// 1 = quarter note, 2 = half note, 4 = whole note
int songBeats[] = {1,1,1,1,1,1,4,4,2,1,1,1,1,1,1,4,4,2};

// "tempo" is how fast to play the song. To play song faster, decrease this value.
int tempo = 150;

void setup() {
    pinMode(speakerPin, OUTPUT);
}

void loop()  {
    playSong();
    delay(500);
}

// CUSTOM FUNCTION - plays song note by note
void playSong() {
    int duration;
    for (int i = 0; i < songLength; i++) { 
        duration = songBeats[i] * tempo;
        if (songNotes[i] == ' ') {
            // if rest, pause without playing sound
            delay(duration);
        } else {
            // else play note by calling custom function to convert note to frequency
            tone(speakerPin, getFrequency(songNotes[i]), duration);
            // wait for note to finish
            delay(duration);
        }
        // brief pause between notes
        delay(tempo/10);
    }   
}

// CUSTOM FUNCTION - returns matching frequency for a note
int getFrequency(char note) {

    // These arrays hold the note characters and their corresponding frequencies
    // The last "C" note is uppercase to separate it from the first lowercase "c"
    // If you want to add more notes to convert, you'll need to use unique characters
    char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
    int frequencies[] = {262, 294, 330, 349, 392, 440, 494, 523};

    // number of notes stored in the "names" array
    int numNotes = 8;

    // Search through letters in array to find matching note and return frequency for that note
    for (int i = 0; i < numNotes; i++) {
        if (names[i] == note) {
            return(frequencies[i]);
        }
    }
    // if note not found, return value of 0
    return(0);
}

Did you figure out the song? 😎

Last updated