PDA

View Full Version : Push button on PIC16F887



menta
- 20th June 2008, 22:03
I have the PICkit 2 express debug
I'm having problems with getting the push button switch.
Can someone post a code for getting the button pressed?

Thanks.

skimask
- 20th June 2008, 22:06
I have the PICkit 2 express debug
I'm having problems with getting the push button switch.
Can someone post a code for getting the button pressed?

Thanks.

There is code for that type of thing right on the CD that came with the package; ready made; ready to be sent directly to the board.

Code to press button:
1) Note position of hand.
2) Hold hand in mid air.
3) Extend one finger.
4) Aim for button on PICKit2 Express circuit board.
5) Close distance between finger tip and button on PICKit2 Express circuit board.
6) Continue to close distance until contact is made between fingertip and aforementioned circuit board.
7) After contact is made, depress said button.
8) Continue to depress button until decision is made to release button.
9) Upon release decision, retract said fingertip until contact is no longer maintained.
10) Further position fingertip to a comfortable distance from button.
11) Retract one finger.
12 ) Replace hand to position noted in step 1.

That should just about do it.
Did I forget anything?

menta
- 20th June 2008, 22:45
I need it in basic.
The code in the cd is asm.
But thats ok.
I have managed.
Thanks.

gringobomba14
- 20th June 2008, 23:19
if PIN =1 then gosub BUTTON_PRESSED

PINisthe port you are using (PORTD.2 for example) BUTTON_PRESSED is what you want to happen after the button has been pressed. What do you want it to do?what code have you written already???

menta
- 21st June 2008, 01:42
SW1 is connected to PORTB.0
But you must enable its analog :
ANSELH = %00000000

menta
- 21st June 2008, 15:15
I have improved the code of this source:
http://www.picbasic.co.uk/forum/showthread.php?t=2129
Still no optimization, but it looks great.
I programmed it so when in setup mode (clock setting) to increment the time, only when button is up, it will increment, but there is a delay in display.

Menta.


INCLUDE "modedefs.bas"

TRISB=$01 'GP1 = input for button
ANSELH = %00000000 ' Set PortA Analogue
OPTION_REG=%00000111 'weak pullups on, TMRO prescale = 256
INTCON=0 'interrupts off
OPTION_REG.7=1 'Turn off weak pullups
TMR0=0 'Reset TMRO
INTCON.2= 0 'Clear TMRO overflow flag

HzTimer VAR Word '1/2 second counter (2 Hz)

HH VAR Byte ' Hours 1-12
MM VAR ByTE ' Minutes 0-59
SS VAR Byte ' Seconds 0-59
X VAR Byte ' temp variable
B0 var byte
col VAR Bit ' colon 1=on, 0=0ff
HOLD var byte


HzTimer=$7A12 'for 1/2 Sec
HH=0:MM=0:SS=0:col=0 'initial conditions

Pause 2000 'settle Time for Serial LCD

' ************************************************** ************
'SET INITIAL TIME WITH PUSH BUTTON (PART 1 of Program)

Serout PORTB.1,6,[254,1]
Pause 100

SEROUT PORTB.1,6,[72,72,58,77,77,58,83,83] 'Display HH:MM
;goto Main ' Skip setup
WHILE PORTB.0=1 'Wait here until user pushes button
button PORTB.0,0,255,0,B0,1,SetHH
PAUSE 300
SEROUT PORTB.1,6,[254,128,72,72]
PAUSE 300
SEROUT PORTB.1,6,[254,128,32,32]
WEND
PAUSE 150
SEROUT PORTB.1,6,[254,128,48,48]
HOLD=0
SetHH: 'Set hours, HH
while PORTB.0=0 ' check if button is pushed for 3 seconds
pause 1000
FAST:
HOLD=HOLD+1
if HOLD>4 then
HH=HH+1
IF HH=13 THEN
HH=1
ENDIF
IF HH>9 THEN
X=128
ELSE
X=129
ENDIF
if HH<9 then
SEROUT PORTB.1,6,[254,128,32]
endif
SEROUT PORTB.1,6,[254,X,#HH]
pause 150
if PORTB.0=1 then StopFast
goto FAST
endif
StopFast:
wend
if (Hold>2) and (HOLD<4) then setmm
hold=0
IF HH=13 THEN
HH=1
ENDIF
IF HH>9 THEN
X=128
ELSE
X=129
ENDIF
while PORTB.0=1 'wait for key to press again
SEROUT PORTB.1,6,[254,X,#HH]
PAUSE 100
wend
HH=HH+1
goto sethh

SetMM: 'Set hours, MM
hold=0
WHILE PORTB.0=1 'Wait here until user pushes button
PAUSE 150
SEROUT PORTB.1,6,[254,131,77,77]
PAUSE 150
SEROUT PORTB.1,6,[254,131,32,32]
WEND
PAUSE 150
SEROUT PORTB.1,6,[254,131,48,48]
setMM1:
while PORTB.0=0 ' check if button is pushed for 3 seconds
pause 1000
FASTMM:
HOLD=HOLD+1
if HOLD>3 then
mm=mm+1
IF mm=60 THEN
mm=1
ENDIF
IF mm>9 THEN
X=131
ELSE
X=132
ENDIF
if mm<9 then
endif
SEROUT PORTB.1,6,[254,X,#mm]
pause 150
if PORTB.0=1 then StopFastMM
goto FASTMM
endif
StopFastMM:
wend
if (Hold>2) and (HOLD<4) then startloop
hold=0
IF mm=60 THEN
mm=1
ENDIF
IF mm>9 THEN
X=131
SEROUT PORTB.1,6,[254,131,48]
ELSE
X=132
ENDIF
while PORTB.0=1 'wait for key to press again
SEROUT PORTB.1,6,[254,131,48]
SEROUT PORTB.1,6,[254,X,#MM]
PAUSE 100
wend
mm=mm+1
goto setMM1
StartLoop:

' ************************************************** ************
'TIME KEEPING LOOP (PART 2 of Code)

'Requires variables, HH for Hours 1-12, and MM for minutes 0-59
'(HH and MM manually set above in Part 1; SS & col = 0 from above)

Main:
ClockLoop: IF INTCON.2=0 THEN ClockLoop ' Wait for TMRO overflow
INTCON.2=0 'Clear TMRO overflow flag

HzTimer = HzTimer - $1000 'decrement timer

IF HzTimer<$1000 THEN
IF Col=1 THEN 'update time'
SS=SS+1
IF SS=60 THEN
SS=0
MM=MM+1
IF MM=60 THEN
MM=0
HH=HH+1
IF HH=25 THEN
HH=1
ENDIF
ENDIF
IF HH>9 THEN
SEROUT PORTB.1,6,[254,128,#HH,58]
ELSE
SEROUT PORTB.1,6,[254,128,32,#HH,58]
ENDIF
IF MM>9 THEN
SEROUT PORTB.1,6,[254,131,#MM]
ELSE
SEROUT PORTB.1,6,[254,131,48,#MM]
ENDIF
ELSE
; Serout PORTB.1,6,[254,130,58] 'colon on
; Serout PORTB.1,6,[254,133,58] 'colon on
ENDIF
IF SS>9 THEN
SEROUT PORTB.1,6,[254,134,#SS]
ELSE
SEROUT PORTB.1,6,[254,134,48,#SS]
ENDIF
ELSE
; Serout PORTB.1,6,[254,130,32] ' Colon off
; Serout PORTB.1,6,[254,133,32] ' Colon off
ENDIF
Col=Col+1
HzTimer=HzTimer+$7A12
ELSE
'Do something here but must be less than 65,500 instructions
'(e.g., less than 65.5 mSec total time)

ENDIF

GOTO Main
' ************************************************** ************
END

menta
- 21st June 2008, 23:47
Now I need to get interrupt when button is pressed,
can anyone lead to a good example?
I tried some from the examples here, and I understand it need to be set to MPASM, but I get errors and compilation fails.
I get error :"source file path exeeds 62 characters"
I tried those examples http://darreltaylor.com/DT_INTS-14/hello.html

skimask
- 21st June 2008, 23:54
can anyone lead to a good example?
Google?


I tried some from the examples here, and I understand it need to be set to MPASM, but I get errors and compilation fails.
I get error :"source file path exeeds 62 characters"
Put your source file to where the path to that source file doesn't exceed 62 characters.

menta
- 22nd June 2008, 00:01
Put your source file to where the path to that source file doesn't exceed 62 characters.

What?
Is this english ?

skimask
- 22nd June 2008, 00:05
Google?


Put your source file to where the path to that source file doesn't exceed 62 characters.


What?
Is this english ?

Yes...

Put your source file (the file which is your source file, the file you are writing to be compiled/assembled and programmed)

to where the path to that source file (the path being the complete expression of the file itself, for example C:\My Documents\PIC_Source_Code\My_Test_File.PBP)

doesn't exceed 62 characters (the count of the characters in that complete source file path does not exceed 62. The count being less than 62, a number of lesser significance when compared to 62, an amount when compared to 62 comes up short with respect to aforementioned quantity).

I don't know...
Is it english?

Let me try something:
Сложете източник файл, където пътят към този източник на файла не надвишава 62 символа
إسلام أون لاين ملف المصدر الى ان الطريق الى ملف المصدر ان لا تتجاوز 62 حرفا
Put vašeg source file u kojem je put do tog izvora datoteke ne prelazi 62 znakova
Dejte zdrojový soubor, kde se cesta k souboru, že zdroj není vyšší než 62 znaků
Разместите исходный файл, где путь, что исходный файл не превышает 62 символов

Which one works for you?

menta
- 22nd June 2008, 00:10
Well, It must be obvious to one who knows this,.

skimask
- 22nd June 2008, 00:31
Well, It must be obvious to one who knows this,.

Maybe...but...
Plugging those words "Source File Exceeds 62 characters" into the SEARCH up top yields answers.
Amazing isn't it?

menta
- 22nd June 2008, 12:17
I tried search for "source file path exeeds 62 characters' which didn't return anything.
I guess I should have search for less words.

menta
- 22nd June 2008, 15:16
I have managed to use the button as interrupt form this source:
http://darreltaylor.com/DT_INTS-14/hello.html

Is it possible also to get another interrupt for the same button while it is pressed for 2 seconds for example ?

skimask
- 23rd June 2008, 05:00
I tried search for "source file path exeeds 62 characters' which didn't return anything.
I guess I should have search for less words.

That's because exeeds is spelled wrong.

skimask
- 23rd June 2008, 05:01
I have managed to use the button as interrupt form this source:
http://darreltaylor.com/DT_INTS-14/hello.html

Is it possible also to get another interrupt for the same button while it is pressed for 2 seconds for example ?

IF a timer interrupts every 1/10 second, and you want to look for a button being pressed for 2 seconds, then I'd suggest looking at the button during every interrupt and add 1 to a counter. If the counter hits 20, the button is pressed for 2 seconds. If the button is let up when the counter is below 20, then reset the counter to zero.
Simple enough...

menta
- 23rd June 2008, 08:04
Ye, I though about it,
But I use the button as "Rising Edge" so when the button is pressed there is no interrupt yet.

skimask
- 23rd June 2008, 13:31
Ye, I though about it,
But I use the button as "Rising Edge" so when the button is pressed there is no interrupt yet.

I didn't say anything about the button causing the interrupt did I?
If you re-read my post, you'll see that I said that a timer causes an interrupt and the button input is read during that interrupt. Therefore, it doesn't matter if your button pulls a line high or low, or what, as long as you are able to read the state of that pin during the interrupt.

menta
- 24th June 2008, 14:00
Right,
Thanks.

gringobomba14
- 24th June 2008, 21:06
Just a question Menta, why did you set the ports as analogue if you are using them for a switch???

skimask
- 25th June 2008, 03:46
Just a question Menta, why did you set the ports as analogue if you are using them for a switch???

They aren't...
PortA is set for analog...
PortB is set for digital (ANSELH = 0). The comment behind the line in the code a few posts back is technically correct, but slightly misleading.

menta
- 25th June 2008, 07:47
Thats right.