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.
Components and supplies
Jumper wires (generic)
Resistor 10k ohm
Tactile Switch, Top Actuated
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
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 4 be used without restriction and 5// without warranty. 6// 7// Exmple sketch 8 - Button Switch Using An External Interrupt 9// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 10// 11 This sketch demonstrates the use of a simple button switch which is processed by 12// 13 an external interrupt process. It presents a very different and alternative approach 14// 15 for associating a button switch to an interrupt. 16// 17// The sketch is designed 18 such that button status is only flagged as 'switched' AFTER 19// 1. button is pressed 20 AND then released, AND 21// 2. elapse of the debounce period AFTER release 22// 23// 24 Note that the associated button interrupt handler function and the button_read() 25// 26 function work together - the interrupt handler starts the on/off process and the 27// 28 button_read() function completes/concludes it. The interrupt handler can only restart 29 AFTER 30// button reading and debounce is complete. This ensures that only one 31 interrupt trigger is 32// processed at a time. 33// 34// The button switch is 35 wired in a standard configuration with a 10K ohm pull down resister which 36// 37 ensures the digital interrupt pin is kept LOW until the button switch is pressed 38 and 39// raises it to HIGH (+5v). 40// 41// Operation of the button is demonstrated 42 by toggling the in built LED on and off. 43// 44 45#define LED LED_BUILTIN 46 // digital pin connected to LED, for testing of switch code only 47bool led_status 48 = LOW; // start with LED off, for testing of switch code 49 only 50 51int button_switch = 2; // external interrupt 52 pin 53 54#define switched true // value if the button 55 switch has been pressed 56#define triggered true // controls 57 interrupt handler 58#define interrupt_trigger_type RISING // interrupt 59 triggered on a RISING input 60#define debounce 10 61 // time to wait in milli secs 62 63volatile bool interrupt_process_status = { 64 65 !triggered // start with no switch press pending, 66 ie false (!triggered) 67}; 68bool initialisation_complete = false; 69 // inhibit any interrupts until initialisation is complete 70 71// 72// ISR for 73 handling interrupt triggers arising from associated button switch 74// 75void 76 button_interrupt_handler() 77{ 78 if (initialisation_complete == true) 79 { 80 // all variables are initialised so we are okay to continue to process this interrupt 81 82 if (interrupt_process_status == !triggered) { 83 // new interrupt so okay 84 start a new button read process - 85 // now need to wait for button release 86 plus debounce period to elapse 87 // this will be done in the button_read 88 function 89 if (digitalRead(button_switch) == HIGH) { 90 // button 91 pressed, so we can start the read on/off + debounce cycle wich will 92 // 93 be completed by the button_read() function. 94 interrupt_process_status 95 = triggered; // keep this ISR 'quiet' until button read fully completed 96 } 97 98 } 99 } 100} // end of button_interrupt_handler 101 102bool read_button() { 103 104 int button_reading; 105 // static variables because we need to retain old values 106 between function calls 107 static bool switching_pending = false; 108 static 109 long int elapse_timer; 110 if (interrupt_process_status == triggered) { 111 // 112 interrupt has been raised on this button so now need to complete 113 // the button 114 read process, ie wait until it has been released 115 // and debounce time elapsed 116 117 button_reading = digitalRead(button_switch); 118 if (button_reading == HIGH) 119 { 120 // switch is pressed, so start/restart wait for button relealse, plus 121 end of debounce process 122 switching_pending = true; 123 elapse_timer 124 = millis(); // start elapse timing for debounce checking 125 } 126 if (switching_pending 127 && button_reading == LOW) { 128 // switch was pressed, now released, so check 129 if debounce time elapsed 130 if (millis() - elapse_timer >= debounce) { 131 132 // dounce time elapsed, so switch press cycle complete 133 switching_pending 134 = false; // reset for next button press interrupt cycle 135 interrupt_process_status 136 = !triggered; // reopen ISR for business now button on/off/debounce cycle complete 137 138 return switched; // advise that switch has been pressed 139 140 } 141 } 142 } 143 return !switched; // either no press request or debounce 144 period not elapsed 145} // end of read_button function 146 147void setup() { 148 149 pinMode(LED, OUTPUT); 150 pinMode(button_switch, INPUT); 151 attachInterrupt(digitalPinToInterrupt(button_switch), 152 153 button_interrupt_handler, 154 interrupt_trigger_type); 155 156 initialisation_complete = true; // open interrupt processing for business 157} 158 // end of setup function 159 160void loop() { 161 // test buton switch and process 162 if pressed 163 if (read_button() == switched) { 164 // button on/off cycle now 165 complete, so flip LED between HIGH and LOW 166 led_status = HIGH - led_status; 167 // toggle state 168 digitalWrite(LED, led_status); 169 } else { 170 // do 171 other things.... 172 173 } 174} 175
Comments