Question on Interactive Display Case Project

Hello all,
I'm not real experienced with programming but I'm trying to work through it.. I have a working sketch but I'm wanting to change a certain behavior and I can't figure out how to do it. Basically it's beyond my current skill.

I'm working on a display that will be going in a childrens museum. The idea is simple. It's an interactive display case. 4 items are on display. User opens one of 4 doors. Each door has it's own switch. Opening a door triggers a mp3 player to play a specific mp3 file and also switches a relay to light the associated object in the display. The relay stays on until the mp3 is finished playing and then turns off. The mp3 can send a serial hex command of 0xFF when it is done so the sketch waits for this to happen and then turns off the relay.

I have this working ok, but I would like it to be possible to interrupt a playing file when a different door is opened. My sketch right now currently does nothing until a the file is done playing.

// Super Hero Gadgets

// MP3s - 01 = Bat Sprays, 02 = Utility Belt, 03 = Bat Phone, 04 = Robin's Vest 

int relay1 = 2; // Bat Sprays
int relay2 = 3; // Utility Belt
int relay3 = 4; // Bat Phone
int relay4 = 5; // Robin's Vest
int button1 = 6;  // Bat Sprays
int button2 = 7;  // Utility Belt
int button3 = 8;  // Bat Phone
int button4 = 9;  // Robin's Vest
int button1state = 0;
int button2state = 0;
int button3state = 0;
int button4state = 0;




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

pinMode(button1, INPUT);
digitalWrite(button1, HIGH);
pinMode(button2, INPUT);
digitalWrite(button2, HIGH);
pinMode(button3, INPUT);
digitalWrite(button3, HIGH);
pinMode(button4, INPUT);
digitalWrite(button4, HIGH);
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);
}

void loop(){
  int button1state = digitalRead(button1);
  int button2state = digitalRead(button2);
  int button3state = digitalRead(button3);
  int button4state = digitalRead(button4);
  
  if(button1state == LOW){
    batSprays();
  }
  if (button2state == LOW){
    utilityBelt();
  }
  if (button3state == LOW){
    batPhone();
  }
  if (button4state == LOW){
    robinVest();
  }
    else{
    idle();
  }
    

} // end loop


void idle() { // for when game is idle. 
  Serial.println("idle");
  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
  digitalWrite(relay3, LOW);
  digitalWrite(relay4, LOW);
}


  
void batSprays(){
  
  Serial.println("Bat Sprays");
  digitalWrite(relay1, HIGH);  // turn on the light
  Serial.write(0x01);  // play the bat spray file
  while (Serial.available() >= 0)     // wait music to finish playing
  {
    int input = Serial.read();        // Read the input
    if (input == 0xFF){    
      break;                          // If file finished then break
    } 
  }
}


void utilityBelt(){
  Serial.println("Utility Belt");
  digitalWrite(relay2, HIGH);  // turn on the light
  Serial.write(0x02);  // play the utility best file
  while (Serial.available() >= 0)     // wait music to finish playing
  {
    int input = Serial.read();        // Read the input
    if (input == 0xFF) {    
      break;                          // If file finished then break
    }
  }
}


void batPhone(){
  Serial.println("Bat Phone");
  digitalWrite(relay3, HIGH);  // turn on the light
  Serial.write(0x03);  // play the bat phone file
  while (Serial.available() >= 0)     // wait music to finish playing
  {
    int input = Serial.read();        // Read the input
    if (input == 0xFF) {    
      break;                          // If file finished then break
    }
  }
}


void robinVest(){
  Serial.println("Robin Vest");
  digitalWrite(relay4, HIGH);  // turn on the light
  Serial.write(0x04);  // play the robins vest file
  while (Serial.available() >= 0)     // wait music to finish playing
  {
    int input = Serial.read();        // Read the input
    if (input == 0xFF) {    
      break;                          // If file finished then break
    }
  }
}

One thought I had to make it possible to iterupt the playing of one file/light by opening a different door was to add this to each of the functions: (add an OR || to each if statement that triggers the break.

void batSprays(){
  
  Serial.println("Bat Sprays");
  digitalWrite(relay1, HIGH);  // turn on the light
  Serial.write(0x01);  // play the bat spray file
  while (Serial.available() >= 0)     // wait music to finish playing
  {
    int input = Serial.read();        // Read the input
    if ((input == 0xFF) || (button2state == LOW) || (button3state == LOW)  || (button4state == LOW)) {    
      break;                          // If file finished then break
    } 
  }
}

But when I do this, the relay totally freaks out when the button is pressed. It basically switches on and off so fast it just sounds like a buzzer so something is obviously wrong. I'm not even sure if the logic is correct. I'm new to 'while' loops.

Any help would be greatly appreciated! Hope this makes sense. I'd be glad to elaborate on anything that's not clear.

Thanks

Opening a door triggers a mp3 player to play a specific mp3 file

What mp3 player are you using? How is it connected to the Arduino?

  Serial.println("Bat Sprays");
  digitalWrite(relay1, HIGH);  // turn on the light
  Serial.write(0x01);  // play the bat spray file
  while (Serial.available() >= 0)     // wait music to finish playing
  {
    int input = Serial.read();        // Read the input

This looks like the mp3 player is connected to the serial port, and assumes that there will be an immediate response from the device, and that the response will be a continuous stream of data that ends with 0xFF when the track ends.

Seems unlikely to me that either of those assumptions is correct.

One thought I had to make it possible to iterupt the playing of one file/light by opening a different door was to add this to each of the functions: (add an OR || to each if statement that triggers the break.

If your earlier assumptions are correct, the values of buttonNstate do not change in the while loop. So, they will never trigger the break.

Hello,
Thanks for reading. Yes, I am communicating with the mp3 player via serial on TX and RX pins. It is a MDFLY unit. http://bit.ly/1k3ExTw. PDF Manual http://bit.ly/1pX2XNG

There is a table in the manual that lists some common HEX commands and it lists 0xFF as "when song ends" but that's about all I know about that functionality.

Do you have any suggestions on how to possibly approach this in a different way? I have messed around with this same concept in a few different ways, i.e. switch case and also not relying on the 0xFF from the mp3 player at all by using delays or predetermined lengths and for loops etc etc. Had similar difficulties. I felt like this was the cleanest and most logical way to go about this, but I am far from any kind of expert on this stuff.

Thanks!