volatile bool button; // type "volatile" for variable inside interrupt handler
int buttonPin = 2; // interrupt pin INT0... also available is INT1, pin 3
int count = 0; // variable to indicate the button was pressed
int cases = 5; // number of functions available  (for this demonstration)

int ledPin3 = 3; //  (for this demonstration)
int ledPin5 = 5; //  (for this demonstration)

void setup() {
  Serial.begin(115200); // start the serial monitor for text (for this demonstration)

  pinMode(ledPin3, OUTPUT); // (for this demonstration)
  pinMode(ledPin5, OUTPUT); // (for this demonstration)

  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin), buttonISR, FALLING); // INT#, ISR, TRIGGER

  welcome(); // Send an introduction to the Serial Monitor (for this demonstration)
}

void loop() {
  if (button) { // button flag is returned from ISR
    delay(150); // debounce for bad boys
    button = 0; // reset ISR flag
    count++; // increment selected patteren
    if (count > cases) { // if counter reached last case...
      count = 0; // ... reset counter to first case
    }
    Serial.print(count);
  }

  switch (count) {
    case 0: zro(); break;
    case 1: one(); break;
    case 2: two(); break;
    case 3: tre(); break;
    case 4: fur(); break;
    case 5: fiv(); break;
      // case 6: six(); break;
      // case 7: svn(); break;
      // case 8: eit(); break;
  }
}

int buttonISR() { // this is the Interrupt Service Routine responding to the button press
  noInterrupts(); // disable interrupts while in the ISR
  button = 1; // set the flag that the button was pressed
  interrupts(); // enable interrupts when leaving the ISR
}

void zro() { // set both LEDs ON
  digitalWrite(ledPin3, HIGH);
  digitalWrite(ledPin5, HIGH);
}

void one() { // ping pong both LEDs
  digitalWrite(ledPin3, HIGH);
  digitalWrite(ledPin5, LOW);
  delay(250);
  off();
  delay(500);
  digitalWrite(ledPin3, LOW);
  digitalWrite(ledPin5, HIGH);
  delay(250);
  off();
  delay(500);
}

void two() { // blink both LEDs
  zro(); // calling the zro() function to turn the LEDs ON
  delay(500);
  off(); // calling the one() function to turn the LEDs OFF
  delay(500);
}

void tre() { // ping pong both LEDs
  zro(); // calling the zro() function to turn the LEDs OFF
  digitalWrite(ledPin3, HIGH);
  digitalWrite(ledPin5, LOW);
  delay(500);
  digitalWrite(ledPin3, LOW);
  digitalWrite(ledPin5, HIGH);
  delay(500);
}

void fur() { // fade ping pong
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
    analogWrite(ledPin3, 255 - fadeValue);
    analogWrite(ledPin5, fadeValue);
    delay(30);
  }
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
    analogWrite(ledPin3, 255 - fadeValue);
    analogWrite(ledPin5, fadeValue);
    delay(30);
  }
}

void fiv() {
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
    analogWrite(ledPin3, fadeValue);
    delay(20);
  }

  delay (100);
  analogWrite(ledPin3, 0);
  delay (80);
  analogWrite(ledPin3, 255);
  delay (100);
  analogWrite(ledPin3, 0);
  delay (80);
  analogWrite(ledPin3, 255);

  for (int fadeValue = 200 ; fadeValue >= 0; fadeValue -= 5) {
    analogWrite(ledPin3, fadeValue);
    delay(30);
  }
}
void welcome() {
  Serial.println("Press the green button with the white arrow to start the simulation.");
  Serial.println("Press the red button to change functions.");
  Serial.print("Function: ");
  Serial.print(count);
}

void off() { // set both LEDs off
  digitalWrite(ledPin3, LOW);
  digitalWrite(ledPin5, LOW);
}