If loop stops iterating

Hey guys!

I'm trying to make a little arduino setup that does a few things. Spin a fan and spin a motor through PWM, and then also play a tune through a little piezo speaker. I have my code so that the fan and motor work fine, and I harvested a bit of code from the Arduino reference page to make the speaker work.

I want to have it so that you press the button a few times, it'll start up the fan and the motor, and play a song, which works great. However, after it's played the song, the button counter stops going up and any further changes to the system and speed of the above components doesn't happen. I've tried a few different versions of this with curly brackets at different point in the program but I can't make it play the song, and then continue on to the next section in the if loop to change the speed of the fan and the motor. Any guidance would be super appreciated.

Thanks in advance :)!

const int buzzerPin = 9;
const int songLength = 15;
char notes[] = "dfD dfD eFeFeca "; // a space represents a rest
int beats[] = {1,1,3,1,1,1,3,1,3,1,1,1,1,1,3,1};

const int  buttonPin = 2;
int tempo = 150;

int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;

int motorPin = 11;
int fanPin = 4; 


void setup() 
{
  pinMode(buzzerPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(motorPin, OUTPUT);
  pinMode(fanPin, OUTPUT); 
  Serial.begin(9600);
}


void loop() 
{
  buttonState = digitalRead(buttonPin);

  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;
  
  if (buttonPushCounter == 3)
  {
  int i, duration;
  
  for (i = 0; i < songLength; i++) // step through the song arrays
  {
    duration = beats[i] * tempo;  // length of note/rest in ms
    
    if (notes[i] == ' ')          // is this a rest? 
    {
      delay(duration);            // then pause for a moment
    }
    else                          // otherwise, play the note
    {
      tone(buzzerPin, frequency(notes[i]), duration);
      delay(duration);            // wait for tone to finish
    }
    delay(tempo/10);              // brief pause between notes
    analogWrite (motorPin, 50);
    analogWrite(fanPin, 50);
    
    //i guess i've just gotta add a bit in here to keep reading the button. 
  }
  
  while(true){} //play song once.

  
  }
  
  if (buttonPushCounter == 6)
  {
    
    analogWrite (motorPin, 200);
    analogWrite (fanPin, 100);
  }
}


int frequency(char note) 
{  
  int i;
  const int numNotes = 8;  // number of notes we're storing
       char names[] = { 'd', 'f', 'D', 'e', 'F', 'c', 'a' };
  int frequencies[] = {294, 349, 587, 659, 698, 523, 440 };  
  for (i = 0; i < numNotes; i++)  // Step through the notes
  {
    if (names[i] == note)         // Is this the one?
    {
      return(frequencies[i]);     // Yes! Return the frequency
    }
  }
  return(0); 
}

Do you remember typing half that sketch in italics?
No, I thought not.

Please edit the post and add the [code][/code] tags you forgot.

Ahh, my bad! Sorry!

  while(true){} //play song once.

Comment should read: "Do nothing, forever".

  while(true){} //play song once.

How is the program going to get out of this while loop ? The comment is right. Once the song has played once this line stops it, and everything else, from happening again.

Oh, gotcha. That makes a lot of sense. What should I put in there instead? Some prelim googling points me in the direction of NoTone(), does that sound about right?

theriver:
Oh, gotcha. That makes a lot of sense. What should I put in there instead? Some prelim googling points me in the direction of NoTone(), does that sound about right?

Why do you need to do anything? You've told the tone() function how long to play each note. It won't return until that time is up. When it does, there will be no sound coming from the speaker.

At the end of the loop that plays the notes, that is what you want. So, you don't NEED to do anything.