1

I interfaced a keypad to stm32f429i board and am able to display respective button of keypad on LCD screen of board. Short press is working fine but I have no idea how to implement long press key event. Can someone please help me?

SubbaReddy
  • 11
  • 1
  • 4

3 Answers3

3

Edit: As suggested by PeterJ_01, using a Timer interrupt is the most elegant way. Do not use the GPIO interrupt for buttons!

If you are using the Hardware Abstraction Layer (HAL) Library, you can do something like this inside your GPIO interrupt:

static int timestamp_pressed = -1;  // -1 means not pressed

if (timestamp_pressed == -1) {
    // user just pressed the button
    timestamp_pressed = HAL_GetTick();  // milliseconds since startup
} else if (HAL_GetTick() - timestamp_pressed > 2000) {
    // 2000 milliseconds = 2 seconds are over
    // << your code

    timestamp_pressed = -1;
}

If you are not using HAL and don't want to use a regular timer interrupt (from TIM1, TIM2, TIM3, ...) you can consider using the SysTick timer (with an interrupt or without). There is plenty information about it in the internet ;)

MemAllox
  • 533
  • 5
  • 22
  • 1
    using EXTI interrupts for the buttons is the huge mistake and should be avoided. – 0___________ Dec 23 '17 at 22:09
  • Why is that so? Because of contact bounce? (If so, couldn't that be resolved in a similar way as I proposed - or is that considered bad style?) – MemAllox Dec 23 '17 at 22:15
  • because you need to block the program execution in the interrupt for the time of the debouncing. Timer interrupts should be used for it. – 0___________ Dec 23 '17 at 22:32
  • I agree that blocking the program in the interrupt is a terrible thing to do. However, if you look at the code i suggested, wouldn't that be fine? – MemAllox Dec 24 '17 at 08:45
  • Ooh i see. The contact bounce would practically block the program because of the multiple interrupts. If your interrupt routine is actively waiting doesn't matter. Thanks! – MemAllox Dec 24 '17 at 09:03
  • Your code is not obvious could you please explain a little? – mohammadsdtmnd Feb 05 '22 at 09:25
0

Yes - you need to use the timer interrupt. Here is the link and the library:

https://www.diymat.co.uk/arm-three-function-click-double-and-long-click-button-library-timer-interrupt-driven/

0___________
  • 60,014
  • 4
  • 34
  • 74
0

An implementation inspired from STM32F746G discovery board example.

if(HAL_GPIO_ReadPin(Push_GPIO_Port,Push_Pin) != RESET)
  {

      HAL_Delay(10);//debounce
      timestamp_butpressed = HAL_GetTick();
      while (HAL_GPIO_ReadPin(Push_GPIO_Port,Push_Pin) != RESET);
      timestamp_butreleased = HAL_GetTick();

      //Is button pressed enouph to run the program?
      if(timestamp_butreleased>timestamp_butpressed?//This condition prevent max value to cause problem
              ((timestamp_butreleased-timestamp_butpressed)>2000)://normal condition
              ((4294967295-timestamp_butpressed)+timestamp_butreleased)>2000)//glitchy conditioin handle
      {
          //application runs here or flag handling heppens here
      }

  }

Another triky implementation (long press triggers as it reaches required time):

if(HAL_GPIO_ReadPin(Push_GPIO_Port,Push_Pin) != RESET)
{
 HAL_Delay(10);
 while(HAL_GPIO_ReadPin(Push_GPIO_Port,Push_Pin) == RESET)
 {
   HAL_Delay(5);
   i++
   if(i==100)break;
 }
 if(i<100)
 {
 short pressed
 }
 else
 {
 long pressed
 }
}

A functional implementation:

uint8_t pushbot(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{

    if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) != RESET)
      {
            uint32_t timestamp_butpressed=0;
            uint32_t timestamp_butreleased=0;
          HAL_Delay(10);//debounce
          timestamp_butpressed = HAL_GetTick();
          while (HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) != RESET);
          timestamp_butreleased = HAL_GetTick();

          //Is button pressed enouph to run the program?
          if(timestamp_butreleased>timestamp_butpressed?//This condition prevent max value to cause problem
                  ((timestamp_butreleased-timestamp_butpressed)>1000)://normal condition
                  ((4294967295-timestamp_butpressed)+timestamp_butreleased)>1000)//glitchy conditioin handle
              {
              return 2;// long pressed
              }
          else
          {
              return 1;// short pressed
          }
      }
    else
    {
        return 0;// not pressed
    }

}
mohammadsdtmnd
  • 330
  • 1
  • 11