Triggered

Current code, they’re messy, i know
#define BUTTON_COUNT 10 // number of buttons
#define COMBOBREAKER_COUNT 2 // number of buttons needed to be on to solve. THIS SHOULD BE  1 < n < BUTTON_COUNT
#define LED_PIN 13
#define LED_PIN_R 6
#define LED_PIN_G 9
#define LED_PIN_B 10
#define EXT_LIGHT_PIN 11
#include "Arduino.h"
#include "DFRobotDFPlayerMini.h"

#if (defined(ARDUINO_AVR_UNO) || defined(ESP8266))   // Using a soft serial port
#include <SoftwareSerial.h>
SoftwareSerial softSerial(/*rx =*/4, /*tx =*/5);
#define FPSerial softSerial
#else
#define FPSerial Serial1
#endif

/** Setup for buttons **/
const uint8_t buttonPins [BUTTON_COUNT] = {A0, A1, A2, A3, A4, A5, 2, 3, 7, 8}; // for 10 buttons
//const uint8_t buttonPins [BUTTON_COUNT] = {A0, A1, A2, A3}; // for 4 buttons

int buttonReadOuts [BUTTON_COUNT];
int lastButtonReadOuts [BUTTON_COUNT];
int combobreaker[BUTTON_COUNT];
int buttonStatuses [BUTTON_COUNT];

bool unlocked = false;
bool backdoor_unlock = false;

int randomizerIndex;
int randNumber1 = 0;
int temp;

int led_pulse = 0;
int pulse_rate = 15;
int pulse_direction = 1;
/** End setup for buttons **/

/** Setup for speakers **/
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);
int playIndex = 1;
int maxPlayIndex = 17;
/** End Setup for speakers **/

void setup()
{
Serial.begin(19200);
pinMode(LED_PIN, OUTPUT);
pinMode(LED_PIN_R, OUTPUT);
pinMode(LED_PIN_G, OUTPUT);
pinMode(LED_PIN_B, OUTPUT);
pinMode(EXT_LIGHT_PIN, OUTPUT);

for(int i = 0; i < BUTTON_COUNT; i++)
{
    pinMode(buttonPins[i], INPUT_PULLUP);
    buttonReadOuts[i] = 1;
    lastButtonReadOuts[i] = 1;
    buttonStatuses[i] = -1;
    if (i < COMBOBREAKER_COUNT)
    { combobreaker[i] = 1;} else 
    { combobreaker[i] = -1;}
}

randomSeed(analogRead(0));
randomizerIndex = 0;
digitalWrite(LED_PIN, HIGH);
unlocked = false;

// speakers
#if (defined ESP32)
    FPSerial.begin(9600, SERIAL_8N1, /*rx =*/D3, /*tx =*/D2);
#else
    FPSerial.begin(9600);
#endif

Serial.begin(115200);
Serial.println();
Serial.println(F("DFRobot DFPlayer Mini Demo"));
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

if (!myDFPlayer.begin(FPSerial, /*isACK = */true, /*doReset = */true)) {  //Use serial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true){
    delay(0); // Code to compatible with ESP8266 watch dog.
    }
}
Serial.println(F("DFPlayer Mini online."));

myDFPlayer.volume(30);  //Set volume value. From 0 to 30
myDFPlayer.play(1);  //Play the first mp3
}

void loop()
{
resetCombo(); 

for(int i = 0; i < BUTTON_COUNT; i++) 
{
    buttonReadOuts[i] = digitalRead(buttonPins[i]);
}

    printButtonStatuses();
    Serial.println(unlocked);

    unlocked = false;
    for(int i = 0; i < BUTTON_COUNT; i++)
    {
    if(combobreaker[i] == buttonStatuses[i])
    {
        unlocked = true;
    } else 
    {
        unlocked = false;
        break;
    }
    }

    if(unlocked)
    {
    lightsOff(); // solved! shut down the machine
    } else
    {
    // keep LED pulsing
    if(led_pulse + pulse_rate < 5 || led_pulse + pulse_rate > 250)
    {
        pulse_rate = -1*pulse_rate;
    }
    led_pulse = led_pulse + pulse_rate;
    analogWrite(LED_PIN_R, led_pulse);
    analogWrite(LED_PIN_G, led_pulse);
    analogWrite(LED_PIN_B, led_pulse);
    digitalWrite(EXT_LIGHT_PIN, LOW);

    for(int i = 0; i < BUTTON_COUNT; i++)
    {
        // when a button is pressed
        if(buttonReadOuts[i] == 1 && lastButtonReadOuts[i] == 0)
        {
            if(i == 1)
            {
            digitalWrite(EXT_LIGHT_PIN, HIGH);
            }

            blinkFast(); // red error lights
            pulse_rate = pulse_rate + 10; // increase fade rate
            buttonStatuses[i] = -1*buttonStatuses[i];
            if(playIndex == maxPlayIndex)
            {
            playIndex = 0;
            } else
            {
            playIndex = playIndex + 1;
            }
            myDFPlayer.play(playIndex);
        }
    }

    for(int i = 0; i < BUTTON_COUNT; i++) {
    lastButtonReadOuts[i] = buttonReadOuts[i];
    }
}

for(int i = 0; i < BUTTON_COUNT; i++)
{
    if(buttonReadOuts[i] == 0)
    {
    backdoor_unlock = true;
    } else 
    {
    backdoor_unlock = false;
    break;
    }
}

if(backdoor_unlock)
{
    for(int i = 0; i < BUTTON_COUNT; i++)
    {
        buttonReadOuts[i] = 1;
        lastButtonReadOuts[i] = 1;
        buttonStatuses[i] = -1;
    }
    randomSeed(analogRead(0));
    randomizerIndex = 0;
    digitalWrite(LED_PIN, LOW);
    delay(2000);
    digitalWrite(LED_PIN, HIGH);
    unlocked = false;
    backdoor_unlock = false;
}

delay(200);
}

void resetCombo() {
while (randomizerIndex < BUTTON_COUNT) {                                 //10 iterations
    randNumber1 = random(0,BUTTON_COUNT);
    temp = combobreaker[randNumber1];                    //temporary integer 
    combobreaker[randNumber1] = combobreaker[randomizerIndex];    //swapping the values
    combobreaker[randomizerIndex] = temp;                    //swapping the values
    randomizerIndex++;
    if (randomizerIndex == BUTTON_COUNT) {
    printresults();
    }
}
}

void printresults() {
Serial.println(combobreaker[0]);
Serial.println(combobreaker[1]);
Serial.println(combobreaker[2]);
Serial.println(combobreaker[3]);
}

void printButtonStatuses() {
for(int i = 0; i < BUTTON_COUNT; i++)
{
    Serial.print(i);
    Serial.print(": ");
    Serial.print(buttonStatuses[i]);
    Serial.print(", ");
    Serial.println(combobreaker[i]);
}
}

void blinkFast()
{
for(int i=0; i < 5; i++)
{
    analogWrite(LED_PIN_R, led_pulse);
    analogWrite(LED_PIN_G, 0);
    analogWrite(LED_PIN_B, 0);

    delay(50);

    analogWrite(LED_PIN_R, 0);
    analogWrite(LED_PIN_G, 0);
    analogWrite(LED_PIN_B, 0);

    delay(50);
}
}

void lightsOff()
{
digitalWrite(LED_PIN, LOW);
analogWrite(LED_PIN_R, 0);
analogWrite(LED_PIN_G, 0);
analogWrite(LED_PIN_B, 0);
myDFPlayer.pause();
digitalWrite(EXT_LIGHT_PIN, HIGH);
}
// A basic everyday NeoPixel strip test program.

// NEOPIXEL BEST PRACTICES for most reliable operation:
// - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections.
// - MINIMIZE WIRING LENGTH between microcontroller board and first pixel.
// - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR.
// - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS
//   connect GROUND (-) first, then +, then data.
// - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip,
//   a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED.
// (Skipping these may work OK on your workbench but can fail in the field)

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN    2
// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 50
// PIN to expect trigger
#define TRIGGER_PIN 3

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)


unsigned int state;
int colorWipeRate;

// setup() function -- runs once at startup --------------------------------

void setup() {
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.

strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show();            // Turn OFF all pixels ASAP
strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)

pinMode(TRIGGER_PIN, INPUT);
state = 0;
colorWipeRate = 50;
//attachInterrupt(digitalPinToInterrupt(TRIGGER_PIN),isr,RISING); // trigger ISR on rising edge of master voltage signal
}


// loop() function -- runs repeatedly as long as board is on ---------------

void loop() {
// Fill along the length of the strip in various colors...
    colorWipe(strip.Color(255,   0,   0), colorWipeRate); // Red
    colorWipe(strip.Color(  0, 255,   0), colorWipeRate); // Green
    colorWipe(strip.Color(  0,   0, 255), colorWipeRate); // Blue

    colorWipe(strip.Color(255,   0,   0), colorWipeRate); // Red
    colorWipe(strip.Color(  0, 255,   0), colorWipeRate); // Green
    colorWipe(strip.Color(  0,   0, 255), colorWipeRate); // Blue

    colorWipeRate = colorWipeRate - 2;
    if(colorWipeRate <= 2)
    {
    colorWipeRate = 2;
    }
}

void isr() {
state = 1;
}


// Some functions of our own for creating animated effects -----------------

// Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.
void colorWipe(uint32_t color, int wait) {
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    //if(digitalRead(TRIGGER_PIN) == 1) // if signal is 0, lights should turn on
    //{
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    //}
    delay(wait);                           //  Pause for a moment 
}
}

// Theater-marquee-style chasing lights. Pass in a color (32-bit value,
// a la strip.Color(r,g,b) as mentioned above), and a delay time (in ms)
// between frames.
void theaterChase(uint32_t color, int wait) {
for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
    strip.clear();         //   Set all pixels in RAM to 0 (off)
    // 'c' counts up from 'b' to end of strip in steps of 3...
    for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
    }
}
}

// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
// Hue of first pixel runs 5 complete loops through the color wheel.
// Color wheel has a range of 65536 but it's OK if we roll over, so
// just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
// means we'll make 5*65536/256 = 1280 passes through this loop:
for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    // strip.rainbow() can take a single argument (first pixel hue) or
    // optionally a few extras: number of rainbow repetitions (default 1),
    // saturation and value (brightness) (both 0-255, similar to the
    // ColorHSV() function, default 255), and a true/false flag for whether
    // to apply gamma correction to provide 'truer' colors (default true).
    strip.rainbow(firstPixelHue);
    // Above line is equivalent to:
    // strip.rainbow(firstPixelHue, 1, 255, 255, true);
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
}
}

// Rainbow-enhanced theater marquee. Pass delay time (in ms) between frames.
void theaterChaseRainbow(int wait) {
int firstPixelHue = 0;     // First pixel starts at red (hue 0)
for(int a=0; a<30; a++) {  // Repeat 30 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
    strip.clear();         //   Set all pixels in RAM to 0 (off)
    // 'c' counts up from 'b' to end of strip in increments of 3...
    for(int c=b; c<strip.numPixels(); c += 3) {
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
    }
    strip.show();                // Update strip with new contents
    delay(wait);                 // Pause for a moment
    firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
}
}