Delay to Millis()

Hey!

For a project I need to make the following arduino setup:
I must have a piezo speaker that can play 5 songs. There is a button as well and if you press the button, the next song should start playing. But the problem is that in every song there is a delay which makes sure there are pauses between the notes so all the notes don't play at once. And because of this delay, I can't read the button state while the song is playing.
My question is: How can I convert this delay to millis() so that I CAN read the button state while the song is playing?

Thanks in advance! :slight_smile:

#include <pitches.h>

int nextSongButton = 8;
int previousSongButton = 7;
int piezoPin = 3;
int trackCount = 0;
int track_1_speed = 90;

int melody[] = {NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4};

int noteDurations[] = {4, 8, 8, 4, 4, 4, 4, 4};

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

pinMode(nextSongButton, INPUT);
pinMode(previousSongButton, INPUT);
pinMode(piezoPin, OUTPUT);
}

void loop() {
int nextSongB = digitalRead(nextSongButton);
int previousSongB = digitalRead(previousSongButton);

for (int thisNote = 0; thisNote < 8; thisNote++) {
int noteDuration = 1000 / noteDurations[thisNote];
tone(piezoPin, melody[thisNote], noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(piezoPin);
}
}

Good idea. Unfortunately, you cannot just replace delay(...) with millis().

I suggest that you learn from Using millis() for timing. A beginners guide

There is also an example Blink Without Delay that may be useful.

I did that, but I don't know how I can do it with my code :frowning:
I'm really stuck now so any help would be appreciated..

laurenzz:
I did that, but I don't know how I can do it with my code :frowning:
I'm really stuck now so any help would be appreciated..

Did you follow the link that was provided?

The demo Several Things at a Time illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

...R

Post your attempt to code this.

@aarg

You do know about social isolation don’t you ?

larryd:
@anon57585045
You do know about social isolation don’t you ?

I only wish.

In the examples I understand what they are doing with Millis(). I just don't know how I can implement the concept in my code. I am looking at this problem for several hours now and it is kinda driving me crazy as I don't know what to do :frowning:

Show us how ‘you tried’ to incorporate millis().

As I said, I really don't have an idea of what I should do, but here is some code I tried I know it makes no sense but I'm really stuck man..

#include <pitches.h>

int nextSongButton = 8;
int previousSongButton = 7;
int piezoPin = 3;
int trackCount = 0;
int track_1_speed = 90;

int melody[] = {NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4};

int noteDurations[] = {4, 8, 8, 4, 4, 4, 4, 4};

unsigned long previousMillis = 0;

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

pinMode(nextSongButton, INPUT);
pinMode(previousSongButton, INPUT);
pinMode(piezoPin, OUTPUT);
}

void loop() {
unsigned long currentMillis = millis();

int nextSongB = digitalRead(nextSongButton);
int previousSongB = digitalRead(previousSongButton);

for (int thisNote = 0; thisNote < 8; thisNote++) {
int noteDuration = 1000 / noteDurations[thisNote];
int pauseBetweenNotes = noteDuration * 1.30;
int readPiezoVal = digitalRead(piezoPin);
Serial.println(readPiezoVal);

if (currentMillis - previousMillis >= pauseBetweenNotes) {
previousMillis = currentMillis;
if (readPiezoVal > 0) {
noTone(piezoPin);
} else {
tone(piezoPin, melody[thisNote], noteDuration);
}
}
}
}

MusicWithoutDelay Library
NonBlockingRTTTL

Try this

 if (millis() - previousMillis >= pauseBetweenNotes) {
      previousMillis = millis();

Because you are using a FOR loop currentMillis is probably not being updated when it needs to be.

...R

PS ... When posting code please use the code button </>
codeButton.png

so your code 
looks like this

and is easy to copy to a text editor See How to use the forum

CHEAT:
Since the delay between notes is quite short, you may get away without millis()
Just ‘test’ your button and ‘break’ from the for-loop each time you run past the existing delay()

It’s not very stylish, but will save you a bit of work on such a simple sketch.

Give you more time to learn & rewrite the code - and build other projects.