Single button function


+ Reply to Thread
Results 1 to 40 of 41

Hybrid View

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

    Default Single button function

    I have a single button that needs to allow users to navigate menus and increment selections.

    I have tried a few things, but wanted to ask the group for ideas. As usual I'm short on space.

    Function 1: Press and Release = Increment
    Function 2: Press and Hold = Enter

    What I have now works ok until you move onto the next submenu and the value increments right away. (BTW ButtonCnt is tied to TMR1 to count how long the button has been held)

    While Switch=0
    IF ButtonCnt>30 Then SubMenu=SubMenu+1
    Wend

    value=value+1

    Thoughts on this one?

  2. #2
    Join Date
    Feb 2005
    Location
    Kolkata-India
    Posts
    562

    Lightbulb Do your user know Morse

    Hey,

    Just kidding. For user friendliness ,I beleive follow the mouse. Click, Double Click, Hold and any combination of the three.

    1. Hold to enter menu.

    2. Click to cycle between items

    3. Double Click to enter submenu incr/decr

    4. click + Click hold increase / decrease alternate

    5. Double click back to main menu

    6. Double click quit menu

    Please post the code if it works.

    Regards

    Sougata

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

    Default

    I found a similar device and will be using the method I described above.

    My conditional statements needed some alteration to function properly.

    Problem solved.

  4. #4
    Join Date
    Apr 2004
    Location
    Ladysmith on Vancouver Island in BC Canada
    Posts
    173

    Default Will this work?

    Hi DynamoBen,

    I wrote a short bit of code here that compiles to 74 words. I'm not sure if it's what you were looking for but I thought I'd post it anyway.

    The first press and release of the button after a hearing a single beep of the buzzer will INCREMENT your variable. Any further (single quick press's) that sounds a single beep will continue to increment the variable and when your finished incrementing then holding the button down for 4.5 seconds will ENTER the variable and exit the loop.

    If you wanted to increment and enter another variable using the same push button then you could place another IF-THEN in the loop and when it beeps a set number of times then the code could jump out of that loop into another loop and the same basic code could be repeated for a different variable (with a little modification to the original code below).

    Also an Led could be used instead of the buzzer. I'm not sure but I think this is what you wanted?

    IF Settings_Push_Button = Is_Pressed THEN
    For i = 0 to 100'this ensures that we return to mainloop
    WHILE Settings_Push_Button = Is_Pressed
    PWM Buzzer,250,1 : PAUSE 1500 : Y = Y + 1
    IF Y = 3 THEN
    'Do the ENTER
    Y = 0
    IF Y = 0 THEN EXIT
    ENDIF
    WEND

    IF Y = 2 THEN
    Y = 0
    'Do the Increment
    ENDIF

    PAUSE 100
    NEXT i
    ENDIF

    EXIT:

    jessey

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

    Default

    Alright I'm back at this again. I can’t figure out an efficient way to do this. My original solution was:

    ButtonHeld con 30

    Switch_Routine:
    ButtonCnt=0
    While Switch=0:Wend
    Pause 250
    Return

    Main:
    ' display lcd info here

    IF Switch=0 Then
    GoSub Switch_Routine

    IF ButtonCnt>ButtonHeld Then
    ' change menu option
    Else
    ' increment value
    EndIF
    EndIF

    Goto Main


    Timer1 counts how long (100 ms interval) the switch is held. Once the user releases the switch then it would reenter the Main to execute the code. The problem is there is no feedback to the user if the button has been held long enough. The program stays at the While:Wend until the user releases the button. If I jump out of the switch prior to the release of the switch the loop keeps executing the same switch command until the user releases the switch. Remember: the switch is still being held down.

    I’m looking for ideas. If the user presses and releases the switch the program would increment value. If the user presses and holds the switch for 3 seconds or more it would change menu options.

    Basically I want two buttons in one.

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

    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).

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

    Default

    Oops - when I cut and altered that example, I messed up...
    The "WHILE / WEND" test for release of the button should be placed AFTER you jump to and write the new menu.
    Otherwise, without the new menu appearing, the user will not know when to let go of the button, and would stand there forever after holding the button... waiting, and waiting...

    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!"

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

    Default

    Your example had the same issue. User sees no change in the display until the button is released.

    I will look into placing the while:wend after display update.

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

    Default A real live working example of ONE Button usage...

    This appended example is the basis for the worlds most inaccurate clock.

    It’s demonstrating ONE Button usage.

    Press the Button momentarily and it will flip the display between 12/24 Hour Mode.

    Press the Button for an extended time and it will jump into a Menu for you to set the time. Note the creative use of the CURSOR to indicate when a SET Function has been executed...

    It’s just a ditty to show how you can do things with ONE Button.

    And shows that code previously written (Olympic Timer) for a PIC16F876 can be quickly and easily ported and modified for a PIC16F628, or PIC16F628A or B or C...

    It’s also a teaser for half a dozen recent (Timer) threads (and for a gentleman searching for an elapsed timer – hint – hint – somebody nudge him to look at this thread!!!!) to show what can be done with 10 minutes worth of code, half a bucket of Cafe Nero's finest and a plastic straw...

    Code:
    	'
    	'	Buttons.bas
    	'	---------------
    	'	by Melanie 
    	'	written on a Laptop in a lunchbreak in a Cafe Nero
    	'	in Londons famous Regent Street... 7th June 2006
    	'
    	'	A simple demonstrator as to what can be done
    	'	with just ONE Button and an LCD...
    	'	Some Code stolen from OLYMPIC TIMER
    	'
    
    	'
    	'	Device Programming Options
    	'	--------------------------
    	@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT
    					' System Clock Options	
    	@ DEVICE pic16F628, WDT_ON	' Watchdog Timer
    	@ DEVICE pic16F628, PWRT_ON	' Power-On Timer
    	@ DEVICE pic16F628, BOD_ON	' Brown-Out Detect
    	@ DEVICE pic16F628, MCLR_OFF	' Master Clear Options (Internal)
    	@ DEVICE pic16F628, LVP_OFF	' Low-Voltage Programming
    	@ DEVICE pic16F628, CPD_OFF	' Data Memory Code Protect
    	@ DEVICE pic16F628, PROTECT_OFF	' Program Code Protection
    
    	'
    	'	Hardware Defines
    	'	----------------
    		'
    		' 	LCD Display
    		'	-----------
    	Define LCD_DREG PORTB		' Port for LCD Data
    	Define LCD_DBIT 4		' Use upper 4 bits of Port
    	Define LCD_RSREG PORTB		' Port for RegisterSelect (RS) bit
    	Define LCD_RSBIT 3		' Port Pin for RS bit
    	Define LCD_EREG PORTB		' Port for Enable (E) bit
    	Define LCD_EBIT 2		' Port Pin for E bit
    	Define LCB_BITS 4		' Using 4-bit bus
    	Define LCD_LINES 2		' Using 2 line Display
    	Define LCD_COMMANDUS 2000	' Command Delay (uS)
    	Define LCD_DATAUS 50		' Data Delay (uS)
    		'
    		'	Buttons
    		'	-------
    	MyButton var PortB.0
    
    	'
    	'	Software Defines
    	'	----------------
    	AMPMFlag var BYTE		' Flag for 12/24 Hour Mode 0=24, 1=12
    					' - Yes I know it's a BYTE but I can't be bothered
    	ButtonPress var BYTE		' Button Counter Variable
    	DataA var BYTE
    	Hours var BYTE
    	Hundredths var BYTE
    	MenuStep var BYTE		' Status Indicator for Menu Display
    	Minutes var BYTE
    	Seconds var BYTE
    	TMR1Cal	var BYTE		' Timer Calibration Value
    	TMR1CalAR var BYTE		' Timer Advance/Retard Indicator
    	TMR1RunOn var WORD		' variable holding TMR1 Run-On value
    
    
    	'
    	'	EEPROM Settings
    	'	---------------
    	Data @0,0			' Advance/Retard Indicator
    	Data 0				' Calibration Value
    	Data 0				' 12/24 Hour Flag
    
    	'
    	'	Software Constants
    	'	------------------
    	LongPress con 20		' Change this value for desired SET 
    					' function trip-point in 50mS steps
    					' Currently set for 1 Second
    	TMR1CalMax con 100		' Maximum adjustment (+/-100uS per 10mS interrupt)
    	TMR1Preset con $D910		' 10mS Timer Reload value, offset by 20uS
    					' to allow for TMR1 Setting Calculations
    	'
    	'	Initialise PIC
    	'	--------------
    	TRISA=%00000000			' PortA I/O Configuration
    	TRISB=%00000001			' PortB I/O Configuration
    	CMCON=%00000111			' Comparators OFF
    	OPTION_REG.7=0			' Enable weak Pull-Ups (used for PressButton)
    
    	'
    	'	Initialise Main Program
    	'	-----------------------
    	Pause 2000			' Timeout for LCD Hardware to wake-up...
    	Read 0,TMR1CalAR		' Read Calibration Advance/Retard Indicator
    	Read 1,TMR1Cal			' Read Calibration Value
    	Read 2,AMPMFlag			' It's what it says...
    	Hundredths=0			' Reset Timer Counter variables
    	Seconds=0
    	Minutes=0
    	Hours=0
    		'
    		'	Initialise TMR1 Interrupts
    		'	--------------------------
    	Gosub SetTimer			' Set the Timer for next 10mS Interrupt
    	On Interrupt goto TickCount
    	PIE1.0=1			' Enable TMR1 Interrupts
    	INTCON.6=1			' Enable all unmasked Interrupts
    	INTCON.7=1			' Enable Global Interrupts
    DisplayRestart:
    	LCDOut $FE,1			' Clear Display
    	'
    	'	Main Program Loop
    	'	-----------------
    	Enable
    DisplayLoop:
    	LCDOut $FE,$0C
    	If AMPMFlag=0 then
    		'
    		'	Here we have got a 24 Hour Clock Display
    		'	----------------------------------------
    		LCDOut $FE,$84,DEC2 Hours,":",DEC2 Minutes,":",DEC2 Seconds
    		else
    		'
    		'	and here we have a 12 Hour Clock Display
    		'	----------------------------------------
    		LCDOut $FE,$82
    		DataA=Hours
    		If DataA=0 then DataA=12
    		If DataA>12 then DataA=DataA-12
    		If DataA<10 then LCDOut " "
    		LCDOut #DataA,":",DEC2 Minutes,":",DEC2 Seconds," "
    		If Hours>11 then 
    			LCDOut "PM"
    			else
    			LCDOut "AM"
    			endif
    		endif
    	'
    	'	Check For Button Press
    	'	----------------------
    	Gosub GetButton
    		'
    		'	Toggle 24 Hour Mode
    		'	-------------------
    	If ButtonPress=1 then
    		AMPMFlag=AMPMFlag^1
    		Write 2,AMPMFlag
    		Goto DisplayRestart
    		endif
    	If ButtonPress<>2 then goto DisplayLoop
    	Disable
    	'
    	'	Setup Mode
    	'	----------
    	LCDOut $FE,1,"Set Time Please:"
    	LCDOut $FE,$C4,DEC2 Hours,":",DEC2 Minutes,":",DEC2 Seconds,$FE,$C5
    	MenuStep=0
    MenuLoop:
    	Gosub GetButton
    		'
    		'	SET Mode
    		'	--------
    	If ButtonPress=2 then
    		MenuStep=MenuStep+1
    		If MenuStep=3 then
    			LCDOut $FE,1,$FE,$83,"Thank You",$FE,$C0,"Have a Nice Day"
    			Pause 2000
    			Goto DisplayRestart
    			endif
    		endif
    	If ButtonPress=1 then
    		'
    		'	Hours
    		'	-----
    		If MenuStep=0 then
    			Hours=Hours+1
    			If Hours>23 then Hours=0
    			LCDOut $FE,$C4,DEC2 Hours
    			endif
    		'
    		'	Minutes
    		'	-------
    		If MenuStep=1 then
    			Minutes=Minutes+1
    			If Minutes>59 then Minutes=0
    			LCDOut $FE,$C7,DEC2 Minutes
    			endif
    		'
    		'	Seconds
    		'	-------
    		If MenuStep=2 then
    			Seconds=Seconds+1
    			If Seconds>59 then Seconds=0
    			LCDOut $FE,$CA,DEC2 Seconds
    			endif
    		endif
    		'
    		'	Ensure Cursor is in a nice place...
    		'	--------------------------------
    	LCDOut $FE,$0E
    	If MenuStep=0 then 
    		LCDOut $FE,$C5
    		else
    		If MenuStep=1 then
    			LCDOut $FE,$C8
    			else
    			LCDOut $FE,$CB
    			endif
    		endif
    	Goto MenuLoop
    
    	'
    	'	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,$0F
    		Wend
    	If ButtonPress>0 then
    		If ButtonPress=>LongPress then 
    			ButtonPress=2
    			else
    			ButtonPress=1
    			endif
    		endif
    	Return
    
    	'
    	'	Subroutine Loads TMR1 values
    	'	============================
    SetTimer:
    	T1CON.0=0			' Stop the Clock
    	TMR1RunOn.Highbyte=TMR1H	' Load the Run-On (Over-Run) value (if any)
    	TMR1RunOn.Lowbyte=TMR1L
    	TMR1RunOn=TMR1Preset+TMR1RunOn	' Calculate the New (adjusted) value for TMR1
    	If TMR1CalAR=0 then		' Calibration ADVANCE (add) or RETARD (subtract)
    		TMR1RunOn=TMR1RunOn+TMR1Cal
    		else
    		TMR1RunOn=TMR1RunOn-TMR1Cal
    		endif
    	TMR1H=TMR1RunOn.Highbyte		' Save new values to TMR1
    	TMR1L=TMR1RunOn.Lowbyte
    	T1CON.0=1			' Restart the Clock
    	PIR1.0=0			' Reset TMR1's Interupt Flag
    	Return
    
    	'
    	'	Timer Interrupt Handler
    	'	=======================
    TickCount:
    	Gosub SetTimer			' Set the Timer for next 10mS Interrupt
    	Hundredths=Hundredths+1		' Increment 10mS Seconds Counter
    	If Hundredths>99 then
    		Hundredths=0
    		Seconds=Seconds+1
    					' Increment the Seconds
    		If Seconds>59 then
    			Seconds=0
    			Minutes=Minutes+1
    					' Increment the Minutes
    			If Minutes>59 then
    				Minutes=0
    				Hours=Hours+1
    					' Increment the Hours
    				If Hours>23 then Hours=0
    				endif
    			endif
    		endif
    	Resume
    
    	End
    Attached Images Attached Images    

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

    Default

    Quote Originally Posted by DynamoBen
    Your example had the same issue. User sees no change in the display until the button is released.

    I will look into placing the while:wend after display update.
    Other than my goof with the WHILE / WEND, the code will jump to a new menu after a HOLD of ~ 1 second. If only pressed, the button test loop ends immediately, and the code continues as needed after a press & release.

    The button test loop auto-terminates after 2 seconds, so even if the user continues holding the button, the code will jump to the new menu anyway, and only after writing the new menu, does it then wait for a button release.

    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!"

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

    Default

    Melanie I've added your code into my project. When setting the times hours, minutes, or seconds the display clears and only displays the value that is currently being altered. Are you seeing the same thing or am I missing something?

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

    Default

    You're doing something wrong...

    When setting the Time, you can see all the fields (by field, you can see Hours, Minutes and Seconds on the same line, and as you press momentarilly, only the field you are currently parked on will change. When you hold for SET, the cursor changes from an underscore to a Block and on finger release moves to the next field, leaving the previous one with the content you set.

    I refer you to the Button-02 picture... there you can see the underscore cursor parked in the Hours field... pressing momentarily will advance Hours through to 23 then cycle around starting from zero. Hold the Button for SET and the cursor changes to a BLOCK, and on finger release moves to Minutes changing back to an Underscore.

    Check your $FE,xx's are the same as mine...

    Melanie

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

    Lightbulb Finally got it!

    After working on this for some time I have come up with a routine that does what I need it to do. I may use Timer1 to keep track of how long the button is held in place of PAUSE, but it works as is.

    There are three button states 0, 1, 2:
    0=no action
    1=short press/release
    2=Held


    Switch_Routine:
    ButtonState=0
    IF Switch=1 Then ButtonCnt=0

    IF Switch=0 Then
    While Switch=0
    Pause 250
    ButtonCnt=ButtonCnt+1

    IF ButtonCnt=ButtonHeld Then
    ButtonState=2
    Return
    EndIF
    Wend

    IF ButtonCnt<ButtonHeld Then ButtonState=1
    EndIF
    Return
    Last edited by DynamoBen; - 12th August 2006 at 18:44.

  14. #14
    Join Date
    Jun 2005
    Location
    Germany
    Posts
    6

    Question Button code doesn't work

    Say hello to everyone,

    where is the fault in this example:


    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

    I have this Sample code compiled and get this error message:

    ERROR Line 18: Bad expression or missing THEN, (Button_01.php)

    See attachment

    I am here new and am pleased about every help.

    Konrad
    Attached Images Attached Images  

  15. #15
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,542

    Post

    Hi, Konrad

    I used such a "multi role" button simply by using the BUTTON Command in a loop...

    the example is here,

    Code:
    '*****************************************************************************
    'Servotest 84 D'après Elektor
    '*****************************************************************************
    '
    '16F84A à 20 Mhz
    
    ' Barregraph 7 leds sur PortB
    ' résolution variable 2-6-20 µS
    ' Mémorisation réglage " moyen"
    
    @  __config _HS_OSC & _WDT_ON & _CP_ON
    
    DEFINE OSC 20 ' 
    DEFINE BUTTON_PAUSE 18
    
    Signal	var PortA.0
    Writeok	var PortA.1 ' Indicateur mode : 0 = manuel 1 = Cycle
    Up 		var PortA.2	' Rotation à Droite
    Down 	var PortA.3 ' Rotation à gauche
    Prog 	var PortA.4 ' Bouton mémorisation
    
    pos 	var Word
    posn 	var Word
    
    compte	var Byte
    dir 	var Byte
    delay	var Byte
    N		var Byte
    
    PORTA 	= 0
    PORTB 	= %00001000 'PortB.7 libre, Led centrale allumée.
    
    TRISA 	= %00011100
    TRISB 	= %00000000
    
    
    READ 1, Posn.HighByte
    READ 2, Posn.LowByte
    
    IF posn = $FFFF OR posn < 750 OR posn > 2250 THEN posn = 1500
    pos = posn
    
    '*****************************************************************************
    mainloop:
    
    Writeok = 0
    
    delay = 0
    
    button Up, 		0, 255, 0, delay, 1, upbutton
    button Down, 	0, 255, 0, delay, 1, dwnbutton
    button Prog, 	0, 255, 0, delay, 1, Program
    
    Gosub Outsig
    PAUSE 18
    compte = 0
    
    Goto Mainloop
    
    
    '*****************************************************************************
    upbutton:
    
    IF Down = 0 THEN 
    
    	Pos = posn
    	Goto Jump1
    	
    Endif
    
    	Compte = compte + 1
    	
    	Select Case Compte
    	
    		Case 255
    			Compte = Compte-1
    			N = 10
    			
    		Case is > 50
    			N = 10
    				
    		Case is > 15 
    		 	N = 3
    		 	
    		Case else
    			N = 1
    			
    	End Select
    	
       	pos = pos + 2*N
       
       	if pos > 2250 then  pos = 2250
      
    Jump1:
    
    For delay = 1 to 9	
    
    	Gosub Outsig
    	Pause 18
    
    Next delay
    
    	Gosub Outsig
    
    Goto mainloop
    
    
    '*****************************************************************************
    dwnbutton:
    
    IF Up = 0 THEN 
    
    	Pos = posn
    	Goto Jump2
    	
    Endif
    
    	Compte = compte + 1
    	
    	Select Case Compte
    	
    		Case 255
    			Compte = Compte - 1
    			N = 10
    			
    		Case is > 50
    			N = 10
    			
    		Case is > 10 
    		 	N = 3
    		 			
    		Case else
    			N = 1
    			
    	End Select
    	
       	pos = pos - 2*N
       
       	if pos < 750 then pos = 750
       	 
    Jump2:
    	
    For delay = 1 to 9	
    
    	Gosub Outsig
    	Pause 18
    
    Next delay
    
    	Gosub Outsig
    
     Goto mainloop
     
    
    '*****************************************************************************
    Program:
    
    Compte = 0
    
    Test: 
    
    IF Prog = 0 Then 
    	
    	compte = compte + 1
    	Gosub Outsig
    	Pause 18
    	
    	IF Compte > 250 THEN Compte = 250: Goto Test
    	IF Compte >= 80 THEN WriteoK = Compte .4 : Goto Test
    	IF Compte >= 20 THEN WriteoK = Compte .2
    	
    	Goto Test		'Attendre relâchement bouton ...
    	
    Endif	
    	
    	IF Compte > 250 OR Compte < 20 Then mainloop
    	
    	IF Compte >= 80 Then
    	 
    		pos = 1500 
    		Goto Save	'remise au Neutre
    
    	Endif	
    
    					'Position "moyenne"
    
    
    Save:
    
    WRITE 1, Pos.HighByte			' 10ms
    WRITE 2, Pos.LowByte			' 10ms
    
    	Posn = pos
    	Gosub Outsig
    
    For delay = 1 to 25
    	
    	WriteoK = 1
    	Gosub Outsig
    	Pause 18
    	
    Next Delay
    	
    	Goto mainloop
    
    
    	
    '*****************************************************************************
    Outsig:
    
    Select Case pos			'Allumage Bargraph
    
    	Case 750
    	
    		PortB = %01100001
    
    	Case is <= posn - 635
    	
    		PortB = %01000000
    		
    	Case is <= posn - 519
    	
    		PortB = %01100000
    		
    	Case is <= posn - 404
    	
    		PortB = %00100000
    		
    	Case is <= posn - 288
    	
    		PortB = %00110000
    		
    	Case is <= Posn - 173	
    	
    		PortB = %00010000
    		
    	Case is <= Posn - 58
    	
    		PortB = %00011000
    		
    	Case is <= Posn
    	
    		PortB = %01001000
    		
    '*****************************************************************************		
    	Case posn					' Position centrée
    	
    		PortB = %01001001
    '*****************************************************************************
    			
    	Case is <= posn + 58
    	
    		PortB = %00001001
    		
    	Case is <= posn + 173
    	
    		PortB = %00001100
    		
    	Case is <= posn + 288
    	
    		PortB = %00000100
    	
    	Case is <= posn + 404
    	
    		PortB = %00000110
    			
    	Case is <= posn + 519
    	
    		PortB = %00000010
    		
    	Case is <= posn + 635
    	
    		PortB = %00000011
    		
    	Case is < posn + 750
    	
    		PortB = %00000001
    		
    	Case 2250
    	
    		PortB = %01000011
    		
    END Select
    		
    Low Signal
    Pulsout Signal, pos /2		'Envoi Signal servo
    
    RETURN
    
    END

    The "important" sections have been Highlighted ...

    Here, the more the pressing UP and DOWN buttons speed up the 'count speed' ... pressing "prog" permits to choose beetween options ...
    Note WriteOk is a led that shows the delay increasing value when pushing the button ...

    Alain
    Last edited by Acetronics2; - 15th January 2008 at 12:58.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  16. #16
    Join Date
    Jun 2005
    Location
    Germany
    Posts
    6

    Post

    Hi, Alain,

    thanks for the fast reaction and the Code sample.

    I would like to build a "One Button Dimmer"

    1. Short Press Button T1: Toggle LED1 on/off or off/on.

    2. Long Press Button T1: Ramp the Light von LED1 up or Ramp the Light down depending on the one last "Long Press", Ramp direction toggle every "Long Press".

    3. Before power off store the last Ramp value

    See the schematic in the attachment

    Every help is welcome,

    Konrad
    Attached Images Attached Images  

  17. #17
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,542

    Talking Slb 0587

    Hi, Vtt

    A look Here, may be ...

    http://www.electronique-diffusion.fr...lb0587&x=2&y=8

    ...

    some chips still on the market !!! ... and in my drawers ... LOL !

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

Similar Threads

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

Posting Permissions

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