ronbentley1
Published

Button Switch Using An External Interrupt

There are numerous examples of how to connect button switches via an external interrupt. This example offers an alternative approach.

BeginnerFull instructions provided33,058
Button Switch Using An External Interrupt

Things used in this project

Hardware components

Tactile Switch, Top Actuated
Tactile Switch, Top Actuated
×1
Jumper wires (generic)
Jumper wires (generic)
×4
Resistor 10k ohm
Resistor 10k ohm
×1
Arduino UNO
Arduino UNO
Any Arduino board will do
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Interrupt Handling for Button Switch

C/C++
An example sketch demonstrating an alternative approach to reading a button switch using an interrupt.
//
//
//  This example and code is in the public domain and may be used without restriction and
//  without warranty.
//
// Exmple sketch - Button Switch Using An External Interrupt
// '''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// This sketch demonstrates the use of a simple button switch which is processed by
// an external interrupt process.  It presents a very different and alternative approach
// for associating a button switch to an interrupt.
//
// The sketch is designed such that button status is only flagged as 'switched' AFTER
// 1. button is pressed AND then released, AND
// 2. elapse of the debounce period AFTER release
//
// Note that the associated button interrupt handler function and the button_read()
// function work together - the interrupt handler starts the on/off process and the
// button_read() function completes/concludes it.  The interrupt handler can only restart AFTER
// button reading and debounce is complete.  This ensures that only one interrupt trigger is
// processed at a time.
//
// The button switch is wired in a standard configuration with a 10K ohm pull down resister which
// ensures the digital interrupt pin is kept LOW until the button switch is pressed and
// raises it to HIGH (+5v).
//
// Operation of the button is demonstrated by toggling the in built LED on and off.
//

#define LED                         LED_BUILTIN  // digital pin connected to LED, for testing of switch code only
bool    led_status =                        LOW; // start with LED off, for testing of switch code only

int     button_switch =                       2; // external interrupt pin

#define switched                            true // value if the button switch has been pressed
#define triggered                           true // controls interrupt handler
#define interrupt_trigger_type            RISING // interrupt triggered on a RISING input
#define debounce                              10 // time to wait in milli secs

volatile  bool interrupt_process_status = {
  !triggered                                     // start with no switch press pending, ie false (!triggered)
};
bool initialisation_complete =            false; // inhibit any interrupts until initialisation is complete

//
// ISR for handling interrupt triggers arising from associated button switch
//
void button_interrupt_handler()
{
  if (initialisation_complete == true)
  { //  all variables are initialised so we are okay to continue to process this interrupt
    if (interrupt_process_status == !triggered) {
      // new interrupt so okay start a new button read process -
      // now need to wait for button release plus debounce period to elapse
      // this will be done in the button_read function
      if (digitalRead(button_switch) == HIGH) {
        // button pressed, so we can start the read on/off + debounce cycle wich will
        // be completed by the button_read() function.
        interrupt_process_status = triggered;  // keep this ISR 'quiet' until button read fully completed
      }
    }
  }
} // end of button_interrupt_handler

bool read_button() {
  int button_reading;
  // static variables because we need to retain old values between function calls
  static bool     switching_pending = false;
  static long int elapse_timer;
  if (interrupt_process_status == triggered) {
    // interrupt has been raised on this button so now need to complete
    // the button read process, ie wait until it has been released
    // and debounce time elapsed
    button_reading = digitalRead(button_switch);
    if (button_reading == HIGH) {
      // switch is pressed, so start/restart wait for button relealse, plus end of debounce process
      switching_pending = true;
      elapse_timer = millis(); // start elapse timing for debounce checking
    }
    if (switching_pending && button_reading == LOW) {
      // switch was pressed, now released, so check if debounce time elapsed
      if (millis() - elapse_timer >= debounce) {
        // dounce time elapsed, so switch press cycle complete
        switching_pending = false;             // reset for next button press interrupt cycle
        interrupt_process_status = !triggered; // reopen ISR for business now button on/off/debounce cycle complete
        return switched;                       // advise that switch has been pressed
      }
    }
  }
  return !switched; // either no press request or debounce period not elapsed
} // end of read_button function

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(button_switch, INPUT);
  attachInterrupt(digitalPinToInterrupt(button_switch),
                  button_interrupt_handler,
                  interrupt_trigger_type);
  initialisation_complete = true; // open interrupt processing for business
} // end of setup function

void loop() {
  // test buton switch and process if pressed
  if (read_button() == switched) {
    // button on/off cycle now complete, so flip LED between HIGH and LOW
    led_status = HIGH - led_status; // toggle state
    digitalWrite(LED, led_status);
  } else {
    // do other things....

  }
}

Credits

ronbentley1
25 projects • 13 followers
Contact

Comments

Please log in or sign up to comment.