I recently read an article about button debouncing and was wondering if I should keep this in mind when working with, for example, an Arduino (ATMega mC)? I assume it is an issue, especially when working with interrupts.

So is it better to detect bounce in code, or should this be taken care of with hardware? Please elaborate.


I would highly recommend hooking a scope (hopefully you have one or can get your hands on one to use) up to your switch. I have seen a student's project that had a bounce on their switch that went from 5v down to -5v up to 4v down to -3v then up to 2v then back down to 0v. When we looked at the current draw on a scope there were some a very very large spike.

In his particular case it was very very much needed for him to debounce his switch in hardware.

However, on the other hand, I have seen switches that have a much smaller effect that could easily just be removed in software.

You do need to weigh your options though. If you have a very complex amount of firmware, adding the overhead on both you as a programmer and the cpu usage may not be worth it and you would be better off to just add a little bit of hardware. Now on the other hand, if you are trying to get costs and size down, you will want to remove as much hardware as possible and do it all in firmware if you can.

  • \$\begingroup\$ I scoped an image of switch bounce and posted it on Wikipedia: en.wikipedia.org/wiki/File:Switch_bounce.JPG \$\endgroup\$ – Thomas O Nov 17 '10 at 19:44
  • \$\begingroup\$ @Thomas O that is a pretty fun picture of bounce. I just want to make sure @Vincent Van Den Berghe understands that not all bounce will look like that. That bounce is limited to 0-5v, it wont always look like that. \$\endgroup\$ – Kellenjb Nov 17 '10 at 19:47
  • 2
    \$\begingroup\$ @Thomas O, as a side note, we have created a practice of failing students who take Oscope images like that. Flash on a screen is horrible. We also take it a step further and push students to collect actual data points, using something like a CSV or labview, so that it can then easily be used in reports and data analysis. \$\endgroup\$ – Kellenjb Nov 17 '10 at 19:50
  • \$\begingroup\$ @Kellenjb, I'm getting a printer soon for my scope which supports HP-IB. Also I've discovered the "Sports" mode on my camera can take good pictures of the scope screen without a flash and with no blurring. \$\endgroup\$ – Thomas O Nov 17 '10 at 20:27
  • 1
    \$\begingroup\$ @Lundin In a real-time environment you depend on interrupts a lot. If you have a button press on an interrupt you don't really want your real-time system be be interrupted several times by a single button press. You also don't want to have to dedicate resources to wait for 10 ms. \$\endgroup\$ – Kellenjb Oct 11 '11 at 18:07

If you're a professional electronics designer chances are that your boss won't even let you do it in hardware. The reason is simple: if your production batch is large enough software is virtually free, while hardware has to be paid for for each unit you produce. And while resistors and capacitors are dirt cheap, mounting them on a PCB may cost up to 20 times their purchase price.

Whether you debounce in software or in hardware, you still have to select quality pushbuttons. The infamous 157ms button from the article is simply not fit for any application.
I usually sample the button at 32ms intervals, which is enough to bridge the debounce time of any good button. I'm quite a fan of the Alps SKQG TACT Switches.

Alps tact switch

On the few devices I tested it had an initial bounce time of less than 10ns. While it has an operating life of 100 000 cycles we tested it for 200 000 cycles and even then the 32ms debounce was sufficient. (I guess I should have measured the actual level of debounce, but our main interest at the time was the final product's behavior. Anyhow, we were using it out-of-spec.)

If you really want a hardware solution I second the SR flip-flop solution mentioned in the article as the technically best solution:

debounce circuit

The flip-flop can be constructed with a dual NAND gate, which is available in a small VSSOP8 package, for instance. The major drawback of this solution is that you need a SPDT pushbutton, where SPST is much more commonly available.


There are lots (and lots) of different ways to debounce buttons. Whether you do it in software or hardware is going to depend on your project requirements and switch type.

Here are some links to different methods:



  • \$\begingroup\$ I was going to go get a link to ganssle when I saw the question. \$\endgroup\$ – Kortuk Nov 17 '10 at 15:50
  • \$\begingroup\$ The ganssle article was the reason I asked this question, it's linked in my question :) Thanks for the link to the debounce code snippets. \$\endgroup\$ – Vincent Van Den Berghe Nov 17 '10 at 22:34
  • \$\begingroup\$ Would you mind summing up a few use cases to illustrate when to use soft/hardware? (this is probably subjective, but I'd like some examples anyway) \$\endgroup\$ – Vincent Van Den Berghe Nov 17 '10 at 22:41
  • 1
    \$\begingroup\$ @Vincent, Kellenjb summed it up on his answer how to decide. I did not click your link because it had a funny name, now that I clicked it I see ganssle! \$\endgroup\$ – Kortuk Nov 17 '10 at 23:17
  • \$\begingroup\$ If that is the consensus/general rule then indeed, there is no need for more examples. \$\endgroup\$ – Vincent Van Den Berghe Nov 18 '10 at 8:10

That article is the "bible" on debouncing. Contact bounce can be a problem with any application.

It's generally best to debounce switches in software as it's easier to adjust for the delays for particular switches, as they differ in their amount of contact bounce. Debouncing the key release is often necessary, as well. Switch manufacturers often specify the amount of bounce for their products, it's typically around 10ms - 20ms.

  • \$\begingroup\$ Why are people voting this down? \$\endgroup\$ – Toby Jaffey Nov 17 '10 at 21:40
  • \$\begingroup\$ Good point about key release debouncing! \$\endgroup\$ – Vincent Van Den Berghe Nov 17 '10 at 22:38
  • 1
    \$\begingroup\$ I did not downvote it, but just saying to do it in software is an awful idea. It is a good idea to characterize. \$\endgroup\$ – Kortuk Nov 17 '10 at 23:19
  • \$\begingroup\$ I said "generally", which is the case, and gave the reason. It also minimizes BOM cost and increases reliability. \$\endgroup\$ – Leon Heller Nov 18 '10 at 13:06
  • \$\begingroup\$ it only increases reliability if the signal stays within safe bounds of your controller. This action will increase reliability if you decrease component count without increases components wear. I was not saying that I disagreed with your posts concept, but I constantly work with engineers just coming into the field and an answer like this and they will debounce everything in software. You always must characterize. I also did not downvote you, but I did not upvote either, I think a broad answer like software risks newer developers risking their hardware. \$\endgroup\$ – Kortuk Nov 18 '10 at 19:04

Switch bounce can go on for tens of milliseconds. If you're polling a switch from an interrupt routine that runs on a timer, bounce won't be an issue, because even if you happen to poll the switch in the middle of a bounce storm, you either get the new state right away, or at worst get the old state, and don't see the new state until the next timer based poll. Polling from a timed ISR like this constitutes a form of software debounce.

However, if you are using that switch to cause the interrupt, and you expect that interrupt service routine to run quickly, in less than say 10 milliseconds, you'll need hardware debouncing, otherwise one switch event could result in a somewhat random number of interrupts, and certainly often more than just the one expected. On the other hand, if the interrupt routine runs long enough, the switch bounce will have settled before the ISR finishes, and you'd be fine, but most well constructed ISRs don't take all that long.

  • \$\begingroup\$ Having the switch to cause the interrupt is a good idea. But once you get it, don't allow further interrupts - shut them off and instead start a timer for the specified debounce time. \$\endgroup\$ – Lundin Oct 11 '11 at 15:09
  • \$\begingroup\$ @Lundin - if timers are available, you can just use the timer to implement the polled approach, and not bother having the switch generate interrupts at all. \$\endgroup\$ – JustJeff Oct 12 '11 at 0:19

The best way to do anyhting is the way that suits you best. But when you already have a microcontroller you can debounce in software at only the cost of a some code effort.

The essiest way to debounce in software is to check the buttons at moments in time that are further apart than the longest bounce time. 50 ms seems to be an upper bound on the bounce time of 'normal' switches, so when you can arrange your software like this you are in the clear:

forever loop
   wait (at least) 50 ms
   check buttons
   do procesing
end loop
  • \$\begingroup\$ And use the on-chip timers on your MCU for this. \$\endgroup\$ – Lundin Oct 11 '11 at 15:06
  • \$\begingroup\$ That is of course possible, but you can write a lot of programs without. \$\endgroup\$ – Wouter van Ooijen Oct 11 '11 at 15:21
  • 3
    \$\begingroup\$ Professional software in quality products will always use on-chip timers. Hobbyists can get away with some "NOP" for loop or dead wait polling. But there is no reason ever to do this in real products, no matter your realtime requirements. "I don't know how the timer works and this dead loop takes 10 seconds for my lazy self to write" is not a valid argument for an engineer. \$\endgroup\$ – Lundin Oct 11 '11 at 15:35
  • \$\begingroup\$ Bullocks. Professionals must be effective, which (depending on the project at hand) can meant (amongst other things) 'use the hardware effectively as possible' or 'use the professional's time as effecive as possible'. So your comming certainly applies in some cases (probably all cases you have dealt with) it certainly does not apply in all cases. \$\endgroup\$ – Wouter van Ooijen Oct 11 '11 at 15:44
  • \$\begingroup\$ To implement the on-chip timer takes an hour of your time at most. This is hardly something complex, it is everyday bread & butter engineering. You can't even invest one hour in your project to get a significantly better solution and overall better quality? Yeah well... if you don't know much about programming, it might take you a week. But then perhaps you shouldn't be working with software in the first place... or perhaps you should work more with it, so you'll learn to implement this simple little thing in no time. \$\endgroup\$ – Lundin Oct 12 '11 at 6:38

One approach to debouncing which hasn't yet been mentioned is to use a double-throw switch with one throw tied to VDD and the other to ground. Feed that into a pin which (either via software or hardware) will be weakly pulled to its present state. Such an approach will provide the advantages of a double-throw switch, but will only require one I/O pin rather than two.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.