Instructables

Arduino: Software debouncing in interrupt function...

Picture of Arduino: Software debouncing in interrupt function...
b.png
b.png
Hi everybody!

So recently i was working on a Project where i wanted to meassure the RPM of one of the Wheels on my Car, and from that calculate the Speed, keep track of the Driven distance etc. with an Arduino.
I wanted to use a Magnet and a Reed Switch to meassure the RPM, for that i needed to debouce the Signal from the Reed Switch, since i couldn't find any way to debouce a signal in interrupt functions that didn't require additional hardware for debouncing the signal on the Internet, here is how i debounced the Signal comming from the Reed Switch...




//Software debouncing in Interrupt, by Delphiño K.M.

long debouncing_time = 15; //Debouncing Time in Milliseconds
volatile unsigned long last_micros;

void setup() {
  attachInterrupt(0, debounceInterrupt, RISING);
}

void loop() {
}

void debounceInterrupt() {
  if((long)(micros() - last_micros) >= debouncing_time * 1000) {
    Interrupt();
    last_micros = micros();
  }
}

void Interrupt() {
  //Do Something
}

You could also "Do Something" in the main function, instead of calling a second function that then does something, i just liked it better this way...

Note: I've only tried this on an Arduino Mega (ATmega1280), with Arduino 0022.
Also, this isn't a perfect solution, the interrupt function is stil called multiple times, the follwing calls, in the next 15ms are just ignored, but hey, it does the job, so screw it!

Well, thats about it, i hope this helps someone...

P.S. This is my first Instructable, so if you don't have anything nice to say, don't say anything at all, allthough corrections, improvements, etc. are of course allways welcome...
Derek J1 month ago

There are two bugs here.

1. If the interrupt occurs just before micros() overflows, Interrupt() is not called, but should be. (last_micros is greater than micros(), giving a negative value that will not be larger than the debounce time.)

2. Calling micros() twice. It should be called once and the value stored in a local variable, before the expression is evaluated.

Also poor strategy to call another function from an ISR (which should get finish work fast) and hides the fact from another programmer that adding work in Interrupt() might be bad...

Derek J Derek J1 month ago

Oops, the first one is not a bug, because of the way C handles unsigned long arithmetic...

cool, check out how I set up my bike speedometer, I used interrupts, but I found that I didn't need to debounce, maybe because the bike moves much slower and I was only checking the reed switch at 1ms intervals:
http://www.instructables.com/id/Arduino-Bike-Speedometer/
delphino-999 (author)  amandaghassaei1 year ago
Sorry for the super late reply... :)
Hmm, maybe you had a better reed switch then i, mine really sucked! ;)
I'm a little confused about you using interrupts but only checking the reed switch at 1ms intervals, i mean if you were using interrupts you wouldn't be checking the reed switch in certain intervals, the whole point of an interrupt is for the Arduino to run a small part of code everytime something happens. Or were you using timer interrupts to check if the reed switch is closed at 1ms intervals? I guess that would explain why you didn't need to debounce. Your reed switch probably just bounced less than 1ms... :)

Anyhow, thanks for your comment! ;)
yes, timer interrupts, and yes, you're probably right about the debouncing.