As suggested by @andyW, I have done debounce tracking inside loop() but how to do it inside the interrupt function. What I've done would be something like this:
int state;
int lastState = HIGH;
long lastDebounceTime = 0;
long debounceDelay = 50; // 50 mS
volatile bool light = false;
void setup() {
pinMode(D0, INPUT_PULLUP);
attachInterrupt(D3, lightOn, FALLING);
}
void loop() {
int reading = digitalRead(D0);
// if reading isn't LOW
if (reading != lastState) {
lastDebounceTime = millis(); // set the clock
}
// Check to see if the press is there long enough to exceed delay of 50 mS (not just noise)
if ( (millis() - lastDebounceTime) > debounceDelay) ) {
if (reading != state) {
state = reading;
if (state == LOW) {
// here is where I'm supposed to call an interrupt function to change a variable
// or just go ahead and change the variable
light = !light;
}
}
}
}
void lightOn() {
light = !light;
}
@metaculus, for non-ISR button sensing you may want to use the clickButton library. For debouncing a button that fires an ISR, you can do something like this:
void btnEvent() //triggers when the switch is pressed. each time you press the switch,
{
if ((millis() - lastDebounceTime) > debounceDelay) //if current time minus the last trigger time is greater than
{ //the delay (debounce) time, button is completley closed.
lastDebounceTime = millis();
//switch was pressed, do whatever you need to here
}
}
@peekay123 can this code be inside an interrupt function without blocking too much? I was told that within one it should be very brief code. That’s why I just change a volatile variable and place conditionals outside:
It is always worth remembering that debounce may not happen, so the code needs to work if there is only a single transition and no subsequents. One approach is to trigger the action from the first transition, and ignore subsequent transitions for a short period of time, there are a great many other algorithms.
Contact bounce isn’t brain surgery, but it can be surprisingly subtle for something that’s often taken for granted.
Just to throw in a somewhat heretic view of this topic
There might be no call for debouncing when the interrupt is attached to only FALLING or RAISING edge of the interrupt at all.
Sure for the given example
debouncing would be required, since the outcome is unpredictable (odd or even count of bounces) - in this case the ISR should rather be called lightToggle().
But if you do what the function name lightOn()suggests, there would not be any need for debouncing, since you would only switch the light on, which doesn't matter, if it was on already. But in case this is unwanted you could just do this
void lightOn() {
if (!light)
light = true;
}
void lightOff() {
if (light)
light = false;
}