Instructables
loading
loading

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...
JadinA213 days ago

Thanks, this was a nice temporary alternative to hardware debouncing.
Probably not perfect, but it works well for simple push button stuff.

markzielon1 month ago

This is very simple and works quite well. Thank you for posting.

If anyone is looking to use this code with a push button, I would recommend setting the debouncing_time to "150", potentially even slightly higher. Lower than this could still give you bouncing issues with certain buttons; I find it to be a happy medium between relatively fast button presses and errors.

That being said, 150 definitely wouldn't be suitable in a video game controller.

You are right, I've chosen 200ms to turn a blinking bike light on and off. Less than that would be unstable.

One thing to consider is that button bouncing should not happen in the first place, if there was an "ideal" button. So I guess for video games, and PC keyboards I guess, the electrical contact of the button must be better (or at least they perform hardware debouncing, while here we are doing software debouncing).

All in all, I found this instructable very instructive! And I don't think it is a big problem, as the OP says, in the function being called but ignored, I suppose every debouncing tutorial I've seen so far use the same technique, with some variations. But this one is very straightforward, and works exactely as expected!

Derek J8 months 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 J8 months 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.