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.

Feb 1, 2021

59617 views

5 respects

Components and supplies

4

Jumper wires (generic)

1

Tactile Switch, Top Actuated

1

Resistor 10k ohm

1

Arduino UNO

Apps and platforms

1

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.

Comments

Only logged in users can leave comments

Anonymous user

2 years ago

Am I correct that as this routine does not use an interrupt for interrupt_trigger_type FALLING it is dependent on read_button() being called before the next button push or it will miss a double push? Do you deal with this in "ARDUINO Microcontroller, External Interrupt Handling"?

ronbentley1

2 years ago

Hi Dan, thank you for your comments and observations. I will try and deal with both of your posts below. post 1: I have removed the reference to the use of millis() as I can see your confusion. The method offered does not use the timer0 ISR, so I can only apologise for any confusion here. post 2: there was a typo in the article - I referred to the RISING parameter with regard to a pinMode call. Of course, this should have referenced an attachinterrupt call instead. As far as missing a double push, then no. If a double push is made then two scenarios are relevant: 1. the second push occurs within an existing push debounce cycle, in which case it will be considered to be spurious and handled, or 2. the second push occurs outside of the debounce cycle, in which case it is a new push and handled. Thank you for your observations which I have taken on board. The forum is excellent for publishing material, but what it lacks is a peer review process. I dare say that what we are going through here can be considered as a peer review process, so all good. Finally, I do not know if you have looked at another of my posts - ez_switch_lib, but the user guide includes a more sophisticated use of a single ISR for many switches, I have added the link to the ez_switch_lib to the Further Reading section of the above article. See the user guide Corollary/Many Switches, One Interrupt Service Routine (ISR). Once again, many thanks Ron Bentley

Anonymous user

2 years ago

I really appreciate your projects - thank you I have respected every one i have read so far! I am confused by the sentence: "This approach ensures that the millis() function can be used to time debounce, which is not the case within an ISR handler." The example then goes on to refer to itself as an ISR (e.g. "// reopen ISR for business now button on/off/debounce cycle complete") ??? Did you mean to say: "... which is not the case within an "A TYPICAL" ISR handler." ??? If so could you point me to a typical ISR handler? Thanks Dan

Anonymous user

3 years ago

My friendo, let me give you an intro to C that perhaps you miss (sorry if i sound like an ah0l3... but i really think you missunderstood that concept... so...) #define ITS_DEFINED || #define IT_DEFINES "1" || ~... <- This means more for the compile behavior of the c:pre/co/pocessor|compiler etc... than for making keywords or enumerable singletons.... #1.- if you need a value lets say (assume phee is always eq to 3.1416^2 eq to pi*pi) then, dont waste an unswapable unpaginable byte/dword/qword or alike... better do the root (3.14) and save memory, memory access, memory retention, adressing, and so on... #2.- lets say, phee is an arbitrary but totally meaningfull to your program (see it as an entity not as an atomic part of a process) then do this: static TYPE varname=VAL; eq ->>> "static const long X=100000;" ; static in memory, constant of tipe long with a permanent value of 10000; meaning: compiler wont waste arithmetic on trying to change that variable... into seeing if it was declared but never used, or see if it does needs to add handling for that data type (wich if were not constant, would mean: Damn, a static always on memory variable,.. should i swap() free() page() or alike (even include the references to), the segments of executable code wich handle how the machine process a data type of long, when doing operations or interactions with it... like: long+long|| long+int|| long has overflow? or even the posible tryout of premitigate a posible division by 0 where 0 is in a long datatype... you get me? #3.- if you need special singletons: "enum State {Working = 1, Failed = 0};" (yea, i usually only used enum while tryung to feel snob... really after the 3rd attempt, sometimes you realize, enum is more related to code understandability and porting , than to self coding enhancement or thinks like that.... BTW, if you have time to waste.... Lambda... in C#.. and some other OO languajes... that thing is cool... its like inthe.middle(ofnowhere=>{execthisifisayso);).letsayididnt(); <- see? did not wasted adressing of a far jump to a function, not wasted time in compiling linking , turing logic and so on... Well, merry xmass friend. ;

ronbentley1

2 years ago

Hi, My apologies but I do not understand any part of your comments. Have you posted to the wrong article?

dpressm

3 years ago

Am I correct that as this routine does not use an interrupt for interrupt_trigger_type FALLING it is dependent on read_button() being called before the next button push or it will miss a double push? Do you deal with this in "ARDUINO Microcontroller, External Interrupt Handling"?

ronbentley1

2 years ago

Hi Dan, thank you for your comments and observations. I will try and deal with both of your posts below. post 1: I have removed the reference to the use of millis() as I can see your confusion. The method offered does not use the timer0 ISR, so I can only apologise for any confusion here. post 2: there was a typo in the article - I referred to the RISING parameter with regard to a pinMode call. Of course, this should have referenced an attachinterrupt call instead. As far as missing a double push, then no. If a double push is made then two scenarios are relevant: 1. the second push occurs within an existing push debounce cycle, in which case it will be considered to be spurious and handled, or 2. the second push occurs outside of the debounce cycle, in which case it is a new push and handled. Thank you for your observations which I have taken on board. The forum is excellent for publishing material, but what it lacks is a peer review process. I dare say that what we are going through here can be considered as a peer review process, so all good. Finally, I do not know if you have looked at another of my posts - ez_switch_lib, but the user guide includes a more sophisticated use of a single ISR for many switches, I have added the link to the ez_switch_lib to the Further Reading section of the above article. See the user guide Corollary/Many Switches, One Interrupt Service Routine (ISR). Once again, many thanks Ron Bentley

dpressm

3 years ago

I really appreciate your projects - thank you I have respected every one i have read so far! I am confused by the sentence: "This approach ensures that the millis() function can be used to time debounce, which is not the case within an ISR handler." The example then goes on to refer to itself as an ISR (e.g. "// reopen ISR for business now button on/off/debounce cycle complete") ??? Did you mean to say: "... which is not the case within an "A TYPICAL" ISR handler." ??? If so could you point me to a typical ISR handler? Thanks Dan