Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] How to debounce multiple switch individually

Status
Not open for further replies.

khaled01819

Newbie level 6
Newbie level 6
Joined
May 27, 2010
Messages
11
Helped
2
Reputation
4
Reaction score
1
Trophy points
1,283
Location
bangladesh
Visit site
Activity points
1,370
How to debounce multiple switch individually. I am newbie for this site. I m using PIC 16F688 mcu and micro-c for this job. I have collect a code but this code works only single switch. plz see the attachment isis and c-code.
 

Attachments

  • Debounce.rar
    12.8 KB · Views: 132

You can add a capacitor in parallel to the switch but it's a very novice solution.

What is done is to stop reading the pin once it gets activated. The program to debounce is really easy, all it has to do is keep reading the pin connected to your switch/button. Once it detects a change it must not read that pin for the next 20ms. Obviously that delay depends of the switch characteristics, I think manufacturers give information about mechanical bounce in their datasheets. If not you keep trying till you don't get any annoying bounce.

To achieve that you could use a global variable, even just 1 bit of it. For instance, when it's a logic 1 you enable the pin to be readed (that bit could be part of a binary mask or something) and the opposite in case of being 0. Once you detect a change in the pin state, manually change that global variable I mentioned before to 0 and start a counter which will count 20ms (or any delay you wanted) and call (after that) an interruption to put that global variable in its original state (say 1).

That will disable the pin lecture for a time while it is going to bounce.

Just ask again if you have any doubt, I hope being useful.
 

Four ways to debounce switch


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//Type 1
 
//If button is pressed do something
 
//If button is pressed the input pin of the button goes high
 
if(RB0) {   //if button pressed
   Delay_ms(200);
   if(RB0) {    //if button still pressed
 
    //Turn ON LED       
   } 
}
 
//Type 2
 
//If button is pressed and released then do something
 
//If button is pressed the input pin of the button goes high
 
if(RB0) {
   Delay_ms(200);
   while(RB0);              //wait till button is released
 
    //Turn ON LED
}
 
 
//Type 3
 
//If button is pressed do something
 
//If button is pressed the input pin of the button goes low
 
 
if(!RB0) {  //if button pressed
   Delay_ms(200);
   if(!RB0) {   //if button still pressed
 
    //Turn ON LED       
   } 
}
 
//Type 2
 
//If button is pressed and released then do something
 
//If button is pressed the input pin of the button goes high
 
if(!RB0) {
   Delay_ms(200);
   while(!RB0);         //wait till button is released
 
    //Turn ON LED
}






For your circuit


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//button pressed
 
if((PORTA & 0x03) == 0x01) {
    Delay_ms(200);
    if((PORTA & 0x03) == 0x01) {
        //do something
    }
}
 
if((PORTA & 0x03) == 0x02) {
    Delay_ms(200);
    if((PORTA & 0x03) == 0x02) {
        //do something
    }
}
 
//button pressed and released
 
if((PORTA & 0x03) == 0x01) {
    Delay_ms(200);
    while(PORTA & 0x03);
        //do something  
}
 
if((PORTA & 0x03) == 0x02) {
    Delay_ms(200);
    if(PORTA & 0x03);
        //do something  
}

 
Last edited:

Hello!

Indeed, using a loop is the worst possible method. The reason explained above
is that it freezes the program. But there is another reason:
If an edge is detected, it means that the button has been pressed. Whatever the
duration. If you use a delay loop as above, and if you get a 100 ms pulse from a
button:
- You detect that the button has been pressed
- You set a delay
- The button is released before the end of the delay
- The delay expires, and since the button is not pressed anymore,
you conclude that the button was not pressed. But it was pressed.

What I usually do:
- Detect an edge at a given button;
- At that point, there are 3 actions:
* Fire a timer
* Disable interrupts for that given button
* Process the actions that should be caused by the button

- When the timer expires, get a timer interruption, and in the timer interruption
routine, re-enable the interruptions for the button you just disabled.

With this method
- You will never miss one button except if you type faster than the timer
- You will never have a rebound except if your timer is really too short.
- As you don't use a wait loop, you can use the processor for real work.

Dora.


Dora
 

Looping and incrementing a counter doesn't freeze program execution ?

No

if you have a function main like this
Code:
  main()
   {
      if (input == 0) {
          if (integrator > 0)
             integrator--;
         }
       else if (integrator < MAXIMUM)
          integrator++;

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

    //   place here your code (with no freeze of course !!)
       ....

     }
 

just make your logic like this

if(RB0==1)
{
if(count==1){ count=0; switch_done=1;}
}
else count=1;

here count and switch_done are the variables.........
 

I normally use an interrupt timer to set a tick every 10ms. You execute the supervise routine in the background program, and read your input status for all inputs one time every tick into a 3 sample buffer. Comparing with AND, OR and XOR you then make out which of your inputs are stable, and check for a new status. You then process the corresponding event routine for the activated/ deactivated input. This way you will have a debounce time of around 20-30ms, both for activation and deactivation.

This makes it simple to add things like autorepeat and key click.
 

Don't use a loop delay (the core just loop doing anything useful, just looping). Most modern MCUs have internal timer modules that can be easily programmed. If you don't know how just search in the forum or internet, it's full of information.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top