Input/Output - Advanced

tone()

tone

Generates a square wave of the specified frequency and duration (and 50% duty cycle) on a timer channel pin which supports PWM. Use of the tone() function will interfere with PWM output on the selected pin. tone() is generally used to make sounds or music on speakers or piezo buzzers.

// SYNTAX
tone(pin, frequency, duration)

tone() takes three arguments, pin: the pin on which to generate the tone, frequency: the frequency of the tone in hertz and duration: the duration of the tone in milliseconds (a zero value = continuous tone).

The frequency range is from 20Hz to 20kHz. Frequencies outside this range will not be played.

tone() does not return anything.


Gen 3 Devices (nRF52) (B-Series SoM, Tracker SoM, Tracker One, Boron, Argon, and E404X):

On Gen 3 Feather devices (Argon, Boron, Xenon), pins A0, A1, A2, A3, D2, D3, D4, D5, D6, and D8 can be used for tone(). Pins are assigned a PWM group. Each group must share the same frequency. Thus you can only output 3 different frequencies at the same time.

  • Group 3: Pins D2, D3, A4, and A5.

  • Group 2: Pins A0, A1, A2, and A3.

  • Group 1: Pins D4, D5, D6, and D8.

On the Boron SoM, pins D4, D5, D7, A0, A1, A6, and A7 can be used for PWM. Pins are assigned a PWM group. Pins are assigned a PWM group. Each group must share the same frequency.

  • Group 2: Pins A0, A1, A6, and A7.
  • Group 1: Pins D4, D5, and D6.

On the Tracker SoM, pins D0 - D9 can be used for PWM. Pins are assigned a PWM group. Pins are assigned a PWM group. Each group must share the same frequency. Pins D8 and D9 can only be used for PWM if not being used for Serial1.

  • Group 2: D8 (TX), D9 (RX)
  • Group 1: D4, D5, D6, D7
  • Group 1: D0, D1, D2, D3

NOTE: The PWM pins / timer channels are allocated as per the following table. If multiple, simultaneous tone() calls are needed (for example, to generate DTMF tones), different timer numbers must be used to for each frequency:

On the Argon, Boron, and Xenon:

Pin Timer
A0 PWM2
A1 PWM2
A2 PWM2
A3 PWM2
A4 PWM3
A5 PWM3
D2 PWM3
D3 PWM3
D4 PWM1
D5 PWM1
D6 PWM1
D8 PWM1

On the B-Series SoM:

Pin Timer
A0 PWM2
A1 PWM2
A6 PWM2
A7 PWM2
D4 PWM1
D5 PWM1
D6 PWM1

On the Tracker SoM:

Pin Timer
D0 PWM0
D1 PWM0
D2 PWM0
D3 PWM0
D4 PWM1
D5 PWM1
D6 PWM1
D7 PWM1
D8 (TX) PWM2
D9 (RX) PWM2


Gen 4 Devices (RTL872x) (P2, Photon 2, and M-SoM):

All PWM compatible pins on the P2, Photon 2, and M-SoM share a single timer. Thus only one frequency of tone can be generated at a time.


Gen 2 Devices (STM32) (E-Series, Electron, Photon, and P2; does not include E404X):

  • On the Photon, P1 and Electron, this function works on pins D0, D1, D2, D3, A4, A5, WKP, RX and TX with a caveat: Tone timer peripheral is duplicated on two pins (A5/D2) and (A4/D3) for 7 total independent Tone outputs. For example: Tone may be used on A5 while D2 is used as a GPIO, or D2 for Tone while A5 is used as an analog input. However A5 and D2 cannot be used as independent Tone outputs at the same time.

  • Additionally on the Electron, this function works on pins B0, B1, B2, B3, C4, C5.

  • Additionally on the P1, this function works on pins P1S0, P1S1, P1S6 (note: for P1S6, the WiFi Powersave Clock should be disabled for complete control of this pin.

NOTE: The PWM pins / timer channels are allocated as per the following table. If multiple, simultaneous tone() calls are needed (for example, to generate DTMF tones), use pins allocated to separate timers to avoid stuttering on the output:

Pin TMR1 TMR3 TMR4 TMR5
D0 x
D1 x
D2 x
D3 x
A4 x
A5 x
WKP x
RX x
TX x

On the P1:

Pin TMR1 TMR3 TMR4 TMR5
D0 x
D1 x
D2 x
D3 x
A4 x
A5 x
WKP x
RX x
TX x
P1S0 x
P1S1 x
P1S6 x

On the Electron and E-Series:

Pin TMR1 TMR3 TMR4 TMR5 TMR8
D0 x
D1 x
D2 x
D3 x
A4 x
A5 x
WKP x
RX x
TX x
B0 x
B1 x
B2 x
B3 x
C4 x
C5 x


Additional information on which pins can be used for tone() is available on the pin information page.

#include "application.h"
// The Photon has 9 PWM pins: D0, D1, D2, D3, A4, A5, A7, RX and TX.
//
// EXAMPLE USAGE
// Plays a melody - Connect small speaker to speakerPin
int speakerPin = D0;

// Notes defined in microseconds (Period/2) 
// from note C to B, Octaves 3 through 7
int notes[] = 
{0,
/* C,  C#,   D,  D#,   E,   F,  F#,   G,  G#,   A,  A#,   B */
3817,3597,3401,3205,3030,2857,2703,2551,2404,2273,2146,2024,   // 3 (1-12)
1908,1805,1701,1608,1515,1433,1351,1276,1205,1136,1073,1012,   // 4 (13-24)
 956, 903, 852, 804, 759, 716, 676, 638, 602, 568, 536, 506,   // 5 (25-37)
 478, 451, 426, 402, 379, 358, 338, 319, 301, 284, 268, 253,   // 6 (38-50)
 239, 226, 213, 201, 190, 179, 169, 159, 151, 142, 134, 127 }; // 7 (51-62)

#define NOTE_G3  2551
#define NOTE_G4  1276
#define NOTE_C5  956
#define NOTE_E5  759
#define NOTE_G5  638
#define RELEASE  20
#define BPM      100

// notes in the melody:
int melody[] = {NOTE_E5,NOTE_E5,0,NOTE_E5,0,NOTE_C5,NOTE_E5,0,NOTE_G5,0,0,NOTE_G4};

// note durations: 4 = quarter note, 2 = half note, etc.:
int noteDurations[] = {4,4,4,4,4,4,4,4,4,2,4,4};

void setup() {
  // iterate over the notes of the melody:
  for (int thisNote = 0; thisNote < 12; thisNote++) {

    // to calculate the note duration, take one second
    // divided by the note type.
    // e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 60*1000/BPM/noteDurations[thisNote];
    tone(speakerPin, (melody[thisNote]!=0)?(500000/melody[thisNote]):0,noteDuration-RELEASE);

    // blocking delay needed because tone() does not block
    delay(noteDuration);
  }
}