ANYEDGE interrupt skipping reads from tact switch input?

MikeLemon
Posts: 45
Joined: Tue Feb 02, 2021 5:55 pm

ANYEDGE interrupt skipping reads from tact switch input?

Postby MikeLemon » Sat Jan 08, 2022 5:18 pm

I've got this unexpectted behavior of a pin anyedge interrupt I setup for button state reading and debauncing and there are times when I press the button and release in a certain way that the button bounces or something and instead of getting state reading as follows:

1
0
1
0
(Just as expected in ANYEDGE INTERRUP)

I instead get sometimes 2 call one after another of the same state like

0
1
0
1
1
1
0
0
0

I was wondering wether it is to be expected and if it is, how programmers usually handle that?

Here's the used code of the library I build the state processing is handles by freeRTOS

Button.c:

Code: Select all

#include "button.h"
#include "stdio.h"

#include "driver/gpio.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

#include "esp_err.h"

#include "esp_timer.h"


xQueueHandle btnQueue;

// // Dont printf() from ISR !!!!!!!!!!!!!

static void IRAM_ATTR buttonISR(void *args){

  int pinNumer = (int) args;
  xQueueSendFromISR(btnQueue, &pinNumer, NULL);

}

void btnTask(void (*myFunc)()){

  int pinNumber, count = 0;

  long DBT = 0;

  while (true)
  {
    
    if(xQueueReceive(btnQueue, &pinNumber, portMAX_DELAY)){

      // Disable Button Interupt
      // gpio_isr_handler_remove(pinNumber);
      printf("State change: %d \n", gpio_get_level(pinNumber));
      // Wait to avoid initial spikes

      vTaskDelay(20/ portTICK_PERIOD_MS);

      if(gpio_get_level(pinNumber)){
        
        long CurrTime = 0;
        CurrTime = (esp_timer_get_time()/1000);

        // printf("Now High, Time diff = %lld\n", (esp_timer_get_time()/1000));
        if((CurrTime - DBT) > 300){

           printf("Button %d was pressed %d times The state is %d\n", pinNumber, count++, gpio_get_level(pinNumber));
        }
      }
      else{DBT = (esp_timer_get_time()/1000);}

      // Do work
      // myFunc();

      // ReEnable Interupt 
      // gpio_isr_handler_add(pinNumber, buttonISR, (void *)pinNumber);
    }

  }

}


uint8_t initButton(btn_params_t *BtnParams, void (*BtnPressedISR)()){

  // Initialize input pin 
  gpio_config_t BtnConfig;

//   BtnParams->BtnActiveState;

  BtnConfig.intr_type = GPIO_INTR_ANYEDGE;
  BtnConfig.mode = GPIO_MODE_INPUT;
  BtnConfig.pull_down_en = 0;
  BtnConfig.pull_up_en = 1;
  BtnConfig.pin_bit_mask = (1ULL << BtnParams->BtnPin);

  gpio_config(&BtnConfig);


  // Init ISR

  gpio_install_isr_service(0);
  gpio_isr_handler_add(BtnParams->BtnPin, buttonISR, (void *)BtnParams->BtnPin);

  // Create queue to communicate between buttonISR and task
  btnQueue = xQueueCreate(10, sizeof(int));
  // Create the button task ( what to do when button is pressed)
  xTaskCreate(btnTask, "TriggeredBtn", 2048, (void *)BtnPressedISR, 1, NULL);


  return(1);
}

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: ANYEDGE interrupt skipping reads from tact switch input?

Postby ESP_Sprite » Sun Jan 09, 2022 2:52 am

The pin likely changed back to the old value before your interrupt was fully processed.

MikeLemon
Posts: 45
Joined: Tue Feb 02, 2021 5:55 pm

Re: ANYEDGE interrupt skipping reads from tact switch input?

Postby MikeLemon » Sun Jan 09, 2022 9:21 am

So, its fine?
How do you usually handle that situation?

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: ANYEDGE interrupt skipping reads from tact switch input?

Postby ESP_Sprite » Sun Jan 09, 2022 9:38 am

Probably. And personally, I generally don't have an interrupt on my switches; I simply poll them in my main loop or some other thread that has a loop that can check them once every 100 ms or so.


Who is online

Users browsing this forum: No registered users and 88 guests