How can I implement Long press and Short press ? Long press should be 3 seconds long

326 views Asked by At

I am working on STM32F407VG development board. I need to design a product by using that processor. My application includes SHORT PRESS and LONG PRESS functionality. I have implemented the Logic. But I don't know what is the issue.

I have used on board User Push button. I have used timer 6 and it generates interrupt after every 20mS. Can someone review the code and tell me about the problem. I know I haven't added the debouncing. That also need to be added.

Currently When I press the button then my executes but it only goes in first if condition which is short press it doesn't handle the long press.

volatile uint32_t buttonPressTime = 0;
volatile uint8_t buttonPressed = 0;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM6_Init(void);

#define SHORT_PRESS_THRESHOLD 50 // For example, 50 milliseconds
#define LONG_PRESS_THRESHOLD 3000 // 3 seconds

int main(void)
{
  
  HAL_Init();

 
  SystemClock_Config();

  /
  MX_GPIO_Init();
  MX_TIM6_Init();
 
  HAL_TIM_Base_Start_IT(&htim6); // Start Timer 6 with interrupts enabled
  

  
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      if (buttonPressed) {
                  if (buttonPressTime < SHORT_PRESS_THRESHOLD) {
                      // Handle short press
                      printf("Short Press");
                  } else if (buttonPressTime >= LONG_PRESS_THRESHOLD)
                  {
                      // Handle long press
                      printf("Long presss");
                  }
                  buttonPressed = 0; // Reset flag
              }
  }
 
}

Tim6 initialization

static void MX_TIM6_Init(void)
{

  

  TIM_MasterConfigTypeDef sMasterConfig = {0};

  
  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 55;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 59999;
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }

}

Call back Function is as follows

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM6)
    {
        if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
        {
            buttonPressTime++; // Increment button press time
        }
        else
        {
            if (buttonPressTime > 0)
            {
                buttonPressed = 1; // Set button pressed flag
            }
            buttonPressTime = 0; // Reset button press time
        }
    }
}

My design application is basically to control the Brightness on single press and turn on/off the display using long press button. The long press duration should be around 2-3 seconds. Currently My code is just a basic code. I will add the functionalities later. When this part of project starts working correctly.

1

There are 1 answers

1
MrSmith42 On

For me it looks like you always set buttonPressTime=0 whenever you set buttonPressed = 1

So when you test if (buttonPressed) the buttonPressTime is always 0.

I would try somethink like:

 /* USER CODE BEGIN WHILE */
 while (1){ 
      if (buttonPressed) {
              if (buttonPressTime < SHORT_PRESS_THRESHOLD) {
                  // Handle short press
                  printf("Short Press");
              } 
              else if (buttonPressTime >= LONG_PRESS_THRESHOLD) {
                  // Handle long press
                  printf("Long presss");
              }
              buttonPressed = 0; // Reset flag
              buttonPressTime = 0; // Reset button press time
       }
 }

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
    if (htim->Instance == TIM6){
        if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){
            buttonPressTime++; // Increment button press time
        }
        else{
            if (buttonPressTime > 0){
                buttonPressed = 1; // Set button pressed flag
            }
            //buttonPressTime = 0; // Reset button press time here leads to always buttonPressTime==0
        }
    }
}