I have an issue with debouncing. I am using a MCP23017 as an I/O-extender with an Arduino. This uses I2C to communicate with each other.

A variable amount of switches is connected to the MCP23017 (0-16 switches). On change of the inputs, an interrupt is generated and the Arduino captures this on rising edge. So whenever a button is pushed or released, an interrupt is generated.

Now I'm confused as how I should debug them. One option would be to set a delay after an interrupt (of let's say 50 ms), before turning the interrupts back on. This could have an issue however, since multiple inputs are connected to the same interrupt line.

Another option is to have a timestamp or something for the last time each switch was changed, and check if the time difference is big enough, otherwise ignore the next pulse. The problem with this is that it uses quit some resources as I have limited memory and there can be up to 8 extenders (so 8 * 16 = 128 inputs).

What is the most efficient way to handle these interrupts with debouncing?

  • 3
    Just don't use an interrupt. It does the exact opposite of what you want, the point of debouncing is to respond to input changes slowly. Just poll in your main loop, increment a counter when the input is active, set it to 0 when it is inactive. When it reaches a certain value (depends on your main loop scan rate) then you declare it on.
    – Hans Passant
    May 13 '14 at 15:50
  • 2
    What @HansPassant says. If you already have a periodic timer interrupt,, (eg. for an RTOS), hook it and poll the port that the switches are on. You can keep a 'currentKeyState' 16-bit var and bitwise XOR to detect changes. If a change is consistent for two, (or more), interrupts, accept it as valid. Dedicated interrupts for manual pushbuttons/keypads etc. are not justified, cause more problems than they solve and are just a major PITA..
    – Martin James
    May 13 '14 at 16:53
  • Waiting for a consistent value over successive reads can help with some sorts of noise, but it's not really a solid de-bouncing strategy. I prefer to act on (or at least record) the keypress when it is first seen, but then ignore subsequent presses of that (or potentially any) key for a certain amount of time or number of iterations through the loop. This keeps the system responsive, while letting the criteria for a second valid press be adjusted - or even expanded to include a key-repeat function. May 15 '14 at 16:47

Add debouncing circuitry if you can; it's not that difficult.

  • 2
    Circuitry is too late - the PCB's have already been ordered.
    – jdepypere
    May 13 '14 at 15:47
  • Hardware debouncing adds cost and layout complexity - software is cheaper and more configurable. May 15 '14 at 16:44

Depends on the application.

Define efficiency. What are you looking to optimize for? Manhours spend coding/testing, processor speed, response time?

Are theses keys to a piano synth? Yes you'll want interrupt speed, and each key needs to not affect the surrounding keys.

Is it going to be rare that two keys are pressed anywhere near each other? a timeout for the ISR is perfectly legitimate.

Will the user not observe any lag when he flips a switch and resources are tight? Then polling could be a viable option.

Are the EMI concerns and you need to filter out false positives? Well you're going to need do some more. Like sampling for sustained values or counting how long until the falling edge occurs.

There are so many options depending on what you want it to do.

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.