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

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