2018-09-13 11:48 AM
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
2018-09-14 01:12 AM
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.
2018-09-14 01:44 AM
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 ?
2018-09-14 01:58 AM
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.
2018-09-16 02:52 PM
can give a sample code.. i think i will understand better
2018-09-16 06:05 PM
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.
2018-09-17 12:30 PM
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:
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;
}
};
2018-09-17 10:28 PM
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 ...