Arduino: Software Debouncing in Interrupt Function...

Published

Introduction: Arduino: Software Debouncing in Interrupt Function...

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...

Share

    Recommendations

    • Water Contest

      Water Contest
    • Oil Contest

      Oil Contest
    • Creative Misuse Contest

      Creative Misuse Contest

    30 Discussions

    I have a rain gauge that uses a tipping bucket with a reed switch/magnet to calculate fallen rain and have been having issues with random interrupt triggering. I tried this code and after updating the value to 30 milliseconds, I've been able to eliminate this problem. Thank you!

    Why not simply do this to avoid needless interrupts during bouncing:

    void debounceInterrupt() {
    noInterrupts();
    delayMicroseconds(15000);
    interrupts();
    // do something
    }

    4 replies

    Interrupts should execute as fast as possible though, so the microcontroller/computer can go back to the main loop. This especially plays a role when you have multiple hardware interrupts, since you can only have one triggered at a time. While your code would also work, it may 'cause problems in certain situations, 'cause the interrupt causes the program to pause for 15ms each time the interrupt is triggered. So if the interrupt is triggered 50 times per secons for example, your program would be waiting doing nothing 75% of the time.

    I use the routine only for debouncing a tactile switch. It's no problem to pause the main program for 15 ms.

    In that case you can do it that way, it's good practice though to keep your main loop (and especially interrupts) running as fast as possible. In some cases you will need every last spare moment your microcontroller has and in that case it's not a particularly good idea, to have it sit and wait though delays all the time. ;-)

    Thank you, it seems to work well! But for my buttons I had to make the delay 300micros to get a good result.

    Hi thanks for tutorial. I tested with Esp 12E and work great.

    Thank you very much :)

    I signed up to Instructables just to say Thanks for this tutorial :)

    1 reply

    Wow, thanks!

    I'm glad if it helped you. :-)

    (one time would have been enough though)

    I signed up to Instructables just to say Thanks for this tutorial :)

    I signed up to Instructables just to say Thanks for this tutorial :)

    I signed up to Instructables just to say Thanks for this tutorial :)

    I signed up to Instructables just to say Thanks for this tutorial :)

    hi, i try adding thats my project manytime and change code but not working,'

    my project have 1 button make led pwm ,25 on/off, and 2 button make same leds pwm 255 and flash plinking led on 100 and off 150, but debouncer not working ,sometime code do leds have on alltime and sometime leds plink alltime and buttons not do anythink, how i made thats working right ? i no understand help please, i use buttons whit pull up, +5 volt--resistor---button and ardunio, other side button have ground. leds normal arduino---resistor--tip 120 transistor--led---ground.

    1 reply

    I don't know, did you try increasing the debounce time to 100ms or so?
    If you're debouncing a button, you probably don't need such a short
    debounce time, since you're likely not gonna push the button it more than 10 times
    a second...

    P.S. Most Arduinos have internal pull up resistors on the majority of their pins, that can be activated using "pinMode(pin, INPUT);
    digitalWrite(pin, HIGH);" or "pinMode(pin, INPUT_PULLUP);" depending on which IDE version you're using. So unless you need a specific pull up resistance or a pull down resistor for some reason, you can save yourself the effort of hooking up a pull up resistor by using the internal one. ;-)

    Since a couple of people have apparently been using this to debounce buttons, I would like to note that in most cases, you won't necessarily need an interrupt for a button. Since you can't possible push the button fast enough for the Arduino to miss it (if your code runs rasonably fast), you could just digitalRead(); the pin the button is connected to somewhere in the main loop and make sure it only reacts to it if the button wasn't pushed in the last 100ms or so.
    Since you have a limited number of hardware interrupt pins, it's good practice, to try and save them for when you really need them. ;-)

    0
    user
    GuusV

    2 years ago

    I tried this code in combination with hardware debouncing like described in this article: http://www.ganssle.com/debouncing-pt2.htm When I keep the button pressed the interrupt is keep getting called. Why is this, when it is triggered on RISING edge?

    1 reply

    Currently I switched to using an SR latch to toggle a state ON or OFF, but it requires 2 buttons. But I have not yet seen it fail and trigger multiple interrupts. And the interrupt routine now only requires 1 line: "state = !state"