Author Topic: ESP8266 - Pushbuttons, debounce & how to easy debounce story  (Read 17084 times)

0 Members and 1 Guest are viewing this topic.

Offline TJ232

  • Frequent Contributor
  • **
  • Posts: 321
  • Country: 00
  • www.esp8266-projects.com
    • ESP8266 Projects
ESP8266 - Pushbuttons, debounce & how to easy debounce story
« on: March 31, 2015, 07:33:23 am »
  What is your favourite technique and what do you prefer to use in your projects? 

   Below you can see and read about a short experiment with ESP8266 CBDB Board and pushbuttons play or how to use a First order Low Pass Filter combined with Interrupt Trigger on falling/rising edge technique to obtain a very clean response over a broad range of key pressing speeds.

Link http://www.esp8266-projects.com/2015/03/buttons-pushbuttons-and-debouncing-story.html

Video



 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2228
  • Country: nz
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #1 on: March 31, 2015, 10:01:46 am »
When it comes to human interaction I like to do my debounce in software, by having an interrupt on a timer and waiting for a suitable number that differ from the and are in agreement before acting on it. It trades a word of RAM for a few less bits on the board, and can be tweaked without lifting a soldering iron.

A case could also be made for this being better for low power designs - in the ISR you can turn the pull-ups on, do a tiny bit of work (maybe update a tick counter), check the input state, and then turn the pull-ups off, all in under a microsecond - but of course if you don't have a need for a timer then sleeping while waiting for an interrupt on change of the port is probably better.

You have the option check the input less frequently when no activity has been seen for a few seconds, reducing the number of CPU cycles burnt looking for input in the ISR.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline ajb

  • Super Contributor
  • ***
  • Posts: 1744
  • Country: us
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #2 on: March 31, 2015, 10:12:23 pm »
Once you debounce in software you're halfway to doing short vs long press detection (such as for fast scrolling through menus or secondary button functions), so software makes a lot of sense.
 

Online digsys

  • Supporter
  • ****
  • Posts: 2156
  • Country: au
    • DIGSYS
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #3 on: March 31, 2015, 10:35:16 pm »
Never understood s/ware debounce. Seems such a waste of processing time and memory. I have always used filter caps, which I select to
give app 4x the max response rate I require .. after all it's just a human pushing the buttons. Why would I need to know the 200 noise
glitches on make / break at nS / uS accuracy ?? The ol' cap has never failed me.
Hello <tap> <tap> .. is this thing on?
 

Offline TJ232

  • Frequent Contributor
  • **
  • Posts: 321
  • Country: 00
  • www.esp8266-projects.com
    • ESP8266 Projects
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #4 on: April 01, 2015, 04:18:45 am »
Never understood s/ware debounce. Seems such a waste of processing time and memory. I have always used filter caps, which I select to
give app 4x the max response rate I require .. after all it's just a human pushing the buttons. Why would I need to know the 200 noise
glitches on make / break at nS / uS accuracy ?? The ol' cap has never failed me.

 :-+  :-+  :-+
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 5779
  • Country: nl
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #5 on: April 01, 2015, 08:25:39 am »
Never understood s/ware debounce. Seems such a waste of processing time and memory. I have always used filter caps, which I select to
give app 4x the max response rate I require .. after all it's just a human pushing the buttons. Why would I need to know the 200 noise
glitches on make / break at nS / uS accuracy ?? The ol' cap has never failed me.
+1
I try to keep everything <1ms away from the micro as much as possible, why waiste good cycles when a cheap component can do it for you.
Keep the non-relevant information as much as possible away from your code at the end you probably need the spared bytes or cycles anyway for much more relevant things. That said, when you have multiple buttons a keymatrix with row/column scanning makes sense but then the scanrate should be slower as the bounce.
 

Offline Marco

  • Super Contributor
  • ***
  • Posts: 4625
  • Country: nl
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #6 on: April 01, 2015, 02:16:55 pm »
If you have a high'ish frequency timer interrupt to begin with then it doesn't really add anything.
 

Online Jeroen3

  • Super Contributor
  • ***
  • Posts: 3403
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #7 on: April 01, 2015, 02:52:07 pm »
If you need debouncing it means your pushbutton are connected to an interrupt. And interrupts should be exclusively for inter-ic communications to prevent issues. So you'd need extra hardware, which costs money and board space. Instead of that, reading a key is done every 20 ms. Which is plenty for user-interacted-actuators. Measure the down-time of the key, in x*20ms, and you can do some filtering on press times.

A single event is a press-and-release with 2 to 15 times 20ms.
A hold event is more than 20 * 20ms. Which is used to increment values automatically. The event is fired repeatedly.
Depending on the application usage of the key, a long hold event may be enabled, with a down-time of several seconds.

This all can be run from either a single thread, interrupt routine, or call from super-loop. With a for-loop and a settings struct, so the "module" is usable in ALL future projects with similar hardware.

A human does not need sub-milliseconds interaction with hardware, so attaching buttons to interrupts is useless. ( except for wake-up purposes )
 

Offline TJ232

  • Frequent Contributor
  • **
  • Posts: 321
  • Country: 00
  • www.esp8266-projects.com
    • ESP8266 Projects
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #8 on: April 01, 2015, 04:08:42 pm »
If you need debouncing it means your pushbutton are connected to an interrupt. And interrupts should be exclusively for inter-ic communications to prevent issues. So you'd need extra hardware, which costs money and board space. Instead of that, reading a key is done every 20 ms. Which is plenty for user-interacted-actuators. Measure the down-time of the key, in x*20ms, and you can do some filtering on press times.

A single event is a press-and-release with 2 to 15 times 20ms.
A hold event is more than 20 * 20ms. Which is used to increment values automatically. The event is fired repeatedly.
Depending on the application usage of the key, a long hold event may be enabled, with a down-time of several seconds.

This all can be run from either a single thread, interrupt routine, or call from super-loop. With a for-loop and a settings struct, so the "module" is usable in ALL future projects with similar hardware.

A human does not need sub-milliseconds interaction with hardware, so attaching buttons to interrupts is useless. ( except for wake-up purposes )


Interesting concept, can you elaborate more how a "super-loop/for-loop" setup can be better and use less resources that a interrupt driven one? to make it easier let's suppose it's a low power one, battery & solar powered. I'm really looking forward to see some comparative data. How will look your for-loop routine in a RTOS environment?

 

Online Jeroen3

  • Super Contributor
  • ***
  • Posts: 3403
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #9 on: April 01, 2015, 05:22:22 pm »
How a "super-loop/for-loop" setup can be better and use less resources that a interrupt driven one
The superloop requires an interrupt to restart, because a superloop will end __wfi or with sleep modes. It won't be more efficient under normal circumstances.
A rtos implementation is equal to an reentrant interval-isr, it is only looped infinitely each time the sleep-api expires. A superloop is about the same, an reentrant routine is called when the last execution time is 20ms ago. The advantage of an rtos is that your routine does not need to be reentrant. But an rtos in very lower power stuff is usually unnecessary overhead.
When you're not on very-lower-power constraints, consider using the arm systick to increment a global time variable every 1 ms. Or when if(>) are difficult, decrement-saturate a number of software timers and compare boolean. This makes software more portable.

In a typical low power application the hardware wakes up sometimes anyways, doing RF, sensors or other communications or display. If will be very fast to compare an input register of GPIO to an known mask to determine if further action is required regarding user requests.

If the main chip only wakes up when a button is pressed, as in a remote control, the interrupt is only used to wake up the chip. Make sure to add debouncing logic externally because a low level of significant time is required to successfully wake up any micro. Erroneous behavior might occur when this low level is not long enough. Read the errata sheets before using such wake-up features.
 

Offline TJ232

  • Frequent Contributor
  • **
  • Posts: 321
  • Country: 00
  • www.esp8266-projects.com
    • ESP8266 Projects
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #10 on: April 01, 2015, 07:13:12 pm »
How a "super-loop/for-loop" setup can be better and use less resources that a interrupt driven one
The superloop requires an interrupt to restart, because a superloop will end __wfi or with sleep modes. It won't be more efficient under normal circumstances.
A rtos implementation is equal to an reentrant interval-isr, it is only looped infinitely each time the sleep-api expires. A superloop is about the same, an reentrant routine is called when the last execution time is 20ms ago. The advantage of an rtos is that your routine does not need to be reentrant. But an rtos in very lower power stuff is usually unnecessary overhead.
When you're not on very-lower-power constraints, consider using the arm systick to increment a global time variable every 1 ms. Or when if(>) are difficult, decrement-saturate a number of software timers and compare boolean. This makes software more portable.

In a typical low power application the hardware wakes up sometimes anyways, doing RF, sensors or other communications or display. If will be very fast to compare an input register of GPIO to an known mask to determine if further action is required regarding user requests.

If the main chip only wakes up when a button is pressed, as in a remote control, the interrupt is only used to wake up the chip. Make sure to add debouncing logic externally because a low level of significant time is required to successfully wake up any micro. Erroneous behavior might occur when this low level is not long enough. Read the errata sheets before using such wake-up features.

So, basically you agree with my opinion that a mix of hardware debouncing + button event subroutine is more desirable than a full software approach as exemplified for example by hamster_nz.

 I am curious to hear about different approaches especially because I have meet a lot of app engineers ready to write/ask for the most sophisticated functions to avoid a poor man RC filter or even a plain simple Capacitor :)
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 14731
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #11 on: April 01, 2015, 07:30:18 pm »
Whether it's single level (one bit binary) or multilevel (ADC) data, it's always best to filter in both analog and digital domains.  The filtering for an analog signal might need to be more particular (specified cutoff, overshoot, etc.), but for debounce it can be pretty crude (a single RC with a time constant a bit longer than the expected bounce period).

What I like to do in digital is use a four bit shift register, and majority voting to change an R-S flip-flop (in VHDL, if (shift[0] + shift[1] + shift[2] + shift[3] == 3) then output <= '1'; elsif (shift[0] + shift[1] + shift[2] + shift[3] == 0) then output <= '0';).  Which can be delayed by one additional clocked D-f/f to provide edge detection (if (output == '1' and outputdly == '0') then... etc.).

Such a debounce will respond imperceptibly quickly if the clock rate and time constant are on the order of 1-5ms, and so solidly that a contact wire can be dragged along a rusty panel and the intermittent signal will either be ignored or detected properly.

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Online Jeroen3

  • Super Contributor
  • ***
  • Posts: 3403
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #12 on: April 01, 2015, 08:30:16 pm »
I am curious to hear about different approaches especially because I have meet a lot of app engineers ready to write/ask for the most sophisticated functions to avoid a poor man RC filter or even a plain simple Capacitor :)
I'm also curious to software that is capable of reading double or triple keypress events. I've never put much thought in it myself.

It's typical to always have an RC filter on your switches to prevent glitches. Or worse on vibrating devices with damaged buttons. Industrial panels tend to lack maintenance, even when damaged, and vibrate heavily. True stress test for debouncers.

ADC multiplexed keys lack dual-key operation. And I did once implement the 20ms read trick with a single 32 bit shift register in software and counting the amount of consecutive 1 bits. Fully 1 is a hold-key, obviously.
« Last Edit: April 01, 2015, 08:33:04 pm by Jeroen3 »
 

Offline SL4P

  • Super Contributor
  • ***
  • Posts: 2130
  • Country: au
  • There's more value if you figure it out yourself!
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #13 on: April 01, 2015, 09:09:30 pm »
So, for a number of buttons - or a key matrix, you guys would put a load of RC debounce pads?
I can't think of any time in the last ten years that I've used RC debouncing, except on non-logic contacts (power, input or output signal path etc...)

As said above, SW debounce is relatively simple - allowing reconfiguration, press-duration timing, inversion etc dynamically with zero hardware revisions...?!
Don't ask a question if you aren't willing to listen to the answer.
 

Offline mrkev

  • Regular Contributor
  • *
  • Posts: 214
  • Country: cz
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #14 on: April 01, 2015, 09:26:40 pm »
When using uC, most people use loop in main program that sweeps over buttons. There is nothing easier than wrote it the way that after one button was pushed, it's not gonna detect another push for x times that loop is passing through. And for
double-clicks, it's really not that hard to just use this dead-zone after first push to eliminate ringing, wait for the release and then just time the gap until another push...
 

Offline electr_peter

  • Supporter
  • ****
  • Posts: 936
  • Country: lt
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #15 on: April 01, 2015, 09:44:09 pm »
SW and HW debouncers do the same function, literally. HW can provide other functions as well at the same time.

RC + schmitt trigger in HW has equivalent in SW. Preferably use polling method, because bad switch bounce can create too many interrupts and create havoc in timing.

In ideal world or very harsh conditions, HW+SW debouncer could be used. For mild or moderate conditions, SW solution provides more flexibility because debounce can be easily tuned to suit user input requirements and switch debounce timing. HW solution requires adjustment of values each time.
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 14731
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #16 on: April 01, 2015, 11:46:22 pm »
So, for a number of buttons - or a key matrix, you guys would put a load of RC debounce pads?
I can't think of any time in the last ten years that I've used RC debouncing, except on non-logic contacts (power, input or output signal path etc...)

As said above, SW debounce is relatively simple - allowing reconfiguration, press-duration timing, inversion etc dynamically with zero hardware revisions...?!

Scanning a matrix doesn't always have the time to filter for debounce (indeed, the scan time per position might be less than the typical bounce period, so that bounce waveforms will technically become aliased -- a messy situation indeed!), but some filtering (and ESD protection!) is always welcome, especially when you consider the RF susceptibility of a row of naked logic inputs -- under the influence of ambient electric fields or RF conducted along cables, who knows what kind of voltages might pop up there!  (As for ESD, membrane types are usually pretty good -- they're behind a nice thick layer of plastic film, able to hold off pretty serious voltage.  But after some wear and a few million cycles, you might start getting direct strikes from charged fingers, so for long life products, you still want to keep that in mind.)

The additional filtering can then be implemented digitally, turning the array into a vector of button states and using a delay-and-voting filter on each bit.  You should also add a disambiguation function, that either freezes the button state while multiple presses are detected, or sets everything to zero, or ignores further changes until all buttons are cleared.

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #17 on: April 02, 2015, 02:04:27 am »
I always put a small R/C filter on each switch input.  It kills off any RF that the wiring may be picking up and smooths out the switch contact bounce at the same time.

My usual switch scan rate is every 50ms with that time extended upon detecting a valid press.  That seems to lock out any wobbly presses from the user.
 

Offline wraper

  • Supporter
  • ****
  • Posts: 11034
  • Country: lv
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #18 on: April 02, 2015, 02:22:23 am »
I like this one, it's ultra robust. It works even if input never stabilizes and consists of never ending bounce.
Quote
/******************************************************************************
debounce.c
written by Kenneth A. Kuhn
version 1.00

This is an algorithm that debounces or removes random or spurious
transistions of a digital signal read as an input by a computer.  This is
particularly applicable when the input is from a mechanical contact.  An
integrator is used to perform a time hysterisis so that the signal must
persistantly be in a logical state (0 or 1) in order for the output to change
to that state.  Random transitions of the input will not affect the output
except in the rare case where statistical clustering is longer than the
specified integration time.

The following example illustrates how this algorithm works.  The sequence
labeled, real signal, represents the real intended signal with no noise.  The
sequence labeled, corrupted, has significant random transitions added to the
real signal.  The sequence labled, integrator, represents the algorithm
integrator which is constrained to be between 0 and 3.  The sequence labeled,
output, only makes a transition when the integrator reaches either 0 or 3. 
Note that the output signal lags the input signal by the integration time but
is free of spurious transitions.
 
real signal 0000111111110000000111111100000000011111111110000000000111111100000
corrupted   0100111011011001000011011010001001011100101111000100010111011100010
integrator  0100123233233212100012123232101001012321212333210100010123233321010
output      0000001111111111100000001111100000000111111111110000000001111111000

I have been using this algorithm for years and I show it here as a code
fragment in C.  The algorithm has been around for many years but does not seem
to be widely known.  Once in a rare while it is published in a tech note.  It
is notable that the algorithm uses integration as opposed to edge logic
(differentiation).  It is the integration that makes this algorithm so robust
in the presence of noise.
******************************************************************************/

/* The following parameters tune the algorithm to fit the particular
application.  The example numbers are for a case where a computer samples a
mechanical contact 10 times a second and a half-second integration time is
used to remove bounce.  Note: DEBOUNCE_TIME is in seconds and SAMPLE_FREQUENCY
is in Hertz */

#define DEBOUNCE_TIME      0.3
#define SAMPLE_FREQUENCY   10
#define MAXIMUM         (DEBOUNCE_TIME * SAMPLE_FREQUENCY)

/* These are the variables used */
unsigned int input;       /* 0 or 1 depending on the input signal */
unsigned int integrator;  /* Will range from 0 to the specified MAXIMUM */
unsigned int output;      /* Cleaned-up version of the input signal */


/* Step 1: Update the integrator based on the input signal.  Note that the
integrator follows the input, decreasing or increasing towards the limits as
determined by the input state (0 or 1). */

  if (input == 0)
    {
    if (integrator > 0)
      integrator--;
    }
  else if (integrator < MAXIMUM)
    integrator++;

/* Step 2: Update the output state based on the integrator.  Note that the
output will only change states if the integrator has reached a limit, either
0 or MAXIMUM. */

  if (integrator == 0)
    output = 0;
  else if (integrator >= MAXIMUM)
    {
    output = 1;
    integrator = MAXIMUM;  /* defensive code if integrator got corrupted */
    }

/********************************************************* End of debounce.c */
« Last Edit: April 02, 2015, 02:24:10 am by wraper »
 

Offline wraper

  • Supporter
  • ****
  • Posts: 11034
  • Country: lv
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #19 on: April 02, 2015, 02:34:53 am »
I could easily achieve 40+ 100% bounce free presses in a second with this method. Mostly tested with signal generator giving out bouncy crap because it's tough for the fingers to press that fast  :)
 

Offline rx8pilot

  • Super Contributor
  • ***
  • Posts: 3565
  • Country: us
  • If you want more money, be more valuable.
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #20 on: April 02, 2015, 02:54:33 am »
I have been using RC+Schmidt trigger in HW for debouncing. I am not saying its the best. It was chosen for two reasons.

1: The system needs to be very reliable and I did not want the chance of a CPU cycle hog messing anything up.
2: My coding skills are modest so I did not trust myself to stay out of trouble. I have been focusing more and more on software so I may try some SW techniques outside of a production design.

My current project has 3 8bit AVR's that are all fairly timing sensitive and already more busy than I would like.

Factory400 - the worlds smallest factory. https://www.youtube.com/c/Factory400
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 5779
  • Country: nl
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #21 on: April 02, 2015, 10:37:53 am »
Some of these debouncing algorithms take up quite a few cycles, besides that you keep on scanning the button(s) each x ms probably calling a function (everything on the stack and back) taking up again unnecessary cycles.
When does a user press a button, perhaps 0,00001% of the lifetime of the product.
So reserving just a single hw (rc filter) debounced interrupt for flagging a potential keyaction and in that interrupt just set a software flag that the key(s) should be polled for some time can have benefits IMO.
 

Online Jeroen3

  • Super Contributor
  • ***
  • Posts: 3403
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #22 on: April 02, 2015, 11:34:04 am »
Some of these debouncing algorithms take up quite a few cycles...
The 20ms read interval should not. It takes 0.004% of cpu time on a 8 MHz ARM cortex m3? (600 cycles for 8 buttons)
Should be a little more on M0, but still sub-percentage numbers.

If you are tight in 100 counts of cycles you have the wrong chip.
 

Offline mrkev

  • Regular Contributor
  • *
  • Posts: 214
  • Country: cz
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #23 on: April 02, 2015, 01:56:18 pm »
Some of these debouncing algorithms take up quite a few cycles, besides that you keep on scanning the button(s) each x ms probably calling a function (everything on the stack and back) taking up again unnecessary cycles.
When does a user press a button, perhaps 0,00001% of the lifetime of the product.
So reserving just a single hw (rc filter) debounced interrupt for flagging a potential keyaction and in that interrupt just set a software flag that the key(s) should be polled for some time can have benefits IMO.
If you have two buttons that are gonna be rarely pressed and if you are not using ext. interupt pins for anything else, sure...
But in many cases, software is not doing much, without input from the user.
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 5779
  • Country: nl
Re: ESP8266 - Pushbuttons, debounce & how to easy debounce story
« Reply #24 on: April 02, 2015, 07:37:35 pm »
And you can go to ultra low power mode for longer times ( than 20 ms), but you can use the same pin you use for scanning as the ext. int. pin, so no extra pin needed.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf