cancel
Showing results for 
Search instead for 
Did you mean: 

Most elegant way to Detect button press and switch actions with STM32L4 MCU

Manojkumar Subramaniam
Associate II

I have a need where, to execute certain action depending on duration of button press.

Example when press from 100ms : Play Song, 200ms : Next Song.

I want to know what is the smartest way to implement this so that the user experience is good in the context it's consistent throughout the program ?

The circuit connecting button to the IO is using a pull up 10k resistor so it also means i would need some debouching as well. The mcu is STM32L4 a

7 REPLIES 7
AvaTar
Lead

An EXTI interrupt for the GPIO pin, on both transitions (LH and HL).

> Example when press from 100ms : Play Song, 200ms : Next Song.

You will need larger distances, 100ms vs. 200ms is almost impossible to manage.

Say, below 100ms, 500ms, 1000ms.

Debouncing depends on mechanical properties of the switch button, 20 to 30ms are usually o.k.

Didn't work with the L4 yet, shouldn't be much different from the F4.

Manojkumar Subramaniam
Associate II

Hi @Community member​  I avoided the interrupt option as there will be some debouching effect on the button signal... filtering it inside a ISR good idea and any idea how to do it ?

AvaTar
Lead

Using interrupts to detect transitions doesn't mean you need to debounce it in the handler.

I used to set a flag, and check it periodically in the main loop.

Debouncing means you accept only one transition in your debounce time.

Since I used to ignore CubeMX (and continue) to do so, I tend to use the SysTick for that periodical loop.

About 10ms might be a good period, you don't need higher granularity for push button debounce.

Manojkumar Subramaniam
Associate II

can give a sample code.. i think i will understand better

Rob.Riggs
Senior

Reset a counter when the button down event is detected. Disable the interrupt for the debounce period then verify that the button is still pressed immediately prior to re-enabling it. Since you want to check if the first press is <=100ms, just make the debounce period 100ms. If it is not depressed when the 100ms timer expires, you have a short press. Otherwise, re-enable the interrupt and then measure when the button up event occurs.

VGold
Associate II

The best way I'm using is

You need to detect if button was pressed and start counting from this point.

you can just in main loop check if pin is low (because you are using pull-up to power) and after this you have two ways: start a timer or to count in main cycle. Doesn't realy matter, speeds are very fast you will not see difference. Timer is more accurate but uses interrupts versus simple cycle counting but without interrupts.

After counting variable started to increment itself every cycle you are checking if it was released by simply checking pin.

So here is the magic: after releasing button you have some value in your counter, now you need to check how long it was pressed depending on it's value, here are examples:

  1. ButtonVar is 10 -> this is bouncing, ignore it and wait the next press, clear counter var
  2. ButtonVar is 5000 -> this is representing in example 50 ms, ignore it, too fast press, clear counter var and wait the next press
  3. ButtonVar is or more than 1000 and less than 50000 - 100+ms press->do task
  4. ButtonVar is greater than 50000 equals 500ms and longer press ->do task

This is very simple way, you can use it

1.without any interrupts and

2.without timers, your main cycle frequency is fast enough and it's much more faster you need (millions or less times per second)

3. automatically filter any bounce or noise (equals to extra-fast presses, ignore it)

int countersA = 0; // or you can use an array for many buttons
 
while(1)
{
   CheckMyButton();
};
 
void CheckMyButton(void)  //or use int to check many buttons 
{
   if (CheckPinIsLow) { counterA++; }
   else
   {
      if ((counterA >= 1000) && (counterA<5000)) DoOur100MsTask();
      if (counterA > 5000) DoOur500MsTask();
      counterA = 0;
   }  
};

AvaTar
Lead

Post get quickly out of sight in this forum, and the search is terrible.

I haven't any source code at hand. My "examples" are in commercial project of former companies now.

But the "old" SPL libraries for the F4 and F3 discovery contained example code for button handling.

But the methods mentioned before would work.

Try your ideas, see if you can easily make a short, longer, and long button press. If you can't, the user will neither ...