Components and supplies
Jumper wires (generic)
Tactile Switch, Top Actuated
Resistor 10k ohm
Arduino UNO
Apps and platforms
Arduino IDE
Project description
Code
Interrupt Handling for Button Switch
c_cpp
An example sketch demonstrating an alternative approach to reading a button switch using an interrupt.
1// 2// 3// This example and code is in the public domain and may be used without restriction and 4// without warranty. 5// 6// Exmple sketch - Button Switch Using An External Interrupt 7// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 8// This sketch demonstrates the use of a simple button switch which is processed by 9// an external interrupt process. It presents a very different and alternative approach 10// for associating a button switch to an interrupt. 11// 12// The sketch is designed such that button status is only flagged as 'switched' AFTER 13// 1. button is pressed AND then released, AND 14// 2. elapse of the debounce period AFTER release 15// 16// Note that the associated button interrupt handler function and the button_read() 17// function work together - the interrupt handler starts the on/off process and the 18// button_read() function completes/concludes it. The interrupt handler can only restart AFTER 19// button reading and debounce is complete. This ensures that only one interrupt trigger is 20// processed at a time. 21// 22// The button switch is wired in a standard configuration with a 10K ohm pull down resister which 23// ensures the digital interrupt pin is kept LOW until the button switch is pressed and 24// raises it to HIGH (+5v). 25// 26// Operation of the button is demonstrated by toggling the in built LED on and off. 27// 28 29#define LED LED_BUILTIN // digital pin connected to LED, for testing of switch code only 30bool led_status = LOW; // start with LED off, for testing of switch code only 31 32int button_switch = 2; // external interrupt pin 33 34#define switched true // value if the button switch has been pressed 35#define triggered true // controls interrupt handler 36#define interrupt_trigger_type RISING // interrupt triggered on a RISING input 37#define debounce 10 // time to wait in milli secs 38 39volatile bool interrupt_process_status = { 40 !triggered // start with no switch press pending, ie false (!triggered) 41}; 42bool initialisation_complete = false; // inhibit any interrupts until initialisation is complete 43 44// 45// ISR for handling interrupt triggers arising from associated button switch 46// 47void button_interrupt_handler() 48{ 49 if (initialisation_complete == true) 50 { // all variables are initialised so we are okay to continue to process this interrupt 51 if (interrupt_process_status == !triggered) { 52 // new interrupt so okay start a new button read process - 53 // now need to wait for button release plus debounce period to elapse 54 // this will be done in the button_read function 55 if (digitalRead(button_switch) == HIGH) { 56 // button pressed, so we can start the read on/off + debounce cycle wich will 57 // be completed by the button_read() function. 58 interrupt_process_status = triggered; // keep this ISR 'quiet' until button read fully completed 59 } 60 } 61 } 62} // end of button_interrupt_handler 63 64bool read_button() { 65 int button_reading; 66 // static variables because we need to retain old values between function calls 67 static bool switching_pending = false; 68 static long int elapse_timer; 69 if (interrupt_process_status == triggered) { 70 // interrupt has been raised on this button so now need to complete 71 // the button read process, ie wait until it has been released 72 // and debounce time elapsed 73 button_reading = digitalRead(button_switch); 74 if (button_reading == HIGH) { 75 // switch is pressed, so start/restart wait for button relealse, plus end of debounce process 76 switching_pending = true; 77 elapse_timer = millis(); // start elapse timing for debounce checking 78 } 79 if (switching_pending && button_reading == LOW) { 80 // switch was pressed, now released, so check if debounce time elapsed 81 if (millis() - elapse_timer >= debounce) { 82 // dounce time elapsed, so switch press cycle complete 83 switching_pending = false; // reset for next button press interrupt cycle 84 interrupt_process_status = !triggered; // reopen ISR for business now button on/off/debounce cycle complete 85 return switched; // advise that switch has been pressed 86 } 87 } 88 } 89 return !switched; // either no press request or debounce period not elapsed 90} // end of read_button function 91 92void setup() { 93 pinMode(LED, OUTPUT); 94 pinMode(button_switch, INPUT); 95 attachInterrupt(digitalPinToInterrupt(button_switch), 96 button_interrupt_handler, 97 interrupt_trigger_type); 98 initialisation_complete = true; // open interrupt processing for business 99} // end of setup function 100 101void loop() { 102 // test buton switch and process if pressed 103 if (read_button() == switched) { 104 // button on/off cycle now complete, so flip LED between HIGH and LOW 105 led_status = HIGH - led_status; // toggle state 106 digitalWrite(LED, led_status); 107 } else { 108 // do other things.... 109 110 } 111} 112
Comments
Only logged in users can leave comments