How to use Tone Melody with flashing LEDs?? (BlinkWithoutDelay example)

#include "pitches.h"
 
const int ledbot = 12;
const int ledtop = 11;
int ledState = LOW;
unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;    
unsigned long previousMillis3 = 0;
boolean outputTone = false;    
 
int spooky[] = {
  NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, NOTE_C3, NOTE_A2, NOTE_A2, NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2,
  0, NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, NOTE_C3, NOTE_A2, NOTE_A2, NOTE_C3, NOTE_D3, NOTE_B2, NOTE_C3, NOTE_A2
};
 
int spookynoteDurations[] = {
  4, 4, 4, 4, 4, 8, 3, 4, 8, 3, 4, 4, 2, 2, 4, 4, 4, 4, 4, 8, 3, 4, 4, 4, 4, 4, 2
};
 
void setup() {
  pinMode(ledbot, OUTPUT);
  pinMode(ledtop, OUTPUT);
  pinMode(8, OUTPUT);
};
 
void loop() {
 
  outputTone = true;
    unsigned long currentMillis = millis();
for (int thisNote = 0; thisNote < (sizeof(spookynoteDurations)/2); thisNote++)
  {
int spookynoteDuration = 1000 / spookynoteDurations[thisNote];
int pauseBetweenNotes = spookynoteDuration * 1.35;
if (outputTone) {
 
    if (currentMillis - previousMillis >= spookynoteDuration) {
        previousMillis = currentMillis;
        noTone(8);
        outputTone = false;
    }
} else {
   
    if (currentMillis - previousMillis2 >= pauseBetweenNotes) {
        previousMillis2 = currentMillis;
        tone(8, spooky[thisNote]);
        outputTone = true;
    }
        if (currentMillis - previousMillis3 >= pauseBetweenNotes) {
    previousMillis3 = currentMillis;
    {
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledbot, ledState);
    digitalWrite(ledtop, ledState);
    }
    }
}
  }
}

This is my code for the song Spooky Scary Skeletons. What's supposed to happen is that whenever a note plays, two LEDs flash. What ends up happening is that only one note plays and the LEDs blink. Can anyone tell me what I did wrong? I've searched on google and tried lots of codes, but none of them seemed to work for me.

You are going wrong by using the for loop. This in effect just ruins the structure of the code.
You have two states playing a tone and the gap between them. I assume you only want to flash the LEDs when playing. You have a third task of advancing the note being played. You need to implement that in a state machine.

Grumpy_Mike:
You are going wrong by using the for loop. This in effect just ruins the structure of the code.
You have two states playing a tone and the gap between them. I assume you only want to flash the LEDs when playing. You have a third task of advancing the note being played. You need to implement that in a state machine.

Thanks for the advice, I've gotten rid of my for loop but I'm not sure how I'd use a state machine to advance the notes.. Could you possibly provide an example?

See all about state machines here:-
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html

#include "pitches.h"

const int ledbot = 12;
const int ledtop = 11;
int ledState = LOW; 
unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;    
const int buttonPin = 4;
int buttonState = 0;
boolean outputTone = false;    
int note = 0;
int song_go = 500;
int leds_go = 500;
unsigned long currentMillis = millis();
  
int spooky[] = {
  NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, NOTE_C3, NOTE_A2, NOTE_A2, NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, 
  0, NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, NOTE_C3, NOTE_A2, NOTE_A2, NOTE_C3, NOTE_D3, NOTE_B2, NOTE_C3, NOTE_A2
};

int spookynoteDurations[] = {
  4, 4, 4, 4, 4, 8, 3, 4, 8, 3, 4, 4, 2, 2, 4, 4, 4, 4, 4, 8, 3, 4, 4, 4, 4, 4, 2
};

int spookynoteDuration = 1000 / spookynoteDurations[note];
int pauseBetweenNotes = spookynoteDuration * 1.35;

void setup() {
  Serial.begin(57600);
  pinMode(ledbot, OUTPUT);
  pinMode(ledtop, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(8, OUTPUT);
};

void loop() {
   
   buttonState = digitalRead(buttonPin);   
   if (buttonState == HIGH)   {
  
  outputTone = true;
if (millis() >= song_go) {

  play_spooky();
}
  if (millis() >= LEDs) {
  LEDs();
  }
}
}

void LEDs() {
        
    if (currentMillis - previousMillis2 >= pauseBetweenNotes) {
    previousMillis2 = currentMillis;
    {
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledbot, ledState);
    digitalWrite(ledtop, ledState);
    }
    }
}

void play_spooky() {

note++;
if (note >= (sizeof(spookynoteDurations)/2)) note = 0;

if (outputTone) {
  
  Serial.println(note);

    if (currentMillis - previousMillis >= spookynoteDuration) {
        previousMillis = currentMillis;
        noTone(8);
        outputTone = false;
    }
} else {
    
    if (currentMillis - previousMillis2 >= pauseBetweenNotes) {
        previousMillis2 = currentMillis;
        tone(8, spooky[note]);
        outputTone = true;
    }

}
  }

I've changed some things but the speaker doesn't play a sound anymore.. Not sure if I approached this right. Any suggestions?

Not sure if I approached this right

I don't think it is either.
Why are you looking at a push button?

The structure is all wrong.
You need the top level of the loop to check the millis timer to see if it is time to change the note. That is either turn it off, or get the next note and turn it on. If it is time you do it and that function should return straight away.

Next you need to check if it is time to change the state of the LED if it is call the function that does that, but this time only if the note is playing, that is the tone variable is true.

Then the loop function ends.

You have the whole thing upside down, and what is more you set the tone variable as true each time round the loop.

#include "pitches.h"

const int ledbot = 12;
const int ledtop = 11;
int ledState = LOW; 
unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;    
const int buttonPin = 4;
int buttonState = 0;
boolean outputTone = false;    
int note = 1;
  
int spooky[] = {
  NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, NOTE_C3, NOTE_A2, NOTE_A2, NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, 
  0, NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, NOTE_C3, NOTE_A2, NOTE_A2, NOTE_C3, NOTE_D3, NOTE_B2, NOTE_C3, NOTE_A2
};

int spookynoteDurations[] = {
  4, 4, 4, 4, 4, 8, 3, 4, 8, 3, 4, 4, 2, 2, 4, 4, 4, 4, 4, 8, 3, 4, 4, 4, 4, 4, 2
};

int spookynoteDuration = 1000 / spookynoteDurations[note];
int pauseBetweenNotes = spookynoteDuration * 1.35;

void setup() {
  Serial.begin(57600);
  pinMode(ledbot, OUTPUT);
  pinMode(ledtop, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(8, OUTPUT);
};

void loop() {
   
   buttonState = digitalRead(buttonPin);   
   if (buttonState == HIGH)   {
    
    unsigned long currentMillis = millis();
    digitalWrite(ledbot, ledState);
    digitalWrite(ledtop, ledState);
    
    if (outputTone == false) {
    if (currentMillis - previousMillis2 >= pauseBetweenNotes) { // LED turns on, tone plays
    previousMillis2 = currentMillis;
    {  
  tone(8, spooky[note]);
  outputTone = true;
  ledState = HIGH;
    }
    }
    }

if (outputTone == true) { // when tone plays
  
    if (currentMillis - previousMillis >= spookynoteDuration) { // stops the note playing when it reaches this time (original duration * 1.35) pretty much the duration of the note
        previousMillis = currentMillis;
        noTone(8); 
        ledState = LOW;
        note++;
        if (note >= (sizeof(spookynoteDurations)/2)) note = 0; // progresses the note array to move onto the next note
        outputTone = false;       
    }

}


  // data
  
  {
  if (outputTone == true) {
  Serial.println("outputTone = true");
  }
  else
  {
  Serial.println("outputTone = false");
}
  }
Serial.println(note);

  }
}

I've made changes according to what you said. The speaker makes a weird tapping noise and the LEDs do not light up. Looking at the Serial monitor with the data, the note array progresses but outputTone stays false.. Sorry if I still am not understanding what you're trying to say, I'm really new to coding haha. Thanks for being so patient.

I've made changes according to what you said.

No you haven't.

Have you read that link in reply #3?

The structure is still nowhere even close.

It will help you if you just concentrate on getting the tune to play first and worry about the lights later. It will also help if you use functions to break up the code so you can see the structure better.

You need to set a time for the next change and check if that time has expired. If it has then do the change, that is turning the note on or off and set the time for the next change. If it has not do nothing, that is finish the loop.

I skimmed it haha,
I read it carefully this time and I realized missed some important things..
I got my program to work but it seems to play the notes 3 at a time then has a weird rest longer than the delays in the middle.. I don't really know how to explain it but I'm just curious as to why this is happening. Thank you very much by the way!

#include "pitches.h"

const int ledbot = 12;
const int ledtop = 11;
int ledState = LOW; 
unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;    
const int buttonPin = 4;
int buttonState = 0;
boolean outputTone = false;    
int note = 1;
long int goTime, stopTime;
int spooky[] = {
  NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, NOTE_C3, NOTE_A2, NOTE_A2, NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, 
  0, NOTE_F3, NOTE_F3, NOTE_E3, NOTE_E3, NOTE_A2, NOTE_C3, NOTE_A2, NOTE_A2, NOTE_C3, NOTE_D3, NOTE_B2, NOTE_C3, NOTE_A2
};

int spookynoteDurations[] = {
  4, 4, 4, 4, 4, 8, 3, 4, 8, 3, 4, 4, 2, 2, 4, 4, 4, 4, 4, 8, 3, 4, 4, 4, 4, 4, 2
};


int nextTime1 = 1000 / spookynoteDurations[note];
int nextTime2 = nextTime1 * 1.35;

 
void setup() {
  Serial.begin(57600);
  pinMode(ledbot, OUTPUT);
  pinMode(ledtop, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(8, OUTPUT);
  goTime = millis();
  stopTime = millis();
};

void loop() {
   
   buttonState = digitalRead(buttonPin);   
   if (buttonState == HIGH)   {
    
    if (millis() >= goTime) spookygo();
    if (millis() >= stopTime) spookyrest();
    
    digitalWrite(ledbot, ledState);
    digitalWrite(ledtop, ledState);

  // data

Serial.println(note);
Serial.println(nextTime1);
   }
}

void spookygo() {
 
  tone(8, spooky[note]);
    ledState = HIGH;
  goTime = millis() + nextTime1;
};

void spookyrest() {
        noTone(8); 
        ledState = LOW;
        note++;
        if (note >= (sizeof(spookynoteDurations)/2)) note = 0; // progresses the note array to move onto the next note
        stopTime = millis() + nextTime2;
        };

Close but not right. There should be only one timer running at any one time.
You need one routine that will toggle the tone and based on if the tone is on or off set the time for the next entry into the toggle tone function.

It finally works! Thank you so much!