Arduino: Software Debouncing in Interrupt Function...

39,867

19

31

Posted

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

  • Epilog Challenge 9

    Epilog Challenge 9
  • Sew Warm Contest 2018

    Sew Warm Contest 2018
  • Paper Contest 2018

    Paper Contest 2018
user

We have a be nice policy.
Please be positive and constructive.

Tips

Questions

30 Comments

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
}

Wow, this solution is so elegant.

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 :)