/*
 * Task5a
 * 
 * Demonstrate using an interrupt routine to detect a button press
 * 
 * This example is *not* debounced
 * 
 */

#define BUTTON_IN 3

// Any variable used in an interrupt routine must be declared as volitile
// This ensures the compiler reads the value directly from dynamic memory (RAM)
// and not a cached register location.
volatile int nButton=0;

// the setup function runs once when you press reset or power the board
void setup() {
  
  // Pin to read button state, use internal pull-up to avoid external resistor
  // This also emulates TTL inputs that float HI.
  // Use INPUT for normal digital input (emulates CMOS input)
  pinMode(BUTTON_IN, INPUT_PULLUP);

  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  // Write something out to show we are alive
  Serial.println(F("Starting..."));

  // Setup the interrupt handler on pin change
  // Must be attached to pin 2 or 3 on Nano
  // FALLING generates an interrupt on falling edge
  attachInterrupt(digitalPinToInterrupt(BUTTON_IN), countButton, FALLING);
}

// the loop function runs over and over again forever
void loop() {

  Serial.print(F("The button has been pressed "));
  Serial.print(String(nButton));
  if (nButton==1) {
    Serial.println(F(" time"));
  }
  else {
    Serial.println(F(" times"));
  }
  
  // Wait 1 second so we don't flood the serial port
  delay(1000);
}

// This function is called via the interrupt handler
// every time a falling edge is detected on pin 3.
// This can happen at any time and will suspend the normal program execution
// until this routine finishes.
void countButton() {

  // Increment our button count
  // Any variable used to communicate information with the
  // rest of the code must be declared at global scope and
  // use the volatile declaration.
   ++nButton;
  
  // Keep interrupt routine as short as possible.
  // Do any real work in the event loop.
}