2

Is there a method to play a Melody with Tone() without using the delay() function?

tone(8, melody[thisNote], noteDuration);
int pauseBetweenNotes = noteDuration;
**delay(pauseBetweenNotes);**
asked Oct 31, 2015 at 11:46
1
  • 2
    Yes. The same method as is used in the BlinkWithoutDelay example sketch. Commented Oct 31, 2015 at 12:14

3 Answers 3

4

As others have noted, this can be done using the same method as used in the standard 'BlinkWithoutDelay' example sketch, and combining that with a state-machine type approach. In a simple state machine you'd assume you can be in one of two states: outputting a tone, and not outputting a tone.

Applying these ideas to your code snippet above:

// BEFORE SETUP
const int tonePin = 8;
unsigned long previousMillis = 0;
const long interval = pauseBetweenNotes;
const long interval = noteDuration;
boolean outputTone = false; // Records current state
// IN LOOP
unsigned long currentMillis = millis();
if (outputTone) {
// We are currently outputting a tone
// Check if it's been long enough and turn off if so
 if (currentMillis - previousMillis >= noteDuration) {
 previousMillis = currentMillis;
 noTone(tonePin);
 outputTone = false;
 }
} else {
// We are currently in a pause
// Check if it's been long enough and turn on if so
 if (currentMillis - previousMillis >= pauseBetweenNotes) {
 previousMillis = currentMillis;
 tone(tonePin, melody[thisNote]);
 outputTone = true;
 }
}
answered Jul 7, 2016 at 4:57
0
1

Adding a bit to kabdulla's great example, to be able to use a MelodyArray

// declaring variables
const int tonePin = 10;
unsigned long previousMillis = 0;
const long pauseBetweenNotes = 250; // interval between notes (ms)
const long noteDuration = 400; // (ms)
boolean outputTone = false; // Records current state
const int MelodyLength = 2;
const int Melody[MelodyLength] = {880, 698};
int MelodyIndex = 0;
unsigned long currentMillis;
void setup() {
}
void loop() {
 currentMillis = millis();
 PlayMelody();
}
void PlayMelody() {
 if (outputTone) {
 // We are currently outputting a tone
 // Check if it's been long enough and turn off if so
 if (currentMillis - previousMillis >= noteDuration) {
 previousMillis = currentMillis;
 noTone(tonePin);
 outputTone = false;
 }
 } else {
 // We are currently in a pause
 // Check if it's been long enough and turn on if so
 if (currentMillis - previousMillis >= pauseBetweenNotes) {
 previousMillis = currentMillis;
 tone(tonePin, Melody[MelodyIndex]);
 outputTone = true;
 //Update to play the next tone, next time
 MelodyIndex = MelodyIndex + 1;
 if (MelodyIndex >= MelodyLength) {
 MelodyIndex = 0;
 }
 }
 }
}
answered Dec 27, 2020 at 20:02
1

this is a minimal modification of the basic Arduino toneMelody example to a non-blocking version

#include "pitches.h"
// notes in the melody:
int melody[] = {
 NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
 4, 8, 8, 4, 4, 4, 4, 4
};
unsigned long previousMillis = 0;
unsigned long pauseBetweenNotes;
int thisNote;
void setup() {
}
void loop() {
 // iterate over the notes of the melody:
 unsigned long currentMillis = millis();
 if (thisNote < 8 && currentMillis - previousMillis >= pauseBetweenNotes) {
 previousMillis = currentMillis;
 // 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 = 1000 / noteDurations[thisNote];
 tone(8, melody[thisNote], noteDuration);
 // to distinguish the notes, set a minimum time between them.
 // the note's duration + 30% seems to work well:
 pauseBetweenNotes = noteDuration * 1.30;
 
 thisNote++;
 }
}
answered May 22, 2022 at 17:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.