Author Topic: a hardware-independent software debouncer  (Read 10461 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: 26906
  • 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: 3240
  • 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: 16864
  • 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: 16864
  • 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: 6460
  • 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: 16864
  • 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: 4228
  • 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: 16864
  • 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: 6460
  • 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: 4228
  • 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: 16864
  • 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: 4228
  • 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: 6460
  • 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: 16864
  • 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: 4228
  • 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: 26906
  • 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: 16864
  • 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: 4228
  • 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: 7547
  • 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: 3240
  • 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/
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: a hardware-independent software debouncer
« Reply #25 on: June 06, 2016, 08:36:52 pm »
The schmitt trigger is what makes things hairy. Many microcontrollers don't have schmitt trigger inputs and some even have truly awfull logic level thresholds (like Atmel's Attiny).
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3478
  • Country: us
Re: a hardware-independent software debouncer
« Reply #26 on: June 07, 2016, 12:06:31 am »
@dannyf
Thank you for the links to your blog and Kuhn's description.  I have been unhappy with my software debouncer and wrote a small program for that approach (simulates, but not thoroughly tested).   I only use Assembly, and the code requires one register and a couple of rotates. This is for a switch (PORTC,0) that is low when open and waits for a low before returning from the ISR.

EDIT: Couldn't get the code to format, so added as image attachment.
 
EDIT2:  Was worried about a step and in fact, it is a bug with a more complex simulation.  Disregard code, it doesn't work.  If fixed, I will repost.
EDIT3:  Fixed that bug. There may be others.  Updated image attachment. Changed rlf debounce,w to rlf debounce,f and added step.

I realize this may be of interest to only 13 people in the world.  But when you are retired, that doesn't matter.

John

Edit:  That code looks horrible, but looked fine in the "preview."   What is the preview for if it doesn't work? Tried pasting from MPLAB, as I usually do and skipped preview.  That wasn't much better.  Attached image.  Sorry for inconvenience.
« Last Edit: June 07, 2016, 01:47:29 pm by jpanhalt »
 

Offline dannyfTopic starter

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: a hardware-independent software debouncer
« Reply #27 on: June 07, 2016, 12:30:12 am »
jpanhalt: i'm happy that it is of use to you.
================================
https://dannyelectronics.wordpress.com/
 

Online Alex Eisenhut

  • Super Contributor
  • ***
  • Posts: 3338
  • Country: ca
  • Place text here.
Re: a hardware-independent software debouncer
« Reply #28 on: June 08, 2016, 12:22:14 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.

Like my Breville toaster oven... grrrrr....
Hoarder of 8-bit Commodore relics and 1960s Tektronix 500-series stuff. Unconventional interior decorator.
 

Offline obiwanjacobi

  • Frequent Contributor
  • **
  • Posts: 988
  • Country: nl
  • What's this yippee-yayoh pin you talk about!?
    • Marctronix Blog
Re: a hardware-independent software debouncer
« Reply #29 on: June 08, 2016, 07:45:57 am »
I like the adaptive nature of an integrator, provided it is called frequently enough - you don't want to starve it - which in some apps may require some thought... If the switch gets old and bounces more, it'll just take longer to make out a steady state. Sounds fine.

I like the argument that Andy brought forth about reacting on first sign of change and doing the debouncing afterwards...

I also like the argument that you could really solve this easily in hardware too (do you really need a schmitt-trigger input?) which saves you some software complexity. This however, is not adaptive with the switch's wear....


I have written an implementation that uses approximate time to debounce (and detect hold). I would not mind making a 'better' or alternative implementations...

So how would you consolidate these aspects into a solid implementation?
Arduino Template Library | Zalt Z80 Computer
Wrong code should not compile!
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: a hardware-independent software debouncer
« Reply #30 on: June 08, 2016, 07:59:49 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.
Like my Breville toaster oven... grrrrr....
Still you have to consider what can happen if a switch starts to make contact by itself due to moisture or dirt. Do you want your toaster to start toasting by itself with the chance of setting the bread crumbs inside on fire and burning down your house? One of the systems I worked on was for dispensing drinks in bars and restaurants. Replacing a flaky switch is much cheaper than cleaning up a 2000 liter beer spill.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline KL27x

  • Super Contributor
  • ***
  • Posts: 4103
  • Country: us
Re: a hardware-independent software debouncer
« Reply #31 on: June 09, 2016, 07:38:08 pm »
+1 to Andy C. For human input switches, I prefer the action to occur immediately, then time out long enough for the switch bounces to end. This is where the noise from the switch, itself, and not other devices on the power rail, are the only concern, of course. If the circuit is getting false signals outside of switch transition that are big enough to register state change, I would probably try to fix the hardware. Many of the micros I use have Schmitt trigger inputs available. I don't often have such problems.  :-// 
« Last Edit: June 09, 2016, 07:41:44 pm by KL27x »
 

Offline wraper

  • Supporter
  • ****
  • Posts: 16864
  • Country: lv
Re: a hardware-independent software debouncer
« Reply #32 on: June 09, 2016, 07:43:11 pm »
+1 to Andy C. For human input switches, I prefer the action to occur immediately, then time out long enough for the switch bounces to end. This is where the noise from the switch, itself, and not other devices on the power rail, are the only concern, of course. If the circuit is getting false signals outside of the switch that are big enough to register state change, I would probably try to fix the hardware. Many of the micros I use have Schmitt trigger inputs available. I don't often have such problems.  :-//
<20-30 milliseconds delay is not fast enough for you?
 

Offline dannyfTopic starter

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: a hardware-independent software debouncer
« Reply #33 on: June 09, 2016, 11:58:27 pm »
There is some merit in responding to the leading edge of key bounces, if you assume that a key wouldn't bounce unless it is pressed. To me, however, that is not a robust enough of an assumption, as there could be line noise, or accidental but short key presses (from mechanical shock for example). But I certainly understand how others may choose that approach.

If so, the Kuhn debouncer can be easily adapted to capture most (but not all) such cases, by changing the key_get() routine to this:

Code: [Select]
//return key state
KEY_STATE key_get(KEY_TypeDef *key) {
return (key->cnt_key != 0)?KEY_PRESSED:KEY_NOTPRESSED; //could be made to return KEY_BOUNCE
}

Essentially it is saying that as long as the debouncer is working (key->cnt_key !=0), the key must have been pressed.

That logic fails if the duration of signal KEY_NOTPRESSED is longer than the duration of signal KEY_PRESSED, which statistically speaking is not as likely as the other way around conditional on the key having been pressed.
================================
https://dannyelectronics.wordpress.com/
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6460
  • Country: nl
Re: a hardware-independent software debouncer
« Reply #34 on: June 10, 2016, 05:34:59 am »
What i have seen done multiple times on adc inputs and could also work for switches is using an moving average algorithm, the size of the buffer, sampling frequency and threshold will determine the debounce and response time. However these cost ram which usually is a scarce resource in embedded projects.
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3478
  • Country: us
Re: a hardware-independent software debouncer
« Reply #35 on: June 10, 2016, 08:06:45 am »
Let's say you have a press and release, like most button switches.   Of course, you can respond to the first change, but if you are going into an interrupt, don't you still have to wait for the release bounce to end before exiting? (Or use some other mechanism to delay enabling that interrupt.)

The SR method with cross-connected NAND's actually removes bounce rather than waits for it to be over.  Unfortunately, that method requires a double-throw switch, which are hard to find.

After a bit more reading, I have decided to try using the "release" edge of a button switch to initiate an interrupt, rather than the first change, and to go with hardware debounce.  Hardware plus interrupt on release avoids having to poll the switches and/or to wait in the interrupt.

John 
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: a hardware-independent software debouncer
« Reply #36 on: June 10, 2016, 08:14:40 am »
In the ISR, you set a flag which indicates that a button has been pressed, do whatever you want to do with timers and counters to de-bounce the switch, then exit. It should be a very quick process.

In some foreground task, you poll the flag at a convenient time to see if it's been set since last time you checked. If it has, then you clear the flag, and do whatever the button is meant to do. This could take quite a long time, so it's not something you want to be doing in an ISR anyway.

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3478
  • Country: us
Re: a hardware-independent software debouncer
« Reply #37 on: June 10, 2016, 08:25:20 am »
In the ISR, you set a flag which indicates that a button has been pressed, do whatever you want to do with timers and counters to de-bounce the switch, then exit. It should be a very quick process.


That (underlined) is what I want to avoid.   Debounce usually has a wait of 10ms to 40ms.  At 16 MHz with a PIC, even 10 ms is equal to a lot of instructions.   That seems to be contrary to the advice to keep interrupts short.

On the other hand, if you don't even enter the ISR until all bouncing is over, then time there can be short.  As for the flags being set and so forth, that is what I do.

John
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: a hardware-independent software debouncer
« Reply #38 on: June 10, 2016, 08:36:15 am »
I think you misunderstand how debouncing is done.

The ISR is entered each time the switch input changes state. This is exactly once per press and once per release for a 'perfect' switch, and maybe 2 or 3 times per change for a bouncy one.

The purpose of the de-bouncing code is to make a decision as to whether each state change is due to an actual press or release, or whether it's just contact bounce. Once that decision has been made, the ISR exits. Since the code to make that decision is simple, the actual time spent in the ISR is minimal.

There's clearly some differences of opinion on what the criteria should be, but I think we're all in agreement that you don't just sit in the ISR doing nothing until the debounce period has elapsed.

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3478
  • Country: us
Re: a hardware-independent software debouncer
« Reply #39 on: June 10, 2016, 09:35:53 am »
@AndyC_772
Assume you enter the ISR on the first rising edge as has been suggesed and the switch bounces for 10 ms.   A short ISR will exit and re-enable the interrupt well before that bouncing ends.    So, you have the potential to get multiple interrupts.

Now, if you wait until the bouncing is over, then you are stuck in the routine for a long time.  Hardware debounce will delay entering the routine, but it doesn't carry a risk of exiting while the switch is still bouncing.

John
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: a hardware-independent software debouncer
« Reply #40 on: June 10, 2016, 10:08:37 am »
So, you have the potential to get multiple interrupts

Yes, you do, absolutely. Intentionally so, by design. Each individual change in state of the button input causes a jump to the ISR.

Your ISR in turn makes a decision about whether the state change was 'real' or not.

If it's 'real', then the ISR signals to some other process that the button state has really changed, and requires action. That other process updates the UI, changes a setting, or whatever else the button was meant to do.

If not, and the switch is deemed to simply be bouncing, the ISR exits with no further action taken.

Offline dannyfTopic starter

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: a hardware-independent software debouncer
« Reply #41 on: June 10, 2016, 10:33:11 am »
Quote
using an moving average algorithm, the size of the buffer, sampling frequency and threshold will determine the debounce and response time. However these cost ram which usually is a scarce resource in embedded projects.

The Kuhn debouncer is a moving average algorithm.

Quote
I have decided to try using the "release" edge of a button switch to initiate an interrupt, rather than the first change, and to go with hardware debounce.

Release-based actions are more reliable, obviously. But it is a little counter-intuitive for the user, and it also requires debouncing: the buttons bounces on both presses and releases.

If you are simply detecting on the first release, and ignoring the subsequent bounces, the Kuhn debouncer can be modified easily to detect that too.
================================
https://dannyelectronics.wordpress.com/
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3478
  • Country: us
Re: a hardware-independent software debouncer
« Reply #42 on: June 10, 2016, 11:08:09 am »
Right now, I have re-designed the circuit to use hardware debounce.

Even with testing only for first release, you are still talking about a of time in the ISR, unless you somehow delay re-enabling that interrupt.

BTW, the code I posted earlier is not really Kuhn's method.  It looks for consecutive ones or zeros, which is what the MAX681x and MC14490 also do.  I later wrote some code for averaging that actually uses Kuhn's method and works pretty well.  Each routine is 9 instructions, excluding the delay call or macro.

Will these debouncing delays actually affect what I am doing now?  Probably not.  The only time-critical interrupt in my code is caused by a TMR0 overflow.

Regards, John
   
« Last Edit: June 10, 2016, 11:50:42 am by jpanhalt »
 

Offline dannyfTopic starter

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: a hardware-independent software debouncer
« Reply #43 on: June 10, 2016, 11:23:17 am »
Quote
It looks for consecutive ones or zeros

The Kuhn debouncer can be made to do that too. For example, rather than decrementing the integrator on KEY_NOTPRESSED, you reset it. Under that scheme, KEY_PRESSED is returned by key_get() if and only if a consecutive number of KEY_PRESSED is detected.

The beauty of this particular implementation is the separation of the integration and the detection of the key's states.
================================
https://dannyelectronics.wordpress.com/
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: a hardware-independent software debouncer
« Reply #44 on: June 10, 2016, 01:51:38 pm »
I think you misunderstand how debouncing is done.

The ISR is entered each time the switch input changes state. This is exactly once per press and once per release for a 'perfect' switch, and maybe 2 or 3 times per change for a bouncy one.
That is a very, really very bad idea! I've seen embedded applications come to a grinding halt (*) due to interference on a switch input. If you use an interrupt to flag a switch then you'll also need to disable the interrupt at that point and enable it from the main process. This also kinda negates the need for using interrupts because what is the difference between polling a flag and a GPIO? Interrupts are for stuff which needs a timely response which cannot be guaranteed by the main loop. A switch is unlikely to need an interrupt since a response time below 100ms to 200ms is perceived as immediately.

* Worst example I've seen is several meters of wire connected to a doorbell on an unprotected I/O pin. At some point the system started to become flaky but my co-workers tasked with that project could not figure out what was wrong. I just never realised they where so stupid to use an interrupt for detecting a key switch input.  :palm: -out of hands and faces error-
« Last Edit: June 10, 2016, 01:55:42 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3478
  • Country: us
Re: a hardware-independent software debouncer
« Reply #45 on: June 10, 2016, 02:16:33 pm »
Just and FYI to add.   I was browsing the new 3rd edition of Horowitz and Hill and came across this "debouncer" on page 730.  There is a brief discussion of why it works there.  So far as I can tell, it is not in the 2nd edition.

I had not seen such a simple version before.  Would be interested in testing it, but I can't find a bad switch to do it with. :)

John




 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: a hardware-independent software debouncer
« Reply #46 on: June 10, 2016, 03:01:30 pm »
Pretty useless since 99.999% of the pushbuttons is single pole.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline bingo600

  • Super Contributor
  • ***
  • Posts: 1989
  • Country: dk
Re: a hardware-independent software debouncer
« Reply #47 on: June 10, 2016, 03:04:44 pm »
I'm debouncing in a 10ms timer IRQ
Using Peter D's code , that implements (if  remember corect) a 4bit barrelshifter

Peter's code (attached)
http://community.atmel.com/projects/efficient-key-debounce


Threads (German)
https://www.mikrocontroller.net/topic/tasten-entprellen-bulletproof#new


I never had any problems , and even extended it to so a 4 x 3 keyboard wo. problems.

/Bingo

 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: a hardware-independent software debouncer
« Reply #48 on: June 10, 2016, 03:10:09 pm »
The golden rule is: don't use lines from buttons or switches as interrupt sources! Ofcourse you can use a timer interrupt to poll keys. The only (extra) problem you'll have is parallel thread synchronisation to convey the switch value to the main process.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline dannyfTopic starter

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: a hardware-independent software debouncer
« Reply #49 on: June 10, 2016, 03:35:07 pm »
Quote
Peter's code (attached)
http://community.atmel.com/projects/efficient-key-debounce

The following change in the Kuhn debouncer would do the same thing:

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

The rest remains unchanged.

Under XC8 Free, the Kuhn version compiles to 17 instructions and the Peter version compiles to 36 instructions. However, it does have the advantage of being able to read multiple buttons at once, assuming that they are on the same port.
================================
https://dannyelectronics.wordpress.com/
 

Offline klunkerbus

  • Supporter
  • ****
  • Posts: 162
  • Country: us
  • Electrical Engineer (retired early)
Re: a hardware-independent software debouncer
« Reply #50 on: June 10, 2016, 03:38:08 pm »
I'm debouncing in a 10ms timer IRQ
Using Peter D's code...

I've been meaning to mention the Danni/Dannegger debounce myself.  It was developed for AVR, but there's no reason why the algorithm couldn't be used on any hardware with some sort of periodic housekeeping interrupt where the switch inputs can be sampled.   I usually have one running at 1mSec or 5mSec intervals.  Crazy efficient; the code supports 8 inputs with the same processing cycles as one input. 

There's not much to the code but it can hard to understand, and sometimes I wish for more than 4 matching states in the vertical adder before change of state is detected.  But it usually works pretty good except on my crappiest switches.  Gurus and moderators in the AVRFreaks forum have a heyday blasting any other scheme.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf