Single button function


Closed Thread
Results 1 to 40 of 41

Hybrid View

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


    Did you find this post helpful? Yes | No

    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.

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


    Did you find this post helpful? Yes | No

    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    

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


    Did you find this post helpful? Yes | No

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

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


    Did you find this post helpful? Yes | No

    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?

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


    Did you find this post helpful? Yes | No

    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

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


    Did you find this post helpful? Yes | No

    Default

    Duh! <smacks forehead> my switch routine had a LCD clear command in it.

  7. #7
    Join Date
    Mar 2006
    Posts
    41


    Did you find this post helpful? Yes | No

    Default syntacks(",)

    Good day

    I'm a picbasic newbie i'd like to ask these syntaxes do?

    AMPMFlag=AMPMFlag^1 '>>>>>>>>>>>>>>>>>>>what does this do?

    Lc var byte [15]
    For i = 0 to 15 : read i, b0:if b0 = 0 then
    lookup i,[1,2,3,11,4,5,6,11,7,8,9,10,11,12,13,14], b0
    Lc(i)=b0 '>>>>>>>>>>>>>>>>>>>>>>>>>>>what does this do?
    goto Address

    I would gladly appreciate for any response
    thanks
    ryan

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


    Did you find this post helpful? Yes | No

    Default

    AMPMFlag=AMPMFlag^1 '>>>>>>>>>>>>>>>>>>>what does this do?

    AMPMFlag is a BIT variable.
    All this does is toggle the BIT variable, if it was zero it will be set to 1, if it was 1 it will be set to 0. It is the equivallent of...

    IF AMPMFlag=0 then
    AMPMFlag=1
    else
    AMPMFlag=0
    endif



    Lc var byte [15]
    For i = 0 to 15 : read i, b0:if b0 = 0 then
    lookup i,[1,2,3,11,4,5,6,11,7,8,9,10,11,12,13,14], b0
    Lc(i)=b0 '>>>>>>>>>>>>>>>>>>>>>>>>>>>what does this do?

    Lc is a BYTE array 15 elements deep in the range Lc(0) to Lc(14)
    You are loading Lc at array location i with the contents of variable b0

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 : 2

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