Simple Debounce Routine

software debounce interrupt
software debouncing
relay debounce
switch debounce ic
software debouncing avr
debounce via software
ganssel's guide to debouncing
arduino debounce library

Do you have a simple debounce routine handy to deal with a single switch input?

This is a simple bare metal system without any OS.

I would like to avoid a looping construct with a specific count, as the processor speed might fluctuate.

I think you could learn a lot about this here: http://www.ganssle.com/debouncing.pdf

Your best bet is always to do this in hardware if possible, but there are some thoughts on software in there as well.

Simple example code from TFA:

#define CHECK_MSEC 5 // Read hardware every 5 msec
#define PRESS_MSEC 10 // Stable time before registering pressed
#define RELEASE_MSEC 100 // Stable time before registering released
// This function reads the key state from the hardware.
extern bool_t RawKeyPressed();
// This holds the debounced state of the key.
bool_t DebouncedKeyPress = false;
// Service routine called every CHECK_MSEC to
// debounce both edges
void DebounceSwitch1(bool_t *Key_changed, bool_t *Key_pressed)
{
    static uint8_t Count = RELEASE_MSEC / CHECK_MSEC;
    bool_t RawState;
    *Key_changed = false;
    *Key_pressed = DebouncedKeyPress;
    RawState = RawKeyPressed();
    if (RawState == DebouncedKeyPress) {
        // Set the timer which allows a change from current state.
        if (DebouncedKeyPress) Count = RELEASE_MSEC / CHECK_MSEC;
        else Count = PRESS_MSEC / CHECK_MSEC;
    } else {
        // Key has changed - wait for new state to become stable.
        if (--Count == 0) {
            // Timer expired - accept the change.
            DebouncedKeyPress = RawState;
            *Key_changed=true;
            *Key_pressed=DebouncedKeyPress;
            // And reset the timer.
            if (DebouncedKeyPress) Count = RELEASE_MSEC / CHECK_MSEC;
            else Count = PRESS_MSEC / CHECK_MSEC;
        }
    }

}

My favorite software debouncers, Software debounce routines range from some quite simple approaches to sophisticated algorithms that handle multiple switches in parallel. Many developers  Debouncing buttons can be a major issue for novice programmers, for something that seems so simple (Just put in a button!) it can be hours of pulling your hair out. Typically a button is partially debounced using hardware but what if you just want the ability to get rid of those false presses or stop it from thinking the button has been pressed 100 times in a second for a quick program?

Simplest solutions are often the best, and I've found that simply only reading the switch state every N millseconds (between 10 and 50, depending on switches) has always worked for me.

I've stripped out broken and complex debounce routines and replaced them with a simple slow poll, and the results have always been good enough that way.

To implement it, you'll need a simple periodic timer interrupt on your system (assuming no RTOS support), but if you're used to programming it at the bare metal, that shouldn't be difficult to arrange.

Note that this simple approach adds a delay to detection of the change in state. If a switch takes T ms to reach a new steady state, and it's polled every X ms, then the worst case delay for detecting the press is T+X ms. Your polling interval X must be larger than the worst-case bounce time T.

[PDF] A Guide to Debouncing, an effective bounce filter, in hardware or software, unless we understand the entire Software debounce routines range from the utterly simple to sophisticated  Software debounce routines range from some quite simple approaches to sophisticated algorithms that handle multiple switches in parallel. Many developers create solutions without completely understanding the problem. Sure, contacts rebound against each other.

There's no single simple solution that works for all types of buttons. No matter what someone here tells you to use, you'll have to try it with your hardware, and see how well it works. And look at the signals on a scope, to make sure you really know what's going on. Rich B's link to the pdf looks like a good place to start.

Debounce, This example demonstrates how to debounce an input, which means checking twice in a short period of time to make sure the pushbutton is  Hi - I'm sure that this 'horse' has been beaten to a pulp but I came up with this simple state machine version of a push-button debounce routine that has served me well for years and wanted to offer it to the group.

I have used a majority vote method to debounce an input. I set up a simple three state shift register type of data structure, and shift each sample and take the best two out of three as the "correct" value. This is obviously a function of either your interrupt handler, or a poller, depending on what method is used to actually read the hardware.

But, the best advice is to ask your friendly hardware designer to "latch" the value and allow you to clear this value when you get to it.

Debouncing via Software [Reference.Digilentinc], An efficient software method to debounce multiple switch inputs counter, these bits could be in variables cnt0, cnt1 and cnt2, for example. Debounce. Pushbuttons often generate spurious open/close transitions when pressed, due to mechanical and physical issues: these transitions may be read as multiple presses in a very short time fooling the program. This example demonstrates how to debounce an input, which means checking twice in a short period of time to make sure

To debounce, you want to ignore any switch up that lasts under a certain threshold. You can set a hardware timer on switch up, or use a flag set via periodic interrupt.

Debouncing switches with vertical counters, Wanna see the sweetest little debouncing routine this side of Spokane? C'mon The simple RC filter here is still only a partial solution, though. Last month we asked you to send in your debounce code. You didn’t disappoint and it’s time to share the code received. There were some guideline for sending in code so if you don’t see yours

Embed With Elliot: Debounce Your Noisy Buttons, Part I, Debouncing Switches. Solutions: -Count based. -from Gansel's “Guide to Debouncing”. -routine called from timer interrupt or delay loop. -check Port D, bit 2,  A couple are of the integrator type. In particular, [Kenneth Kuhn]’s debounce routine is very nice. It increments a counter every time it sees the button pressed, and decrements it when the button isn’t pressed. By using a threshold like seven counts or something, it avoids responding to initial wiggles.

[PDF] Debouncing Switches, Figure 1 shows the classic debounce circuit. Two cross-coupled NAND gates form a very simple Set-Reset (SR) latch. The design requires a double-throw switch. will occasionally pervert the debounce routine. For the sake of the experiment we need to see them. I tested the trigger switches from an old cheap game-playing joystick (the three yellow ones in the picture), the left mouse button from an ancient Compaq computer (on PCB in upper left corner), toggle switches, pushbuttons, and slide switches.

Debouncing, hardware and software, part 2, There are different opinions on how to use it, but interrupt driven switch debouncing will not be discussed here. The following is a simple software debounce 

Comments
  • Actually found it about 10 minutes after asking the question. Quite Handy. I agree with the HW solution...if only...
  • I agree that a steady period works perfectly OK - I often use my display refresh cycle for debouncing "since I'm there" and that works fine. You're missing the actual "debounce logic" here, though - unless you always trigger on a state change, which simply won't work every time.
  • @Tom, the whole point is there is no debounce logic: You don't need it. Switch 'bounce' is really just an artefact caused by sampling a mechanical contact clusure faster than it was designed to operate. By dropping the sample rate down, you sidestep the problem. (and yes, video refresh frequency is spot on for most good switches)
  • Very interesting, I hadn't thought of it that way. After some scribbling, I believe that you're provably correct IF the polling period is between twice the longest debounce cycle from your hardware and half the length of the shortest button press that you'll accept, as long as you're willing to accept a delay of (occasionally) up to two full polling cycles. (For a screen refresh rate of 60Hz, that implies a bounce cycle of <9ms for example.) I must have been grumpy, I marked you down - and apparently I can't change this. :-( If you change your answer slightly, I can mark it up again.
  • Great! Hmm, I have a suboptimal definition of "bounce time" that's not as good as yours. Perhaps a better name for the concept is "time to stability" - how long after a state change is the signal stable? - which corresponds to your idea of it.
  • That doesn't seem right to me. Surely the order they come in is important? For example, if your shift register says Up Down Up, surely you are "in the middle of a bounce" and you need to wait one more period?
  • I agree that HW would be better but that's not in the dice.
  • If it's something a person is switching, you almost always need to debounce it, even if there's hardware debouncing. People's hands shake, they use not enough or too much force on the button, or crap has gotten into the button - they can mechanically create bounce that way, which your SPDT will then faithfully report. Hardware debouncing is great, however, and if nothing else, lets you keep your bounce time much smaller and get a more responsive keyboard.
  • I found your algorithm interesting (close to what I'm looking for). I edited it to remove the negation '~', which I think was incorrect