2018-08-27 12:36 AM
I have tried something like below in my interrupt function but i was unable to detect long press ,every time it was detecting short press.
static timestamp_pressed=-1;
if (timestamp_pressed == -1)
{
user just pressed the button
timestamp_pressed = HAL_GetTick(); // milliseconds since startup
}
if (HAL_GetTick() - timestamp_pressed > 3000)
{
// 3000 milliseconds = 3 seconds are over
state_Long=1;
timestamp_pressed = -1;
}
else
{
state_short=1;
timestamp_pressed=-1;
}
2019-01-28 07:17 PM
I'm not going to be of any direct help as I'm trying to learn STM32 coming from a PIC background. I have the following code that works for PIC and detects short and long press and even toggles an output (buzzer) once inside the long loop. Hopefully you can adapt, and post the code back.
char AdvancedButton(char *port, char pin, char active_state, uint16_t time_ms_short, uint16_t time_ms_long) {
unsigned int cnt = 0;
char result = 0;
unsigned int time;
time = (time_ms_long - time_ms_short);
if ((*port >> pin & 0x01) == active_state) {
result = 1;
vdelay_ms(time_ms_short); // Debounce time
while ((*port >> pin & 0x01) == active_state) {
if (++cnt >= time) {
result = 2;
// Make a beep to signal long press achieved
while ((*port >> pin & 0x01) == active_state) {
// wait till button released
}
break;
}
delay_ms(1);
}
}
return result;
}
Cheers,
Paul
2019-01-28 11:36 PM
You need to differ between events.
On button down, start the timer to measure the press length.
On button up, evaluate the elapsed time and raise the appropriate event.
Only debouncing makes the algorithm slightly more complex.
2019-01-29 10:03 PM
If you wait until the button is released before checking the elapsed time then there is no opportunity to sound a beep, flash a LED or whatever to alert the user that a long press has happened.
2019-01-29 10:32 PM
True, but only if one would want to do that. I can't read that requirement out of the OP's post.
2019-01-29 11:15 PM
Perhaps he doesn't know what he wants yet =) I'm a bit like that.
After some playing around, this works fine.
pressed = AdvancedButton(GPIOD, GPIO_Pin_11, 1, 30, 3000);
if (pressed == 1) {
printf("%s\r\n", "Short Press");
}else if (pressed == 2) {
printf("%s\r\n", "Long Press");
}
uint8_t AdvancedButton(GPIO_TypeDef *port, uint16_t pin, uint8_t active_state, uint16_t time_ms_short, uint16_t time_ms_long) {
uint8_t result = 0;
uint16_t time;
uint32_t last_val;
time = time_ms_long - time_ms_short;
last_val = millis();
if (TM_GPIO_GetInputPinValue(port, pin) == active_state) {
result = 1;
delay_ms(time_ms_short); // Debounce Time
while (TM_GPIO_GetInputPinValue(port, pin) == active_state) {
if (millis() - last_val >= time) {
result = 2;
//
// Make a beep or something here
//
while (TM_GPIO_GetInputPinValue(port, pin) == active_state) {}
break;
}
}
}
delay_ms(100); // Short delay to counter debounce on release
return result;
}
2019-01-30 01:02 AM
The questions are:
- Does the target hardware have any audio output (beep) at all ?
- Would it even be heard at the deployment side ?
For systems I came across last years, the answers were always no.
Which doesn't mean they do not exist ...
2019-01-30 02:13 AM
In my case I'm designing the PCB with a buzzer so that I can have some audible feedback when the long press has occured. Being on the same board as the pushbutton, being able to hear it really isn't an issue.
Ohh, almost forgot, I have a couple of macros defined.
// Define macro to read pin state
#define TM_GPIO_GetOutputPinValue(GPIOx, GPIO_Pin) (((GPIOx)->ODR & (GPIO_Pin)) == 0 ? 0 : 1)
#define TM_GPIO_GetInputPinValue(GPIOx, GPIO_Pin) (((GPIOx)->IDR & (GPIO_Pin)) == 0 ? 0 : 1)