Truncated match.
PICList
Thread
'Push buttons'
1997\03\25@012849
by
David BALDWIN
|
Hi,
As usual, I have some questions today... I am using the check_keys
routine from Bob Blick. In fact, it only detects falling edges on portA.
I am searching for a routine that could decide between a single press on
a switch and a long press on a switch (more than 500ms or 1s). The
reason is that I don't have so much I/O on my 16C84 and had like one
switch to have more than one function. Can anybody help?
-david
P.S.: Thanks to everybody for the EEPROM writing, it works nicely since
I am waiting for the write to complete :)
;--------
; test for keypress and call time adjust if needed
;--------
Check_keys movf PORTA,w ;get port "a"
xorwf keys,w ;compare with previous
andlw b'00000111' ;only care about button pins
btfsc STATUS,Z ;zero set=no buttons
retlw 0 ;return
xorwf keys,f ;store key value
movlw 0x64 ;a fairly long delay will
movwf scratch ;prevent key bounces
Key_delay movlw 0xFF
call Delay
decfsz scratch
goto Key_delay
btfss keys,2 ;test "minutes" button
goto Inc_mins
btfss keys,1 ;test "tens" button
goto Inc_tens
btfss keys,0 ;test "hours" button
goto Inc_hours
retlw 0 ;must be a glitch. yeah, right!
1997\03\25@023726
by
tjaart
|
David BALDWIN wrote:
>
> Hi,
>
> As usual, I have some questions today... I am using the check_keys
> routine from Bob Blick. In fact, it only detects falling edges on portA.
> I am searching for a routine that could decide between a single press on
> a switch and a long press on a switch (more than 500ms or 1s). The
> reason is that I don't have so much I/O on my 16C84 and had like one
> switch to have more than one function. Can anybody help?
>
I use a routine in my Timer0 interrupt service that does the following :
Is button pressed ?
Yes : Increase counter BUTTON_COUNTER
Is BUTTON_COUNTER > 10 (This value depends on your app)
Yes : Set BUTTON_PRESSED_FLAG
No : BUTTON_COUNTER = 0
All you have to do in your main routine, is to look if
BUTTON_PRESSED_FLAG is set.
If you want to use look for long and short presses, do the following :
Use a routine in your Timer0 interrupt service that does the following :
Is button pressed ?
Yes : Increase counter BUTTON_COUNTER
Is BUTTON_COUNTER > 20 (This value depends on your app)
Yes : Set LONG_FLAG
Is BUTTON_COUNTER > 10 (This value depends on your app)
Yes : Set SHORT_FLAG
No : BUTTON_COUNTER = 0
Is LONG_FLAG set ?
Yes : Set LONG_BUTTON_PRESSED_FLAG
Else is SHORT_FLAG set ?
Yes : Set SHORT_BUTTON_PRESSED_FLAG
All you have to do in your main routine, is to look if
SHORT_BUTTON_PRESSED_FLAG,
or LONG_BUTTON_PRESSED_FLAG is set.
You have to remember to reset the flags after use in your main routine.
If you think
this is a very long and cumbersome method, here are a few points to
consider :
1) Your software never hangs in delay loops
2) The inputs are much better debounced than with just two samples.
3) You work with flags, so you don't have to worry about the debouncing
- it happens
by itself.
4) If you have multiple inputs, you can optimise the code to be shorter
than other
methods.
5) If you use this method to debounce keypads, you'll find double
keypresses easy.
--
Friendly Regards
Tjaart van der Walt
spam_OUTtjaartTakeThisOuT
wasp.co.za
_____________________________________________________________
| Another sun-deprived R&D Engineer slaving away in a dungeon |
| WASP International http://wasp.co.za |
| GSM and GPS value-added applications |
| Voice : +27-(0)11-622-8686 | Fax : +27-(0)11-622-8686 |
|_____________________________________________________________|
1997\03\25@090932
by
Karoly Hoss
David BALDWIN wrote:
>
> Hi,
>
> As usual, I have some questions today... I am using the check_keys
> routine from Bob Blick. In fact, it only detects falling edges on portA.
> I am searching for a routine that could decide between a single press on
> a switch and a long press on a switch (more than 500ms or 1s). The
> reason is that I don't have so much I/O on my 16C84 and had like one
> switch to have more than one function. Can anybody help?
>
> -david
not a nice way but it worx in my app
button : jnb button,xxx
call waitasecond
xxx jnb button,yyy
first funtion starts
goto button
yyy second function starts
goto button
as for debounce and such things
I use pullup resistor in paralell with a small cap
it worx perfectly for me
bye
charley
1997\03\25@113441
by
John Dammeyer
|
At 07:25 AM 25/03/1997 +0100, you wrote:
>I am searching for a routine that could decide between a single press on
>a switch and a long press on a switch (more than 500ms or 1s).
I'd make one suggestion here. Set up your algo. in such a way that you
accept the single press as an action that occurs between the debounce period
(50-100ms) and your long press. There is nothing more frustrating to an
equipment user than to have the action occur after the button is released.
In your example an operator would feel frustrated if they pressed the button
down for 400ms and nothing happened but if they pressed for 401ms it did.
From an ergonometric prespective users prefer the act of pressing the button
to cause an action rather than releasing the button. If the button is used
for two totally opposite things you may find this difficult to impliment.
Try adding feedback at the moment the debounce period is complete but before
you make a choice on button action. An operator, who hears a beep or sees a
LED blink, and just wants the short press, will then release the key at
which time you could invoke the action.
John
Pioneers are the ones, face down in the mud,
with arrows in their backs.
Automation Artisans Inc. Ph. 1-250-544-4950
PO Box 20002 Fax 1-250-544-4954
Sidney, BC CANADA V8L 5C9
1997\03\25@211544
by
sdattalo
|
David BALDWIN wrote:
> As usual, I have some questions today... I am using the check_keys
> routine from Bob Blick. In fact, it only detects falling edges on portA.
> I am searching for a routine that could decide between a single press on
> a switch and a long press on a switch (more than 500ms or 1s).
David,
Check out my debouncing routine to capture both edges:
http://www.interstice.com/~sdattalo/technical/software/pic/debounce.html
A simple way to check if a key is pressed for a "long time" is with
the following untested code:
MOVF previous_state,W ;Get the previous state of the
;switch (i.e. the last time it
was
;debounced).
XORWF latest_state,W ;Get the latest state of the
switch
XORWF previous_state,F ;Save latest state as previous
state
ANDLW BIT_POS_OF_SWITCH ;We're interested in this bit.
SKPNZ ;or SKPZ if input is low on key
press
INCFSZ a_counter,F ;Detected a pressed key count
it.
CLRF a_counter ;No detection, so clear the
counter.
If this little chunk of code runs once every 5ms and you want to measure
key presses longer than one half of a second, then you simply need to
monitor when "a_counter" exceeds 100 (base 10). The state of the switch
is the "debounced state". In other words, the debounce routine would
first
execute before this one. Anyone see the subtlety in the skips?
Scott
PS. John, CLRF DOES affect the Z-bit on 16Cxx parts too. You will have
to make many, many, many more mistakes before any embarassment is
warranted
though.
More... (looser matching)
- Last day of these posts
- In 1997
, 1998 only
- Today
- New search...