Reputation: 43
I'm trying to implement a logic to detect a keypress and hold from a RF remote. Currently I'm able to detect the button press in my controller RF receiver. I'm getting the interrupt callback for every press. Now how do I detect a press and hold for 5 sec in the code?
I checked in the oscilloscope that when I press and hold a key in remote, I get the RF data in my receiver every 34ms.
All I can think of is to count the number of sequential interrupts with the same data in 5 secs and validate it but I'm not sure its the right way.
Any suggestions how to implement it. I will try it.
Thanks
Upvotes: 1
Views: 1763
Reputation: 43
Thank you all so much for the suggestions. I implemented the logic based on the suggestion given by users "the busybee, Clifford and Lundin" and it is working now. Please have a look.
void ISR_callback(uint32_t value) //Button press ISR
{
button_data = (uint8_t)((value>>8) & 0xF);
if(button_data == 0xB) //required button pressed
{
button_pressed = 1;
button_timer_50ms = 0; //reset the independent 50ms counter, if button pressed
}
}
void main(void)
{
while(1)
{
if (one_ms_time_expired()) //1ms timer loop
{
if(button_pressed) //is set in ISR, if button is pressed
{
timer_5sec++; //Counter to check if key is pressed for 5 sec
button_timer_50ms++; //Independent counter to reset status if button is released
if(button_timer_50ms==50) //if no key pressed for 50ms, reset all status
{
button_timer_50ms = 0;
button_pressed = 0;
timer_5sec = 0;
button_data = 0;
}
if(timer_5sec == 5000) //5sec done
{
timer_5sec = 0;
button_data = 0;
button_pressed = 0;
button_timer_50ms = 0;
//Buzzer_ON
}
}
}
}
}
Upvotes: 0
Reputation: 93546
A good idea with any button, direct, or as in this case remote, is to detect both press and release. Then apply the press and hold timing on top of that. In that way physical and remote buttons can be handled in the same manner.
In this case you could detect release by setting a 50ms timer that is restarted on every 35ms button interrupt. Then if the 50ms timer expires, the button has been released (or gone out of range).
Then for the 5 second hold, you could have 5 second timer that can be started on button down, and cancelled on button release. Similarly, if that timer expires you trigger the hold event.
The timers could be implemented in software or hardware, although it might be a poor use of resources to dedicate two hardware timers to one button.
See also Pressing button for 3 seconds and how to measure its time with Atmega8 1MHz?. Given press/release detection as described above, you could apply the higher level hold timing as in the accepted answer to that question.
Upvotes: 2
Reputation: 214525
First of all, depending on what RF technology you are using, you may not be getting the response in real-time. Some RF technologies have relatively long latency/propagation delay and many can't guarantee real-time at all. You may want to take this in account by measuring with a scope the time between the physical key press in the transmitter until the time when that key press is detected in the receiver.
Also we have to assume that the button is properly debounced on the transmitter side, or you'll be getting lots of garbage sent through the air.
Possible method 1:
Possible method 2:
Upon getting the first keyboard interrupt, assuming it fires on rising edge, change that interrupt to now trigger on falling edge. Then start a timer and ensure that no interrupts fire during the time that timer was running.
Some MCU timer peripherals support input capture on both edges, so you could implement various alternative methods to the above based on that.
Possible method 3:
Upvotes: 1