Author Topic: a hardware-independent software debouncer  (Read 12064 times)

0 Members and 1 Guest are viewing this topic.

Offline dannyfTopic starter

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
a hardware-independent software debouncer
« on: June 06, 2016, 12:32:18 am »
The Kuhn debouncer is well known for its simplicity and elegance: you simply integrate the incidents of key presses and non-presses - increment for key presses and decrement for non-presses.

I took the approach and striped away the hardware specific elements so the routines themselves are now able to be compiled on any platform. The hardware-specific portion of reading a pin is done through a user-specified handler, as shown here: https://dannyelectronics.wordpress.com/2016/06/05/a-generic-software-debouncer/

Full header and source files are available.

The heart of the code is here:

Code: [Select]
//update the integrator [0..CNT_MAX]
if ((*(key->keyread))()==KEY_NOTPRESSED) key->cnt_key -= (key->cnt_key <= 0)?0:1; //decrement cnt_key if key is not pressed
else key->cnt_key += (key->cnt_key >= CNT_MAX)?0:1; //increment cnt_key if key is pressed


About 30 ticks to execute on a PIC24F.

To use it, you simply include the header + source files into your project, provide a handler to read the keys and call the key read routine, either in the main loop or through an interrupt (timer, or external interrupts or pin change interrupts).

The code, as is, does not support fancier IO functions, like detection of key releases, double clicks, or long/short clicks. But they aren't difficult to add at all.

Enjoy.

edit: took out a typo.
« Last Edit: June 07, 2016, 12:29:43 am by dannyf »
================================
https://dannyelectronics.wordpress.com/
 
The following users thanked this post: jpanhalt

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 28780
  • Country: nl
    • NCT Developments
Re: a hardware-independent software debouncer
« Reply #1 on: June 06, 2016, 08:29:55 am »
Why decrement when released? Just set the counter to zero when not pressed and when pressed count up to a maximum value and trigger at a certain value.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3455
  • Country: gb
Re: a hardware-independent software debouncer
« Reply #2 on: June 06, 2016, 10:20:17 am »
Why decrement when released? Just set the counter to zero when not pressed and when pressed count up to a maximum value and trigger at a certain value.

 :-+ That's how I've always done it.
 

Offline wraper

  • Supporter
  • ****
  • Posts: 18242
  • Country: lv
Re: a hardware-independent software debouncer
« Reply #3 on: June 06, 2016, 11:09:45 am »
Why decrement when released? Just set the counter to zero when not pressed and when pressed count up to a maximum value and trigger at a certain value.
Why??? Because it gives robust result when signal is not clean. Both presses and releases. The less clean signal is, the more time it take takes to trigger value. And signal don't need to completely settle for triggering the value. Allows very fast and reliable debounce even with very crappy switches.
Quote
Just set the counter to zero when not pressed
:palm: and that's the reason why many devices start to experience double/triple presses after the switches receive some wear when actually there was only one press.
« Last Edit: June 06, 2016, 11:14:19 am by wraper »
 

Offline dannyfTopic starter

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: a hardware-independent software debouncer
« Reply #4 on: June 06, 2016, 11:14:01 am »
The stock key-get() returns two states right now, key pressed or keynotpressed.

If you desire the detection of pin bounces (pin transitions), you can alter that routine to return keybounce as well.
================================
https://dannyelectronics.wordpress.com/
 

Offline wraper

  • Supporter
  • ****
  • Posts: 18242
  • Country: lv
Re: a hardware-independent software debouncer
« Reply #5 on: June 06, 2016, 11:19:45 am »
Why decrement when released? Just set the counter to zero when not pressed and when pressed count up to a maximum value and trigger at a certain value.

 :-+ That's how I've always done it.
:-- That's why sometimes I want beat up the people who made the debounce in some devices. Instant state change on button release = no debounce for it.
« Last Edit: June 06, 2016, 11:22:07 am by wraper »
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6618
  • Country: nl
Re: a hardware-independent software debouncer
« Reply #6 on: June 06, 2016, 11:21:58 am »
Why decrement when released? Just set the counter to zero when not pressed and when pressed count up to a maximum value and trigger at a certain value.
That could work for short keypresses but not for long ones.
So what if you have a requirement that the user should press the button for a long time , say 5s to reset the system and ten times the switch glitches. You will never get to the threshold or your software that lies underneath. You will get ten individual short keypresses with a different meaning.
The integrator software should also allow for some overflow, so the threshold should IMO NOT be the maximum value as the Kuhn debouncer code has, it should be like a real hardware RC, which is below 0,8V it is not pressed and above 4V it is pressed for instance with a maximum of 5V. In the software we can make our own thresholds where in between it is a grey area and you don't know if the user was pressing the button and released it or is still pressing the button but not long enough for the threshold. Then you can correctly detect (very)long keypresses. Oh well in the end it is what you need and want, i like the contribution Danny.  :-+
 

Offline dannyfTopic starter

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: a hardware-independent software debouncer
« Reply #7 on: June 06, 2016, 11:27:31 am »
The detection of long pressed can be implemented if you use a lower threshold for short presses.

For example, in the key get routine, you can return key-shortpressed or key-longpressed based on the value of the integrator.

Detection of double clicks is a little more complicated and better suited for a fully implemented state machine.
================================
https://dannyelectronics.wordpress.com/
 

Offline wraper

  • Supporter
  • ****
  • Posts: 18242
  • Country: lv
Re: a hardware-independent software debouncer
« Reply #8 on: June 06, 2016, 11:30:55 am »
The detection of long pressed can be implemented if you use a lower threshold for short presses.

For example, in the key get routine, you can return key-shortpressed or key-longpressed based on the value of the integrator.

Detection of double clicks is a little more complicated and better suited for a fully implemented state machine.
Just noticed there is no low threshold after Kjelt mentioned it. It's no good without it. What you should do is trigger "1" when counter reaches max and trigger "0" when counter reaches zero. This way this is very robust, otherwise not robust at all.
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4351
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: a hardware-independent software debouncer
« Reply #9 on: June 06, 2016, 11:42:20 am »
I don't like this method. It inherently adds delay between pressing a key and action actually being taken, which makes for a potentially frustrating user experience. A responsive UI is a hallmark of a well designed product, IMHO.

Instead, I use a technique in which the very first time a button is detected as being pressed, it's acted upon. At the same time, a timer is initialised with a blanking interval, during which time no further changes in button state will be processed. Only when that blanking interval has elapsed will the button be enabled again. This eliminates the initial delay, and allows a relatively long debounce period to be used.

The debounce period limits the time between consecutive button presses, not the time it takes for a single press to be recognised.

Code: [Select]
uint8_t blank_time = 0;
uint8_t debounced_button = 0;

void timer_isr (void)
{
  if (blank_time == 0)
  {
    b = get_button_state();
    if (b != debounced_button)
    {
      debounced_button = b;
      blank_time = DEBOUNCE_TIME;
    }
  }
  else
  {
    blank_time--;
  }
}

Offline wraper

  • Supporter
  • ****
  • Posts: 18242
  • Country: lv
Re: a hardware-independent software debouncer
« Reply #10 on: June 06, 2016, 11:44:30 am »
Here is what I do for multiple inputs. Hopefully there are no errors because I just partially rewrote this right now because there was also some hardware related bit rearranging going in between in the code I copied it from.
EDIT: button_data and Button_integrator are variables which holds the value between debounce cycles. Other variables can be reinitialized.
Quote
uint8_t Button_integrator[NUMBER OF INPUTS] = {0};
uint8_t button_data = 0;

^ global variables, pointers, whatever. Must hold the data between each button read cycle.


uint8_t input_data;
uint8_t ch_num;
uint8_t input_bit_shift1;



read inputs into input_data;
input_bit_shift = 0x01;

for(ch_num = 0; ch_num < NUMBER OF INPUTS; ch_num ++)
         {
            if(input_data & input_bit_shift)
               {
                  if(Button_integrator[ch_num])      // check if the counter has not reached 0
                     Button_integrator[ch_num] --;
                  else
                     button_data &= 0xFF - input_bit_shift;
               }
               else
               {
                  if(Button_integrator[ch_num] < ButtonMaxCount)   //check if the counter has not reached maximum
                     Button_integrator[ch_num] ++;
                  else
                     button_data |= input_bit_shift;
               }

               input_bit_shift <<= 1;
            }
« Last Edit: June 06, 2016, 12:49:29 pm by wraper »
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6618
  • Country: nl
Re: a hardware-independent software debouncer
« Reply #11 on: June 06, 2016, 11:47:03 am »
I don't like this method. It inherently adds delay between pressing a key and action actually being taken, which makes for a potentially frustrating user experience. A responsive UI is a hallmark of a well designed product, IMHO.
Instead, I use a technique in which the very first time a button is detected as being pressed, it's acted upon.
So you don't debounce the switch then. You are only mitigating keypress bounces but if you're input is not really low ohms, a relais or other inductive noise source could trigger a false button press ?
Better add a RC then.
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4351
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: a hardware-independent software debouncer
« Reply #12 on: June 06, 2016, 11:55:36 am »
Debounce: yes!

Filter short duration spikes that are nothing to do with contact bounce: no, obviously.

If, in a given application, the switch inputs are prone to noise pick-up, then I agree that a timer is a good way to filter those. I've not personally found this to be a problem, but perhaps if the switches are remote from the processor then it would be more of an issue.

Of course, in that case, you'd probably want to include an ESD or other transient suppressor near the CPU anyway, and possibly a current limiting resistor.

Either way, I don't think it's good to have an inherent response delay equal to the worst-case contact bounce time. Noise spikes would - I'd expect - tend to be much shorter in duration, and could be filtered with a much shorter time constant than would be needed for reliable debouncing.

Offline wraper

  • Supporter
  • ****
  • Posts: 18242
  • Country: lv
Re: a hardware-independent software debouncer
« Reply #13 on: June 06, 2016, 12:01:29 pm »
Either way, I don't think it's good to have an inherent response delay equal to the worst-case contact bounce time. Noise spikes would - I'd expect - tend to be much shorter in duration, and could be filtered with a much shorter time constant than would be needed for reliable debouncing.
With a code I posted above I can debounce 50-100 of presses per second with close to 100% reliability (tested with signal gen outputting bouncy crap). It is used where very small delay between presses is possible. Something similar to double click in mouses. If you make a delay between the presses, it would completely suck.
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4351
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: a hardware-independent software debouncer
« Reply #14 on: June 06, 2016, 12:08:27 pm »
There's no way round the fact that, with any switch, the minimum time between consecutive clicks that can be recognised is a function of the worst-case contact bounce interval.

All I'm doing is swapping the time when action is taken, and the waiting interval which we use to tell the difference between contact bounce and real clicks.

Act, then wait, as opposed to wait, and then act.

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6618
  • Country: nl
Re: a hardware-independent software debouncer
« Reply #15 on: June 06, 2016, 12:12:27 pm »
I do agree that the "waiting" or better integration time should be less than the human acceptable threshold, just as if you are for instance multiplexing led displays you don't want them to give a visible flickering.
 

Offline wraper

  • Supporter
  • ****
  • Posts: 18242
  • Country: lv
Re: a hardware-independent software debouncer
« Reply #16 on: June 06, 2016, 12:22:15 pm »
There's no way round the fact that, with any switch, the minimum time between consecutive clicks that can be recognised is a function of the worst-case contact bounce interval.

All I'm doing is swapping the time when action is taken, and the waiting interval which we use to tell the difference between contact bounce and real clicks.

Act, then wait, as opposed to wait, and then act.
For instant act on press you need additional delay after previous switch release. Otherwise your next press may be just some bounce on switch release. In my case I want both presses and releases registered as fast as possible. Not just press and then wait 0.1 s after release because with such delay you will miss fast double click on PC mouse, for example.
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4351
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: a hardware-independent software debouncer
« Reply #17 on: June 06, 2016, 12:34:49 pm »
If your switch really might bounce for 100ms on release, then surely you have no choice?

If you wanted to get really cute, you could impose a different waiting interval for press vs release. I'd expect a switch to bounce for longer on press than release, so you could do:

Code: [Select]
uint8_t blank_time = 0;
uint8_t debounced_button = 0;

const uint8_t debounce_time [2] = {50, 10}; // longer debounce time after a press than after a release

void timer_isr (void)
{
  if (blank_time == 0)
  {
    b = get_button_state();
    if (b != debounced_button)
    {
      debounced_button = b;
      blank_time = debounce_time [b];
    }
  }
  else
  {
    blank_time--;
  }
}

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 28780
  • Country: nl
    • NCT Developments
Re: a hardware-independent software debouncer
« Reply #18 on: June 06, 2016, 01:53:49 pm »
Why decrement when released? Just set the counter to zero when not pressed and when pressed count up to a maximum value and trigger at a certain value.
That could work for short keypresses but not for long ones.
So what if you have a requirement that the user should press the button for a long time , say 5s to reset the system and ten times the switch glitches. You will never get to the threshold or your software that lies underneath. You will get ten individual short keypresses with a different meaning.
True but you have to ask yourself how well a device works if the switches are that flaky. And how does it tell the difference between 2 short presses and one long press? BTW I always put the counter on a tens of milliseconds interval so very short interruptions are likely to be missed anyway.

@AndyC_772: It is true that this method introduces a short delay but the trick is to make it so short the user doesn't notice it. When dealing with a switch I want to see it's signal active at least 3 times during 50ms to 100ms before letting the firmware do something. It depends on the application but in many cases you really need to be sure a button is pressed and it is not moisture playing games with your device.
« Last Edit: June 06, 2016, 01:59:03 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline wraper

  • Supporter
  • ****
  • Posts: 18242
  • Country: lv
Re: a hardware-independent software debouncer
« Reply #19 on: June 06, 2016, 02:24:07 pm »
True but you have to ask yourself how well a device works if the switches are that flaky.
Almost all of the tact switches are that flaky, especially as time passes. If the switch is not pressed at exacly at the right angle, not pressed hard, and user's finger is not stiff enough, it will produce gibberish during the long press. I personally don't want to rely on quality of the switches used. I prefer design working reliably even with crappiest of them.
From my experience in repairing things - When tact switches get flaky, a glaring example is when people start pressing them very hard (literally with full strength) and by this completely destroying them very fast (membrane becomes flat). If there was decent debounce, they would survive much longer time.
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4351
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: a hardware-independent software debouncer
« Reply #20 on: June 06, 2016, 02:31:58 pm »
From my experience in repairing things - When tact switches get flaky, a glaring example is when people start pressing them very hard (literally with full strength) and by this completely destroying them very fast (membrane becomes flat). If there was decent debounce, they would survive much longer time.

Isn't this exactly what people do if a button doesn't appear to work immediately?

Technical people might work out that the correct way to use a button, is to press and be patient.

The other 99% would, I suspect, decide that 'press hard' is necessary. Hence my desire to ensure a button has an effect asap.

Offline BravoV

  • Super Contributor
  • ***
  • Posts: 7555
  • Country: 00
  • +++ ATH1
Re: a hardware-independent software debouncer
« Reply #21 on: June 06, 2016, 02:32:58 pm »
Post just to sub ...  :P  .. carry on folks ..

Offline suicidaleggroll

  • Super Contributor
  • ***
  • Posts: 1453
  • Country: us
Re: a hardware-independent software debouncer
« Reply #22 on: June 06, 2016, 03:09:02 pm »
From my experience in repairing things - When tact switches get flaky, a glaring example is when people start pressing them very hard (literally with full strength) and by this completely destroying them very fast (membrane becomes flat). If there was decent debounce, they would survive much longer time.

Isn't this exactly what people do if a button doesn't appear to work immediately?

"Immediately" in the human world and "immediately" in the button debounce world are two very different things.  A user will not notice a 10ms delay that's been added to the button press to debounce it, and they certainly won't get frustrated to the point of hammering on the button because it's not reacting...
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3455
  • Country: gb
Re: a hardware-independent software debouncer
« Reply #23 on: June 06, 2016, 03:57:26 pm »
Why decrement when released? Just set the counter to zero when not pressed and when pressed count up to a maximum value and trigger at a certain value.

 :-+ That's how I've always done it.
:-- That's why sometimes I want beat up the people who made the debounce in some devices. Instant state change on button release = no debounce for it.

If you only need to detect the press event (rather than release event) I don't see the problem?  Irrespective I have never made a device where contact bounce has caused user interface problems.
« Last Edit: June 06, 2016, 03:59:07 pm by mikerj »
 

Offline dannyfTopic starter

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: a hardware-independent software debouncer
« Reply #24 on: June 06, 2016, 08:33:19 pm »
Having done all thee software denouncing work, I have to say that I'm not a fan of software denouncing.

For one reason: simplicity. Forr all software denouncing could do, I can do it with AA simple RC filter. And the incremental woork there is to add a capacitor: I always put a serial resistor on mcu pins connected to the outside world, for protection. So addig a resistor to a schmitt trigger inout pin is all I need to do for a simple debouncer.

================================
https://dannyelectronics.wordpress.com/
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf