PDA

View Full Version : three functions (press, double-click, long press) in one button



keymuu
- 23rd February 2011, 00:09
Hi!

there was a thread talking about this but only with two functions, a normal and a long press. Could not found the double-click incorporated there, not in Mel's code or any other place either. So I figured out the following sub-routine based on Mel's code. Bpressed is the byte returned from the´MCP23016 read, where all buttons are attached. the procedure returns in buttoPress what kind of a press it was:

specialButton: 'check if normal button press, double-click or a long press
buttonCnt = 0
gosub getIOexp ' get IOexpander MCP23016
while ((Bpressed && useButton) = useButton) and (buttonCnt < 60) ' check if a long press..
buttonCnt = buttonCnt + 1 : If buttonCnt >= 100 then goto error
pause 25 ' -> 60 x 25ms = 1,5 sec = long press
gosub getIOexp
wend

buttonPress = shortPress ' normal press

if buttonCnt >= 60 then
buttonPress = longPress
return 'it was a LONG PRESS, so no need to check other things

else ' now it can be either a normal press or double-click

buttonCnt = 0
' not pressed at the moment, but wait for a second click
gosub getIOexp ' read the buttons once again, and wait if the user
' clicks/push the button a second time within 1sec
while ((Bpressed && useButton) = 0) and (buttonCnt < 40)
buttonCnt = buttonCnt + 1 : If buttonCnt >= 100 then goto error
pause 25 ' -> 40 x 25ms = 1 sec
if ((Bpressed && useButton) = useButton) then 'pressed/clicked again?
buttonPress = doublePress
return ' it was a DOUBLE-CLICK, so no need to continue
endif
gosub getIOexp
wend ' if not pressed within one second, then it was a single press
' and also the program will not advance within that second, and
' that looks of course like the program would hang for that time.
endif ' buttonCnt >= 60
return ' form specialButton

However, that is not elegant when waiting for a double-click but it was only a single press.:(
The program waits in vain for one second, before it can continue. :mad:

Could somebody please tell if there is some other approach which would not have that one second delay? All ideas are appreciated, thank you.

Jerson
- 23rd February 2011, 08:22
Well, I guess, you need to wait anyway to determine a double press. So, one option left is to reduce the waiting time from 1sec to maybe 300mS.

Second option would be to selectively look for a single press, double press or long press where applicable and thus save the common routine which determines all three modes.

Mike, K8LH
- 24th February 2011, 13:16
I think "short" press, "long" press (>1 second), and "longer" press (>2 seconds) might work better since you can act on the "release" switch state. I would also use a piezo speaker or something similar for audible feedback. Generate a single short beep on the "new press" state, a double beep at the one second timeout, and a triple beep at the 2 second timeout.

Cheerful regards, Mike

amgen
- 24th February 2011, 20:17
I use 3 function, 1 button:
>short press, on/off
>press 2 sec next function ( 8 hr on for example)
>press/hold 5 sec to go to program function

Led indicates mode,

prioritize functions so you wait for less used functions

this project was a lighting timer switch, press on/off, hold 2 sec for 8hr on, press to program(led blinks fast) set for 15,30,60 minutes stored to eeprom.
fun project

keymuu
- 26th February 2011, 01:08
Thanks,
it seems to be impossible to fight against time, waiting for the other click in double-click.
If you have many buttons then of course one could use a "boolean" variable for ex. enableDblClick and have it TRUE when you need double-cliks and FALSE when not and exit straight after long or short press. Then of course one should consider if there really is a need for all three functions for one button in the case if there are several buttons in you application. And as suggested, using short, semi-long and long press gives also 3 functions for one button...
Many things are possible, but not exactly all ;)

Charles Linquis
- 26th February 2011, 05:51
You could do something like:
create 2 flags
create 4 counters
Set up a TMR interrupt to interrupt every 10 ms or so. Poll your button.
If the button is down, increment two counters - "down1counter" and a "totaltimecounter" and set flag1. If flag1 is set and flag2 is not set, and the button is up, increment an "upcounter" and the totaltimecounter. Set flag 2. If flag 1 is set and flag 2 is set, and the button is down, increment down2counter and the totaltimecounter. Let totaltimecounter continue to run. After totaltimecounter has reached some value (a couple of seconds maybe), clear all counters to get ready for the next push(es).

Before being cleared, the counters should have the information your program needs to make a decision. All in the background.