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 = 3; // number of functions available  (for this demonstration)

int ledPin3 = 3; //  (for this demonstration)
int ledPin4 = 4; //  (for this demonstration)

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

  pinMode(ledPin3, OUTPUT); // (for this demonstration)
  pinMode(ledPin4, 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;
  }
}

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(ledPin4, HIGH);
}

void one() { // ping pong both LEDs
  digitalWrite(ledPin3, HIGH);
  digitalWrite(ledPin4, LOW);
  delay(250);
  off();
  delay(500);
  digitalWrite(ledPin3, LOW);
  digitalWrite(ledPin4, 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(ledPin4, LOW);
  delay(500);
  digitalWrite(ledPin3, LOW);
  digitalWrite(ledPin4, HIGH);
  delay(500);
}

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(ledPin4, LOW);
}