2 push buttons instead of one

Discussion in 'Embedded Systems and Microcontrollers' started by dayv3, Dec 4, 2015.

  1. dayv3

    Thread Starter Member

    May 22, 2014
    31
    0
    Hi all,

    Awhile ago I wrote/ built an interrupt driven push button de-bouncing circuit with a 12F683. But now, I want to be able to de-bounce 2 push buttons instead of one, each one acting separately. What is the best way to approach this problem? Do I use separate PICs for each button or is it better to have 2 interrupt routines running simultaneously? I am looking for someone to help point me in the correct direction.

    Dave
     
  2. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,395
    497
    In Intel 8051 interrupts have priority. So even if you trigger both interrupts, one of them will have higher priority then the other and will be executed first.

    Is PIC setup the same way?

    The debouncing routine should be the same for both buttons.
     
  3. dayv3

    Thread Starter Member

    May 22, 2014
    31
    0
    I do not know

    For my application, toggling a relay, I do not think it matters that much, but you ask a good question
    that I need to know the answer to for future projects. I will look for an answer to your question and on
    how to use 2 ISR's
    Thanks
     
  4. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    12Fxxx is single priority interrupts.A good way to debounce is to use a timer interrupt that peridocally samples the inputs and uses the timer period over several interrupts to do the debouncing. Post flags that indicate the status of the switches.
    Search the forums for debounce and you will get lots of examples.
     
  5. dayv3

    Thread Starter Member

    May 22, 2014
    31
    0
    @JohnInTX I already have a good interrupt routine that you helped me with some time ago.
    What do you mean by single priority?

    But I have never ran two ISR's at the same time so I will need to teach myself how to do that.
    Does a anyone know where there is a good example of a PIC being run with multiple ISR's
    that I can study? ( In C)

    Dave
     
  6. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    Your current interrupt routine should read the value of the pin. Do it the same way as one except expand your code to read the second pin.

    It would have really helped if you included your code.
     
  7. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    There is no need to see the existing code because it is based on a poor method of reading buttons. Why poor? Because it struggles to handle multiple pins.

    Instead of an interrupt for each pin thing of one interrupt to start a button check. If even multiple buttons are stable (pressed or not pressed) over several readings then they can be marked as changed and denounced.

    When I do this I have found readings every 25 ms to be good; two readings that agree will mark stable buttons. Note the time may need be longer for buttons that bounce more. I findvthis interval intercept able for the human pressing the button.

    This method also gives you a way to get a system heartbeat which is quite useful when you need to time something.
     
  8. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016

    You are recommending polling rather than instead of using interrupts for the switches? Yeah I was going to mention that.

    What I would like to see is some good debounce code written in C. I think others would find it useful so please share. I have some I use that I wrote years ago and I sort of use the method you mentioned, seems to work put I am not positive the code is flawless.
     
  9. dayv3

    Thread Starter Member

    May 22, 2014
    31
    0
    For the C code that I wrote/ use look up "12F683 ISR switch debounce", I always document my code well.
    I looked on the web and found a few references to using multiple interrupts but I have not yet
    found a really clean picture. If anyone has or knows of a good example of using multiple interrupts I
    would appreciate it if you would point me to it.
     
  10. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    I could have been more clear on that - sorry, typing on a tablet.
    Single priority (and single interrupt vector) means that there is only one interrupt / service routine. You can process more than one interrupt in the system but they all share resources and if you in the process of servicing one interrupt, any others that may occur during that time have to wait, regardless of how much more important they may be. That is why experienced PIC programmers will tell you to always keep your interrupt routines as short as possible and never do delays inside the ISR.

    I do my debouncing logic a little different than ErnieM but we both use a single timer interrupt to schedule sampling of the switch(es).
     
  11. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    Why do you think you need to use interrupts? Just use polling instead.

    But if you insist on interrupts.

    I stand corrected on my post above above for those chips that support multiple external interrupts. That is the problem with not checking datasheets. :) It is more complicated than just reading the values. You need to enable the interrupts for those other pins and implement the additional interrupt code.


    But I think that is not going to apply for you anyway.

    I am not familiar with the 12 family of Pics but I have checked the datasheet. Have you done the same? From what I am reading, only GP2 has an external interrupt. So you will either need to poll or move to another Pic. Or hopefully someone will correct me on one external interrupt.
     
  12. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    I think the 12F683 only has one external interrupt on GP2 anyway. Can you confirm?
     
  13. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    Looks like all of the pins are interrupt on change. But only GP0 has external interrupt.
     
  14. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    As @spinnaker says. But I would not use interrupt on change for debouncing. It gets ugly fast IMO.
     
  15. dayv3

    Thread Starter Member

    May 22, 2014
    31
    0
    That is what I thought you meant. but if I remember correctly once the interrupt routine is entered the processor saves the stack so no events will be lost, just delayed. Which is fine for my application.

    I need to do a little more research on how to do multiple interrupts, but if anyone has a clean example in C I would greatly appreciate it.
     
  16. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    Hello again, Dave. Hope you and family are well and enjoying the beginning of this Holiday season.

    There are a couple example code snippets at Debouncing a switch in software using a PIC16F72 that use parallel switch state logic to filter out all but the "new press" state for multiple switches. One of the examples simply samples the switches at some prescribed 'debounce' interval while one of the other examples includes a low pass filter, like you're using now, using a 2-bit vertical counter. Basically, it's a way to run up to eight independent 24-msec counters in parallel. Not the easiest code to understand, however, recently Forum member Joey999 reminded me of a method I came across on the Microchip Forum which may be a little easier to understand. Both low pass filter methods rely on sampling a switch at the same state four times in a 24-millisecond span before toggling the debounced switch state latch for any particular switch. All of the routines debounce both the "press" and "release" states and pass along "new press" flags for your main program.

    Don't be afraid to ask questions...

    Cheerful regards, Mike

    Code (Text):
    1. ;
    2. ;  sample switches at 8-msec intervals.  debounce both 'press' and 'release'
    3. ;  states by sampling them four times at the same state spanning 24-msecs.
    4. ;
    5.    void interrupt()             //
    6.    { TMR2IF = 0;                // clear TMR2 interrupt flag
    7.      delta[3] = delta[2];       // shift delta accumulator
    8.      delta[2] = delta[1];       //  "
    9.      delta[1] = delta[0];       //  "
    10.      swnew = ~GPIO;             // sample active lo switches
    11.      swnew &= 0b00001001;       // on GP3 & GP0 pins only
    12.      swnew ^= swold;            // changes, press or release
    13.      delta[0] = swnew;          // add sample to accumulator
    14.      swnew &= delta[1];         // check debounce 'time-out'
    15.      swnew &= delta[2];         //  "
    16.      swnew &= delta[3];         //  "
    17.      swold ^= swnew;            // update switch state latch
    18.      swnew &= swold;            // filter out 'release' bits
    19.      flags |= swnew;            // save 'new press' flags
    20.    }                            //
    21.  
    Code (Text):
    1. ;
    2. ;  vertical counter example
    3. ;
    4. ;  sample switches at 8-msec intervals.  debounce both 'press' and 'release'
    5. ;  states by sampling them four times at the same state spanning 24-msecs.
    6. ;
    7.    void interrupt()             //
    8.    { TMR2IF = 0;                // clear TMR2 interrupt flag
    9.      delta = ~GPIO;             // sample active lo switches
    10.      delta &= 0b00001001;       // on GP3 & GP0 pins only
    11.      delta ^= latch;            // changes, press or release
    12.      vcnt0 &= delta;            // clear stable or bouncing counters
    13.      vcnt1 &= delta;            //  "
    14.      vcnt0 = ~vcnt0;            // increment counters
    15.      vcnt1 ^= vcnt0;            //  "
    16.      delta &= vcnt0;            // collect counter overflows
    17.      delta &= vcnt1;            //  "
    18.      latch ^= delta;            // update switch state latch
    19.      delta &= latch;            // filter out 'release' bits
    20.      flags |= delta;            // save 'new press' flags
    21.    }                            //
    22.  
     
    Last edited: Dec 5, 2015
  17. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016

    You cannot do external interrupts with more than one switch on that Pic. Why don't you post you existing code so this all becomes more clear? Help others to help you.
     
  18. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    Nonsense! You can use IOC (Interrupt On Change) for all six I/O pins on the 12F683.
     
  19. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    I said external interrupt not IOC. IOC capability mentioned in post #13. Since the OP has not posted his code no way to know what he is doing.
     
    Last edited: Dec 5, 2015
  20. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    And I am trusting John's knowledge of IOC that this is not the best way to go in this application. Post 14.
     
Loading...