Single button function


Closed Thread
Results 1 to 40 of 41

Hybrid View

  1. #1
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Code:
    	MyButton var PortB.0		' Your Button can be anywhere
    					' Connect between PIC pin and Vss
    					' Use Weak Pull-Up or Resistor to Vdd
    
    	ButtonPress var BYTE		' Button Counter Variable
    
    	LongPress con 20		' Change this value for desired SET 
    					' function trip-point in 50mS steps
    					' Currently set for 1 Second
    
    	
    MainLoop:
    	LCDOut $FE,1,"Go Press..."
    ButtonLoop:
    	Gosub GetButton
    	If ButtonPress>0 then
    		If ButtonPress=1
    			LCDOut $FE,1,"Short Press"
    			else	
    			LCDOut $FE,1,"Long Press"
    			endif
    		Pause 1000
    		Goto MainLoop
    		endif
    	Goto ButtonLoop
    
    	'
    	'	Subroutine weighs-up users finger
    	'	in multiples of 50mS
    	'	Constant LONGPRESS determines boredom level
    	'	-------------------------------------------
    	'	on Exit...
    	'	ButtonPress=0 - No Press
    	'	ButtonPress=1 - Short Press
    	'	ButtonPress=2 - Long Press
    GetButton:
    	ButtonPress=0
    	While MyButton=0
    		If ButtonPress<255 then ButtonPress=ButtonPress+1
    		Pause 50 ' This is also our Debounce value
    		Wend
    	If ButtonPress>0 then
    		If ButtonPress=>LongPress then 
    			ButtonPress=2
    			else
    			ButtonPress=1
    			endif
    		endif
    	Return
    If you have an LCD for example, you can always clear the display (or light a LED if you have one) to indicate that a SET has been performed. Here's a variation..
    Code:
    	MyButton var PortB.0		' Your Button can be anywhere
    					' Connect between PIC pin and Vss
    					' Use Weak Pull-Up or Resistor to Vdd
    
    	ButtonPress var BYTE		' Button Counter Variable
    
    	LongPress con 20		' Change this value for desired SET 
    					' function trip-point in 50mS steps
    					' Currently set for 1 Second
    
    	
    MainLoop:
    	LCDOut $FE,1,"Go Press..."
    ButtonLoop:
    	Gosub GetButton
    	If ButtonPress>0 then
    		If ButtonPress=1
    			LCDOut $FE,1,"Short Press"
    			else	
    			LCDOut $FE,1,"Long Press"
    			endif
    		Pause 1000
    		Goto MainLoop
    		endif
    	Goto ButtonLoop
    
    	'
    	'	Subroutine weighs-up users finger
    	'	in multiples of 50mS
    	'	Constant LONGPRESS determines boredom level
    	'	-------------------------------------------
    	'	on Exit...
    	'	ButtonPress=0 - No Press
    	'	ButtonPress=1 - Short Press
    	'	ButtonPress=2 - Long Press
    GetButton:
    	ButtonPress=0
    	While MyButton=0
    		If ButtonPress<255 then ButtonPress=ButtonPress+1
    		Pause 50 ' This is also our Debounce value
    		If ButtonPress=LongPress then LCDOut $FE,1
    		Wend
    	If ButtonPress>0 then
    		If ButtonPress=>LongPress then 
    			ButtonPress=2
    			else
    			ButtonPress=1
    			endif
    		endif
    	Return
    Another variation which I tend to use, is if you have a Piezo, beep it at every Button Press start (ie ButtonCount=1) as a confidence indicator for the user (they like things like that), and then Beep Constantly once the LONGPRESS value has been reached. example...

    Code:
    	'
    	'	Subroutine weighs-up users finger
    	'	in multiples of 50mS
    	'	Constant LONGPRESS determines boredom level
    	'	-------------------------------------------
    	'	on Exit...
    	'	ButtonPress=0 - No Press
    	'	ButtonPress=1 - Short Press
    	'	ButtonPress=2 - Long Press
    GetButton:
    	ButtonPress=0
    	While MyButton=0
    		If ButtonPress<255 then ButtonPress=ButtonPress+1
    		Pause 50 ' This is also our Debounce value
    		If ButtonPress=1 then Gosub Beep
    		If ButtonPress=>LongPress then Gosub Beep
    		Wend
    	If ButtonPress>0 then
    		If ButtonPress=>LongPress then 
    			ButtonPress=2
    			else
    			ButtonPress=1
    			endif
    		endif
    	Return
    You can go on with variations for ever....

    Code:
    	'
    	'	Subroutine weighs-up users finger
    	'	in multiples of 50mS
    	'	Constant LONGPRESS determines boredom level
    	'	-------------------------------------------
    	'	on Exit...
    	'	ButtonPress=0 - No Press
    	'	ButtonPress=1 - Short Press
    	'	ButtonPress=2 - Long Press
    GetButton:
    	ButtonPress=0
    	While MyButton=0
    		If ButtonPress<255 then ButtonPress=ButtonPress+1
    		Pause 50 ' This is also our Debounce value
    		If ButtonPress=1 then Gosub Beep
    		If ButtonPress=>LongPress then Gosub Beep
    		If ButtonPress=255 then Gosub Klaxon ' Users fallen asleep
    		Wend
    	If ButtonPress>0 then
    		If ButtonPress=>LongPress then 
    			ButtonPress=2
    			else
    			ButtonPress=1
    			endif
    		endif
    	Return
    I use a WORD as the Counter in many cases, and if the Button is held for a really long time (eg 30 Seconds or even a Minute), it lets me jump into a Secret Set-Up Menu or just display an unexpected message for the User if I'm feeling devilish... or just as a 'Granny Button' to erase Passwords, Contrast and LCD Backlight levels that have been messed up. Users are a peculiar bunch... they put a password into the Menu (which they promptly forget) or save a near Invisible LCD Contrast setting and then they call Tech-Support to pull them out of the sh*t. It's nice to tell them to Press and Hold the Button for 30 minutes (or until their finger goes numb - whichever comes first) and everything will reset back to the factory default settings... (it'll reset after a minute, but if you tell them 30 they'll not do it a second time).

  2. #2
    Join Date
    Jun 2005
    Location
    Wisconsin
    Posts
    382


    Did you find this post helpful? Yes | No

    Default

    Melanie as always thank you for your examples and advice.

    What I'm seeing in your examples is what I'm already doing. A single short press functions normally and the user sees a value increment when they release the switch. However in the case of a long press (ENTER) they have no idea, short of adding an led/buzzer/clear screen, that they have held the switch long enough to change menus. Basically they have to count in their head.

    Is this just something I need to live with? Do you run into any problems with this type of interface?

  3. #3
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Wherever possible I use a 3-button interface (Up/Down/Set), but if I'm stuck with one button, I try to provide some kind of user feedback so they know where they stand...

    Example 1... www.k3planet.com/Datasheet-9910-1.pdf

    ...and people thought I was kidding when I said I put "Yankee Doodle" into a commercial product!

  4. #4
    Join Date
    Jun 2005
    Location
    Wisconsin
    Posts
    382


    Did you find this post helpful? Yes | No

    Default

    Nice!

    Alright I give; I either need to use another pin for feedback or add another switch. I guess I need to move from a minimalist single switch project to a two switch project.

    Thanks for the assistance.

  5. #5
    Join Date
    May 2004
    Location
    New England
    Posts
    164


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by DynamoBen
    However in the case of a long press (ENTER) they have no idea, short of adding an led/buzzer/clear screen, that they have held the switch long enough to change menus. Basically they have to count in their head.
    Is this just something I need to live with? Do you run into any problems with this type of interface?
    What about having the menu change happen automatically after a button HOLD of say 1.5 seconds.
    The user sees the menu change, so they know they've held the button long enough.
    After the menu changes, your code then waits for the button to be released before continuing - avoiding spurious inputs at the new menu.
    If the user is goofy enough to continue holding the button, the program just sits waiting until they release it (or rig up a shocker on the button so they get zapped after 20 seconds :-)

    Only quicly looked over Melanies samples - maybe she already suggested something like that?

    Arch
    "Data sheets? I ain't got no data sheets. I don't need no data sheets. I don't have to read any stinking data sheets!"

  6. #6
    Join Date
    Jun 2005
    Location
    Wisconsin
    Posts
    382


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Archilochus
    What about having the menu change happen automatically after a button HOLD of say 1.5 seconds.
    The user sees the menu change, so they know they've held the button long enough.
    After the menu changes, your code then waits for the button to be released before continuing - avoiding spurious inputs at the new menu.
    If the user is goofy enough to continue holding the button, the program just sits waiting until they release it (or rig up a shocker on the button so they get zapped after 20 seconds :-)

    Only quicly looked over Melanies samples - maybe she already suggested something like that?

    Arch
    This is exactly what I wanted to do. However it’s a programming nightmare. I have been working on this for days and have come up with nothing. It is simple to describe but difficult to implement.

  7. #7
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Do you not have anything that can be used as feedback to the user? Describe your User Interface (OK, so we know it's got ONE button) - but what else has your device got in the way of LEDs LCDs or Beepers? And what do you want the Button to Do?

  8. #8
    Join Date
    Jun 2005
    Location
    Wisconsin
    Posts
    382


    Did you find this post helpful? Yes | No

    Default

    The UI currently consists of one switch and an LCD. The switch is used to change time/date in normal mode. In the backdoor setup its used to set the time/date on a RTC.

    The advantage to having two switches is that the user could have autorepeat functionality when setting the clock in setup. The disadvantage is that the second switch would go unused the rest of the time, which is most of the time.
    Last edited by DynamoBen; - 7th June 2006 at 01:39.

  9. #9
    Join Date
    May 2004
    Location
    New England
    Posts
    164


    Did you find this post helpful? Yes | No

    Default

    This is cut & adapted from an old piece of graphical LCD menu / sub-menu code that I had laying about. There was more to it, but I removed some stuff that didn't apply. I *think* this code worked OK, but it's been a long time since I played with it. I added some comments to it...

    Code:
    ; Button press pulls input pin LOW
    
    ; This next is placed with the subroutines...
    CountButn:	; Count button press duration during a ~2s loop.
    ; Loop auto-exits after either 2 seconds, or when user releases the button
    ; (if released before 2 seconds are up).
    ; "HoldFlag" used to flag if button pressed (HoldFlag=0), or held (HoldFlag=1).
    	pause 50 : HoldFlag = 0   ; Pause to ignore switch bounce, clear flag 
    	For CounterC = 0 to 49    ; 2s loop checks button input state...
    		Pause 40
    		if Butn then Exit_CountButn  ; When button released, end loop
    	Next CounterC                            ; Increment counter each loop
    Exit_CountButn:	; Test # loops button held for. If > 20 (0.8s), set 'HoldFlag'
    	if CounterC > 20 then HoldFlag = 1	
    	Return
    ;
    ; ####################################
    ;
    ; Here we're in the "main menu" section and looking for a button press OR hold.
    	if Butn = 0 then    ; On button press...
    		gosub CountButn    ; check button press duration (press / hold)
    		WHILE Butn = 0      ; On return from sub, if button still held,
    		WEND                   ; wait until user releases button.
    		if HoldFlag then      ; if HELD more than 0.8S, HoldFlag will be set
    			gosub PressPower : goto SecureChk ; Turn OFF, jump to security mode menu
    		EndIF
    ; if only pressed, NOT held, HoldFlag=0, so continue with whatever you need to do...
    ; Clear out previous arrow before drawing new...
    		CS_Left=0 : CS_Right=1 : GraphicFlag=1 : TextFlag=0
                    LoopStop=7 : StartADR=7690    ; graphic memory address
    		TempXY = PageFlag : gosub SetXY	; Set LCD X, Y locations
    		gosub Write_Data		; Write commands to LCD
    		PageFlag = PageFlag + 1	      ; Increment page counter after button press
    		if PageFlag > 3 then PageFlag=1	; Limits page counter to 1-3
    		gosub DrawArrow			; Draw new 8 byte arrow 
    		CounterA = 74			  ; After any press, loop continues 6sec looking for more presses.
    	EndIF
    "Data sheets? I ain't got no data sheets. I don't need no data sheets. I don't have to read any stinking data sheets!"

Similar Threads

  1. Sony SIRC IR Issue
    By Ryan7777 in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 8th August 2015, 09:10
  2. 3 HPWM channels
    By docwisdom in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 4th April 2006, 03:43
  3. Code check -- button not working
    By docwisdom in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 2nd March 2006, 23:43
  4. Pushbutton code routine suggestions?
    By jessey in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 3rd September 2005, 02:02
  5. Button subfunction 16F628
    By Jųan in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 19th August 2005, 17:44

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts