View previous topic :: View next topic |
Author |
Message |
Bryan
Joined: 23 Apr 2005 Posts: 73
|
Debouncing |
Posted: Wed Oct 26, 2005 6:13 pm |
|
|
I am having a terrible time with getting my debounce routines to work for several interrupt driven buttons. Does the PIC queue interrupts that occur on the same port and then execute them in order? My problem here is that I have buttons that are supposed to move an arrow on an LCD one spot per button press (left or right depending on which button is pressed), but it often moves many spaces meaning multiple interrupts are occuring for each press (I am pretty sure that this means it is registering every bounce as an interrupt). I would think that if the PIC isn't queueing the interrupts that a delay would suffice to stop the bouncing, but the delays aren't working for me. Here is my code:
Code: |
/****************************************************************************
* NAME: move_right
* DESCRIPTION: Sets the right arrow move right boolean to true
*****************************************************************************/
#int_ext
void move_right()
{
moveright = true;
}
|
and then in the main loop...
Code: |
if (moveright && mode == 1)
{
delay_ms(20);
if(leftarrowpos + 1 != rightarrowpos)
{
leftarrowpos += 1;
}
else
{
leftarrowpos = 12;
}
moveright = false;
redisplay();
}
|
I am not sure why this still bounces so much, and I have tried some of the routines given on this site as well as putting the delay in the interrupt itself (I know this isn't advisable). I have tried increasing the delay significantly and have found that a 400ms delay causes most presses (About 90%) to act debounced. Unfortunately this causes the system to lag, and it seems unreasonable for any button to need a delay this long for debouncing. If anyone has any thoughts please let me know as I am getting very frustrated with this and am about to just implement a hardware solution since software doesn't seem to be working. |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
Re: Debouncing |
Posted: Wed Oct 26, 2005 7:09 pm |
|
|
Bryan wrote: | I am having a terrible time with getting my debounce routines to work for several interrupt driven buttons. |
Since your button is connected to the interrupt, you should debounce the button in hardware. This thread gives some solutions for h/w debouncing. http://www.ccsinfo.com/forum/viewtopic.php?t=24103
Bryan wrote: | Does the PIC queue interrupts that occur on the same port and then execute them in order? |
No, PIC doesn't que interrupts. PIC doesn't nest interrupts either. If you get an interrupt, and the same interrupt occurs befor ethe first one is serviced (i.e. the ISR returns), the second interrupt is ignored. Sad but true.
By the way, I'm entertaining an idea of making an interrupt controller with a queue out of a CPLD and interfacing it to a PIC via I2C or SPI. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Oct 26, 2005 7:25 pm |
|
|
Quote: | If you get an interrupt, and the same interrupt occurs befor ethe first one is serviced (i.e. the ISR returns), the second interrupt is ignored. |
Couldn't you, or shouldn't you, put the delay in the ISR to actually debounce the switch? I understand that that isn't a recommended technique, but a delay outside the ISR really doesn't do anything except add a bunch of delays to the switch bounce?
BTW. I have had very good success with Newguy's interrupt driven keypad code from the code library used along with tactile switches.... His code uses delays outside the ISR which contradicts what I said above...
An expert explanation would be greatly appreciated,
John |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Wed Oct 26, 2005 7:34 pm |
|
|
jecottrell wrote: | Couldn't you, or shouldn't you, put the delay in the ISR to actually debounce the switch? |
That will work for a simple case, but:
1. An interrupt with an equal priority can be missed.
2. The timing of your main() will be all over the place. It's detrimental if main() is running a control loop without a timer. And even if the control loop is runing on a timer interrupt, the timer interrupt can be missed (see 1.). |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Oct 26, 2005 8:26 pm |
|
|
Unless you are waking from sleep, why even bother using an interrupt to detect button presses? I have yet needed to do this. I simply have a task that runs every so often checking for button presses. If you check the code library, you will find some routines that I wrote for another user. These are way more complicated than just detecting button presses but it might be worth looking at
http://www.ccsinfo.com/forum/viewtopic.php?t=22145 |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
|
amcfall
Joined: 20 Oct 2005 Posts: 44
|
|
Posted: Thu Oct 27, 2005 9:11 am |
|
|
What I did was have an adjustable debounce delay (it's a feature!). After however many ms pass and the value is met it clears then enables the interrupt.
Avery |
|
|
|