In addition to the other great responses you've received:
I often use dual (and occasionally triple) functions per key (I'll describe dual here.) This saves component count and cost in smaller cost-sensitive applications.
You can have the same key invoke different actions on short and long (or short, medium, and long) presses. I normally use <2 sec for short, and >5 sec for long.
The shorter presses can be acknowledged only on releasing the key because you can't know if the user intends to keep it pressed even longer for the next function. This means you need to debounce both key-down and key-up to save you from the possibility of noise appearing as a (premature) release, using similar methods to those described in other replies.
The longest key can be acknowledged regardless of a release but I prefer to wait for a release anyway which also gives me an indication of possible stuck-key errors (indefinite presses), if it doesn't happen within some reasonable time. So, in reality, there is always an extra quite long "hidden" key which is returned as KeyError.
I am told that the "real world" is where the walls are not padded. I do not know for sure, since they won't let me out to see it.
Is the simple software delay suitable for real world applications?
Yes it will work 100% with a 2ms switch and very reliable for a 5, 10 15. But as you approach 100 the reliability of proper detection falls away as the probability of sampling at 5 discrete times in a row when the switch is in the bounced state rises.
The "padding" in the timer method eliminates this.
This method also works as a noise/glitch filter as well, although if you have noise/glitches that can cause a state change on an input you probably should be looking elsewhere.
I am not saying it is bad concept, I use both basic methods myself, where appropriate.
Regards David
Message Edited by peg on 2006-07-02 12:21 PM
Fair enough!
Somehow I got it in to my head that you were sampling at 1ms rate which led me to comment as I did. 25 consecutive samples of an uncontrolled frequency source would be impossible enough.
FC wrote:Is the simple software delay suitable for real world applications?Since the debounce is specific for each type of switch, the bounce needs to be studied for the best debounce technique.
Yes, normally it is. The debounce time is usually inversly proportional to the cost of the switch. Good quality keypad switches can be safely debounced in 10-15ms.
What else did you have in mind for the "real world applications" where you think it wouldn't work?
If you can't debounce it in 100ms you should probably looking at a different switch rather than more complex code as the "bounce" time will probably only get worse with time.
Regards David
Hi Bud,
Now that you have quantified the ways, others will suggest more!
If you have a spare timer, you can scale it and set the modulo to get your delay.
Then when you see the switch operate :
Read TPMxSC to help next step
Clear TOF inTPMxSC
Write to TPMxCNTH to reset counter
Now you can wait for TOF to become set or get it to generate an interrupt
Don't clear TOF as you normally would when you service this.
Then perform the intended switch response. (if you did not do it when you first detected closure)
This method saves having to do the 16-bit adds.
Regards David
Message Edited by peg on 2006-06-30 03:11 PM
See, there you go, even before I finished typing method 3 arrives!
Some comments on this method though:
1. switch needs to remain down at the end of debounce. (not always an issue)
2. if a second switch changes state within the firsts debounce the debounce can be extended to double length (now it has to be down for 2 x debounce time)
3. You don't get to react to the closure until after the debounce time (or 2?).
If it is a keypad or array of finger operated buttons this is not a problem, but if they are machine switches etc this could cause havoc.
You will notice I avoided scrutiny by only answering the exact question about implementing the timer.
This is one of those subjects that a first seem innocuous but can be quite complicated and dependant on many other things.
Regards David
Message Edited by peg on 2006-06-30 03:13 PM
Bud wrote:There seems to be 2 ways to handle switch debounce when you want to read into a port. One is to develop a delay loop the second is to utilize a timer. the delay loop is fairly easy.. how do I initialize a timer to be randomly called only when I want to debounce the switch? I am utilizing a 9sc08gt16 processor.ThanksBud
Hello Bud,
To generate non-critical time delays, such as for switch debounce, LED flashing, etc, there are a couple of simple methods using the timer. The first uses a periodic interrupt such as RTI or timer overflow. The second method requires simply to read the timer count register, and does not specifically require any interrupts to be enabled.
Method 1
The periodic interrupt should occur multiple times within the timeout period - the actual timeout period will have an uncertainty of one interrupt period (i.e. +/- one half period). Allocate one or more global variables (of byte or word size), one variable for each simultaneous timeout that may need to occur, say timeout1, timeout2.
Within the timer ISR place the following code for each variable, to decrement the variable unless already zero.
if (timeout1) timeout1 -= 1;
if (timeout2) timeout2 -= 1;
etc.
Then within the main program, where you need the timeout delay period, the following code should work.
for (timeout1 = DEBOUNCE; timeout1; );
or alternatively
timeout1 = DEBOUNCE;
while (timeout1);
Method 2
If the timer overflow method should have insufficient resolution because the overflow period is too long (and you do not wish to alter timer settings for other reasons), simply chose a bit within the timer count register (TCR) that toggles at a suitable rate, and use this as the basis for decrementing a timeout variable. The following example uses bit 9 for the timing.
#define MASK 0x0100
for (timeout1 = DEBOUNCE; timeout; ) {
while (TCR & MASK == 0);
while (TCR & MASK);
timeout1--;
}
I hope this provides some ideas.
Regards Mac
Message Edited by bigmac on 2006-06-30 04:59 PM