Input/Output - Advanced
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);
}
}