This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

I'd like to make a button double-click feature.

Hello

I am making a button double-click function in sdk v17.
I've tried 'app_button' and 'app_timer'. Created a timer that is called every 0.1 seconds and terminates when 5 calls(0.5sec).
This timer is to wait for the next button after pressing the button.

When the button is released, the timer is started, and when the button is pressed while the timer is running, it is recognized as a double click.

I don't think this method itself is bad. (Maybe...?)

But contrary to my expectations, it works strangely.  When App_button_release is called, the timer runs and it ends in 0.5 seconds. But it ends, and it runs again. And if I double-click, everything stops.

#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include "nordic_common.h"
#include "nrf.h"
#include "ble_hci.h"
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "ble_conn_params.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#include "nrf_sdh_ble.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_lesc.h" 
#include "nrf_ble_qwr.h"
#include "app_timer.h"
#include "ble_nus.h"
#include "app_uart.h"
#include "app_util_platform.h"
#include "bsp_btn_ble.h"
#include "nrf_pwr_mgmt.h"

#if defined (UART_PRESENT)
#include "nrf_uart.h"
#endif
#if defined (UARTE_PRESENT)
#include "nrf_uarte.h"
#endif

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

//==========================================================

//add include
#include "app_button.h" 
#include "nrf_delay.h" 
#include "peer_manager.h" 
#include "peer_manager_handler.h" 
#include "fds.h" 
#include "nrf_drv_twi.h"
#include "app_error.h"
#include "bsp.h" 
#include "app_pwm.h" 

#include "nrf_drv_saadc.h" //ADC
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"


APP_TIMER_DEF(m_DoubleClick_timer_id); //double click check, repeate timer


void gpio_init(void)
{
  nrf_gpio_cfg_output(BSP_LED_0); //board_led1
  nrf_gpio_pin_set(BSP_LED_0);

  nrf_gpio_cfg_output(BSP_LED_1); //board_led2
  nrf_gpio_pin_set(BSP_LED_1);

  nrf_gpio_cfg_output(BSP_LED_2); //board_led3
  nrf_gpio_pin_set(BSP_LED_2);

  nrf_gpio_cfg_output(BSP_LED_3); //board_led4
  nrf_gpio_pin_set(BSP_LED_3);

  nrf_gpio_cfg_input(BUTTON_1,NRF_GPIO_PIN_PULLUP);
}


uint32_t click_check;
bool double_click = false; //check button push/released

static void DoubleClick_timer_handler(void * p_context)
{
  click_check++; //100msc

  printf("%d\n", click_check);

  if(click_check == 5) //timer stop after 0.5sec
  {
    click_check = 0;
    DoubleClick_timers_stop(); 
  }
}


static void timers_init(void)
{
    ret_code_t err_code;

    // Initialize timer module.
    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

   //Create Press Time timers/
    err_code = app_timer_create(&m_DoubleClick_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                DoubleClick_timer_handler);
    APP_ERROR_CHECK(err_code);
}


static void DoubleClick_timers_start()
{
  ret_code_t err_code;

  double_click = true;
  err_code = app_timer_start(m_DoubleClick_timer_id, APP_TIMER_TICKS(100), NULL); //count 0.1sec
  APP_ERROR_CHECK(err_code);
}


static void DoubleClick_timers_stop()
{
    ret_code_t err_code;

    printf("end double click time\n");
    double_click = false;

    err_code = app_timer_stop(m_LongPress_timer_id); 
    APP_ERROR_CHECK(err_code); 
}


static void app_button_event_handler(uint8_t pin_no, uint8_t button_action)
{
    ret_code_t err_code;
    static uint32_t first_pressed;
    static uint32_t long_pressed;

    switch (pin_no)
    {
      case BUTTON_1: //button1
        switch (button_action)
        {
          case APP_BUTTON_PUSH:
          {
            NRF_LOG_INFO("Button pressed...");
            printf("Button pressed...");
            nrf_gpio_pin_clear(BSP_LED_2); //led on
            //pwm_change_frequency(1500);
            //do_play_buzzer();

            if(double_click == true) //if button release
            {
              printf("double click!\n");
            }

            //get pressed time
            pressed_time = app_timer_cnt_get()*1000/32768;//milli-sec
            NRF_LOG_INFO("pressed_time: %d", (int)pressed_time);
            printf("pressed_time: %d\n", (int)pressed_time);
            pressed_cnt = true;

            LongPress_timers_start(); //press time count

          } break;

           case APP_BUTTON_RELEASE:
           {  
              NRF_LOG_INFO("Button releaed...");
              nrf_gpio_pin_set(BSP_LED_2); //led off
              DoubleClick_timers_start();

              //nrf_gpio_pin_set(LED_2);
              if (pressed_cnt)
              {
                released_time = app_timer_cnt_get()*1000/32768; //milli-sec
                NRF_LOG_INFO("released_time: %d", (int)released_time);
                printf("released_time: %d\n", (int)released_time);
              }

              pressed_cnt = false;

              LongPress_timers_stop();
                
           } break;
        } 
      break;

      default:
         APP_ERROR_HANDLER(pin_no);
      break;
    }
}


static void app_buttons_init(void)
{
  uint32_t err_code;

  static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] =
  {
    #ifdef BUTTON_1 //button1
    {BUTTON_1, false, BUTTON_PULL, app_button_event_handler},
    #endif // BUTTON_0
  };

  err_code = app_button_init((app_button_cfg_t *)app_buttons,
                                       BUTTONS_NUMBER,        // 1
                                       APP_TIMER_TICKS(50)); //debounce
  APP_ERROR_CHECK(err_code);
}

Can I get some advice or reference about double-clicking a button?

Thank you!

Parents Reply Children
No Data
Related