Pulse interrupt debounce handling

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I have a atsamv71q21 board and I am writing a code to count a pulses of 2ms , I taken a one PIN and assigned to handle a interrupt , but when I generating pulses , my interrupt handler not counting properly because of debouncing , So my question is how to handle the debouncing of interrupt.

 

Thank you.  

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you sure the signal is bouncing?  Have you put a scope on the pin and verified?  What type of signal are you monitoring at a 2ms period?  An encoder perhaps?  How long is the signal bouncing relative to the 2ms period?  100us or so?  This matters for implementation details.

 

If the bouncing period is very short, say a few 10's of microseconds, one option is to delay inside the ISR before proceeding.  Careful here as this is generally bad practice.  ISR's are meant to happen asynchronously to the application, and execute as quickly as possible.  Delay's inside an ISR are frowned upon.

 

Another option is to have the ISR set a flag notifying the main application and disabling itself (only its own interrupt).  Even better it saves the main system timer counter value at that moment provided the timer is much faster than 1ms.  The main application polls the flag, see it is set, does the real work, and reenables interrupts for the next pulse.  Careful here if the main application is busy doing too much as it might not service the pulse in time, causing lost pulses.

 

Or cascade interrupts.  The first edge happens, it's ISR disables itself but starts a timer.  The timer expires and generates another interrupt.  That timer interrupt does the work and reenables the first interrupt for the next pulse.

 

Or smooth the signal via hardware before the processor sees it, perhaps sending it through a schmidt trigger or opto-isolators with the proper pullups, perhaps even an RC.

 

Or smooth the signal is software.  Is there a high resolution timer available?  Capture its value at each interrupt and save it for the next one.  Calculate the delta time from this interrupt and the prior interrupt.  If the delta time is too small, ignore the glitch.

 

Or check out the built in glitch filters on the SAM V71 GPIO.  This might be your best solution provided the glitches are pretty fast compared to the pulses you want to service.

 

Did I ask if you have measured the glitches with an oscilloscope yet? :)

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your responce.

As to told I put a scope on the pin to check the signal is bouncing or not actually it is not bouncing. 

Actually setup to generate a pulse is , I taken a GPIO as a interrupt with internal pull-up is on and I touching that pin to ground to generate pulse and that pulses I am trying to calculate. When touch a pin to ground once it is counting more than one.

To display the count I am using one switch.

 

Following is the my code:

 

#include <atmel_start.h>
#include <stdio.h>
#include <string.h>

uint8_t count = 0;
unsigned char buffer[5];
uint8_t Send_Flag = 0;
uint8_t status = 0;
uint8_t debounce = 0,pulse_count =0;
struct io_descriptor *dsc;

 

uint8_t pulse = 0;
uint8_t pulse1 = 0;

static pulse_counting(void)

{
    count++;
}

 

void EXTERNAL_IRQ_0_example1(void)

{

        ext_irq_register(PA2,pulse_counting);
        ext_irq_register(PA6,printing);
}

 

 

int main(void)
{
        
/* Initializes MCU, drivers and middleware */
        atmel_start_init();

        usart_sync_get_io_descriptor(&USART_0,&dsc);

        usart_sync_enable(&USART_0);

        ext_irq_init();

        ext_irq_enable(PA2);

        ext_irq_enable(PA6);io_write(dsc,(uint8_t *)"\n\r****OPENCOLLECTOR****\n\r",23);
        /* Replace with your application code */

        while (1) 
        {
            EXTERNAL_IRQ_0_example1();
        
                    if(gpio_get_pin_level(GPIO1) == 0)
                     {
                         // Bouncing has started so increment BTN_press with 1, for each "high" bounce
                         BTN_press++;

                         // "reset" BTN_release

                         BTN_release = 0;

                         // If it bounces so much that BTN_press is greater than Bouncevalue

                         // then button must be pressed

                         if (BTN_press > Bouncevalue)

                         { // This is initial value of BTN_pressed.
                             // If program gets here, button must be pressed

                             if (BTN_pressed == 0)
                             {
                                    count++;
                                 // Setting BTN_pressed to 1, ensuring that we will
                                 // not enter this code block again
                                 BTN_pressed = 1;
                             }
                             // LEDs toggled, set BTN_pressed to 0, so we can enter
                             // toggle code block again
                             BTN_press = 0;
                         }
                     }
                     else{
                         // Increment the "low" in the bouncing
                         BTN_release++;
                         BTN_press = 0;
                         // If BTN_release is greater than Bouncevalue, we do not have a
                         // pressed button
                         if (BTN_release > Bouncevalue)
                         {
                             BTN_pressed = 0;
                             BTN_release = 0;
                         }
                     }