PDA

View Full Version : Reading if Pin is High or Low?



Spindle
- 31st July 2005, 08:34
Hey guys/gals.

I am working on a project that involved an SPDT switch. I have the middle of the switch wired to a 5volt source and the other two wired to PORTB.5 and PORTB.7. What I want to do is check if PORTB.B or PORTB.7 goes high so then I can tell my PIC to drive my motor. PORTB.5 will be to drive my motor forward and PORTB.7 is to drive my motor reverse. Is there something similar to.

if PORTB.5 = HIGH Then?

Thanks in advanced.

- Matthew

Art
- 31st July 2005, 08:37
yes, it's
IF portb.5 = 1 THEN 'check if portb.5 is high

Cheers, Art.

mister_e
- 31st July 2005, 08:52
Be sure you place a pull down resistor on both PORTB pins
Be sure your pin is define as input with the TRIS setting too

my 2 cents... as always


TRISB.5=1

IF PORTB.5 THEN ' do the same as IF PORTB.5=1 THEN
' do something here
ENDIF


OR, if your PIC have some A/D built in, you can use one channel to read your switch and do all the according stuff on 1 pin. You just need few resistors.
something like this...
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=385&stc=1">

once it's done you use a snip of code like this


ADCIN 0,ForwardReverse
IF ForwardReverse<110 then
Gosub MotorReverse
ENDIF

IF ForwardReverse>140 then
Gosub MotorForward
ENDIF

110 and 140 are arbitrary value. Could work as is, but test it before. Set up a 8 bit A/D conversion.

Spindle
- 31st July 2005, 09:06
hrmm, something isn't right...

[code]

CMCON = 7 ' Disable analog comparator
TRISA = %11110110 ' set PORTA to input
TRISB = %11110000 ' set PORTB to output
DEFINE HSER_BAUD 9600 'send serial data at 2400 baud

UP VAR PORTB.5
DOWN var PORTB.7
FM VAR PORTB.2

POSITION var word 'Position value
VELOCITY var word 'Average velocity value
FUNCTION var word 'Function register
I var byte 'Loop variable

TRISB.5 = 1
TRISB.7 = 1

MAIN:

if UP THen
serout FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
serout FM,T9600,["P01 270000", CR, LF] 'Send MOVETO_ABSOLUTE command

for I = 1 to 100
pause 25
serout FM,T9600,["R01 00",CR,LF]
serout FM,T9600,["R01 14",CR,LF]
next
endif

if DOWN THEN
serout FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
serout FM,T9600,["P01 0", CR, LF] 'Send MOVETO_ABSOLUTE command

for I = 1 to 100
pause 25
serout FM,T9600,["R01 00",CR,LF]
serout FM,T9600,["R01 14",CR,LF]
next
endif

goto MAIN

END

[code/]

I am trying to see which pin is high, RB7 or RB5 and then send the right command to the motor driving circuit. No movement however :\

mister_e
- 31st July 2005, 09:27
CMCON = 7 ' Disable analog comparator
TRISA = %11110110 ' set PORTA to input
TRISB = %11110000 ' set PORTB to output

UP VAR PORTB.5
DOWN var PORTB.7
FM VAR PORTB.2

POSITION var word 'Position value
VELOCITY var word 'Average velocity value
FUNCTION var word 'Function register
I var byte 'Loop variable
T9600 con 2 ' <== Baudrate definition in case you don't use
' INCLUDE "modedefs.bas" line

MAIN:
if UP THen
serout FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
serout FM,T9600,["P01 270000", CR, LF] 'Send MOVETO_ABSOLUTE command

for I = 1 to 100
pause 25
serout FM,T9600,["R01 00",CR,LF]
serout FM,T9600,["R01 14",CR,LF]
next
endif

if DOWN THEN
serout FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
serout FM,T9600,["P01 0", CR, LF] 'Send MOVETO_ABSOLUTE command

for I = 1 to 100
pause 25
serout FM,T9600,["R01 00",CR,LF]
serout FM,T9600,["R01 14",CR,LF]
next
endif

goto MAIN

The DEFINE HSER_BAUD 9600 'send serial data at 2400 baud have nothing to do with SEROUT, AND i don't see any crystal speed declaration. @9600 bauds with SEROUT, 8MHZ or higher is highely recommended.

Spindle
- 31st July 2005, 09:38
I am using a PIC16F628 if that helps. It still isn't working for some reason. When i flip the switch nothing happend, but then the motor starts turning in like 30-40 secs. Its weird hehe. Its also 3:40am and getting late. I'll look at it again with fresh eyes in the morning but any more help is still apreciated.

mister_e
- 31st July 2005, 09:50
well i don't see any line that show you send any kind of signal to your motor... can you post your whole new and fresh code???

With fresh eyes... do you see your pull-down resistor attach to the UP, DOWN pins???

Spindle
- 31st July 2005, 09:57
No resisters are attached to the UP and DOWN pins. Does that mean their value is just floating? What value should these resistors be?

mister_e
- 31st July 2005, 10:05
YEAH the value is floating and your PIC is between two value, and he see some pink elephant around and he's afraid of.

Value should be bellow 10K.

Spindle
- 31st July 2005, 10:11
lol alright thanks. I really apreciate your help mister_e. I must have missed your post about the resistors when I was responding. I'll try it in the morning. Thanks again.

mister_e
- 31st July 2005, 10:17
No problem. Good night !!!

Melanie
- 31st July 2005, 11:05
In conventional design, you would never apply your +5v to your switch. The +5v should NEVER leave your PCB, or be connected to any unnescessary component. It's valuable, you don't want to corrupt it, or add noise to it, because it could affect the operation of your PIC.

A better connection would be to have the COMMON of your switch going to Vss (0v), with either side to your PIC pins as before. You then only need a SINGLE Pull-UP resistor on each pin going to +5v. 10K is a good value.

The control logic is then INVERTED... ie the pin goes LOW when there's a switch on it... eg...

TRISB.5=1
TRISB.7=1

Loop:
If PortB.5=0 then goto DriveForward
If PortB.7=0 then goto DriveReverse
Goto Loop

Since you're experimenting, why not dispsense with the external Resistors and invoke the INTERNAL WEAK PULL-UPS that exist on PortB?

TRISB.5=1
TRISB.7=1
OPTION_REG.7=0

Loop:
If PortB.5=0 then goto DriveForward
If PortB.7=0 then goto DriveReverse
Goto Loop

Look in the PICs Datasheet to find the OPTION Register to see what that instruction does.

Spindle
- 31st July 2005, 19:02
A better connection would be to have the COMMON of your switch going to Vss (0v), with either side to your PIC pins as before. You then only need a SINGLE Pull-UP resistor on each pin going to +5v. 10K is a good value.

On the switch its three prong. The middle prong is going to ground. The one side of it is going to PORTB.5 and the other side is going towards PORTB.7. You said put a Pull-UP resisor on the ones going to PORTB.5 and PORTB.7. That makes sense, but you said going to +5v? I don't understand that... Can you please clairfy, thanks.

Spindle
- 31st July 2005, 19:48
This is my current code

@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT ' system clock options
@ DEVICE pic16F628, WDT_ON ' watchdog timer
@ DEVICE pic16F628, PWRT_ON ' power-on timer
@ DEVICE pic16F628, MCLR_OFF ' master clear options (internal)
@ DEVICE pic16F628, BOD_ON ' brown-out detect
@ DEVICE pic16F628, LVP_OFF ' low-voltage programming
@ DEVICE pic16F628, CPD_OFF ' data memory code Protect
@ DEVICE pic16F628, PROTECT_OFF ' program code protection

include "modedefs.bas"

UP VAR PORTB.5
DOWN var PORTB.7
FM VAR PORTB.2


POSITION var word 'Position value
VELOCITY var word 'Average velocity value
FUNCTION var word 'Function register
I var byte 'Loop variable
T9600 con 2

LF con 10 'Linefeed ASCII value

TRISB.5 = 1
TRISB.7 = 1
'OPTION_REG.7 = 0

'WRITE command to FUNCTION register, and enable velocity limit mode
'
serout FM, T9600, ["W01 03 64", CR, LF] 'Enable velocity limit mode
pause 100
serout FM, T9600, ["R01 03", CR, LF]
pause 20

MAIN:
IF UP = 0 THEN
serout FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
serout FM,T9600,["P01 270000", CR, LF] 'Send MOVETO_ABSOLUTE command
ENDIF

IF DOWN = 0 THEN
serout FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
serout FM,T9600,["P01 0", CR, LF] 'Send MOVETO_ABSOLUTE command
ENDIF

goto MAIN
End

I am not using the internal resistors. I am using external 10k ones on the PORTB.5 and PORTB.7 lines
P.S. Will someone teach me how to do the code tag!

Melanie
- 31st July 2005, 19:53
Each side of the switch goes to the Port pin. There is a Resistor, one end on the Port pin, the other is nailed to +5v. That's why they are called Pull-UP - they pull UP to +5v when the pin is unused. When you close the switch, it drops the pin voltage to 0v.

Spindle
- 31st July 2005, 20:26
Melanie,

I am sorry for my newby-ness (new word). I am not an Electrical Engineer just a highschool student working on a summer project.

Right now i have the center of the switch going to ground. Then the sides of the switch going through a 10k ohm resistor, then to PORTB.5 and PORTB.7 respectively. I also have a 5 volt bus. Does anything have to be connected to it? Like a jumper from PORTB.5|7 to 5 volt as well?

mister_e
- 31st July 2005, 20:41
A image is always welcome i guess
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=388&stc=1">

OR, as Melanie suggested, remove those pull-up resistor, and add

OPTION_REG.7=0
at the top of your code. This will enable the internal pull-up.
about VB code, tags and blah blah click here (http://www.picbasic.co.uk/forum/misc.php?do=bbcode)

Spindle
- 31st July 2005, 21:32
Thanks you two! It works now. I cound't have done it with out yah!

Spindle
- 1st August 2005, 03:13
Ok the only problem is now if I switch it one way and then switch it to the middle the motor still goes because I guess the command is still being sent to the motor driving circuit. There is however a _break pin you can control. See attached image. Other than how its wired from the diagram mister_e posted the ground that comes off my chip goes to the switch and then to PIN 12. This drives it low and disables the H-Bridge on circuit. The problem when the switch is turned left or right for forward and reverse movement nothing happens because _break is still being driven low. I can't think how I can make it high when the switch is left or right. Maybe instead of connecting the pin to the ground, connect it to another portb pin and when its switch left make that pin high but i don't think to 5 volt supplies will work on a switch :P again I am no electrical engineer but am trying my hardest. Any help is apreciated. Please check out the picture I basically want to do that with the break switch but only when the SPDT switch is in the middle. When its to the left and right have _break go back high.

mister_e
- 1st August 2005, 03:54
can you provide the whole datasheet or a link of this specific motor controller???

Spindle
- 1st August 2005, 03:57
Motion Mind Module

http://www.solutions-cubed.com/solutions%20cubed/MM1_2005.htm

http://www.solutions-cubed.com/solutions%20cubed/Products%20Page/Downloads/MOTMDS_4.pdf

Thanks!

mister_e
- 1st August 2005, 04:16
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=390&stc=1">
Well i guess you could fix about everything by reading the actual motor position and tell him to go to the readed position.

well to make it more clear... here's a snip of the idea


MAIN:
IF (UP = 0) AND (DOWN=1) THEN
serout FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
serout FM,T9600,["P01 270000", CR, LF] 'Send MOVETO_ABSOLUTE command
ENDIF

IF (DOWN = 0) AND (UP = 1) THEN
serout FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
serout FM,T9600,["P01 0", CR, LF] 'Send MOVETO_ABSOLUTE command
ENDIF

if (DOWN = 1) AND (UP = 1) then
' SERIN motor position
' SEROUT motor position to make him stop
endif

goto MAIN
End
it's an idea. Let us know!

mister_e
- 1st August 2005, 04:40
OR... use a variable and increment/decrement it on each IF THEN statement... the only thing... i don't know how the movement will be produced... probably it will not going to be purely smooth.

try


PositionHB var byte
PositionLB var word
T9600 con 84 ' 9600 bauds

MAIN:
IF (UP = 0) AND (DOWN=1) THEN
serout2 FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
if positionlb < 9999 then
if positionhb != 27 then
positionlb = positionlb+1
endif
else
positionlb = 0
if positionhb < 27 then
positionhb = positionhb+1
endif
endif

serout2 FM,T9600,["P01 ",dec2 positionhb,dec4 positionlb,_
CR, LF] 'Send MOVETO_ABSOLUTE command
ENDIF

IF (DOWN = 0) AND (UP = 1) THEN
serout2 FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
if positionlb then
positionlb = positionlb - 1
else
positionlb = 9999
if positionhb then
positionhb = positionhb-1
endif
endif

serout2 FM,T9600,["P01 ",dec2 positionhb,dec4 positionlb,_
CR, LF] 'Send MOVETO_ABSOLUTE command
ENDIF

goto MAIN
End

there's probably something i missed in the math condition but, this have to work... well i guess.

Spindle
- 1st August 2005, 04:51
thanks mister_e I am gonna try your first thing, this is for a motorized shade application so the next step is to have the position constantly store the absolute position in the PICs eeprom incase the main power is cut it won't be confused when power is applied again. Thats aways off, first thing is first, I shall try your solution!

Spindle
- 1st August 2005, 04:59
I tried your first solution and no go. When you flip the switch one way it still goes forward and when you flip the switch the other way it still goes reverse. But if you were to flip it from left to center it would still spin and NOT shut off. Same if you were to flip it from right to center. It would still move (the motor) until it gets to that absolute position. Some how I have to ustilize that _break pin because brining it low disables the H-Bridge. I have to do that somehow where if the switch is to the left or right its not pulled low. Mister E. It is wired up like your diagram in your previous posts.

mister_e
- 1st August 2005, 05:05
now it's me that need to sleep :)

what about the second option now???

Spindle
- 1st August 2005, 05:12
Second Solution doesn't work eaither.

The problem is i think the code is right (your first solution) its just mechanically/electrically/wirely I need your help on how I can wire up the SPDT switch to go low when its in the center disableing the H-Bridge. the _brake line would be low. But when the switch is thrown left or right the _break line can not be low so the H-Bridge is reenable. Right now it is wired up like your schematic.

mister_e
- 1st August 2005, 14:03
Well i this could be as easy as..


MAIN:
IF (UP = 0) AND (DOWN=1) THEN
serout FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
serout FM,T9600,["P01 270000", CR, LF] 'Send MOVETO_ABSOLUTE command
ENDIF

IF (DOWN = 0) AND (UP = 1) THEN
serout FM, T9600 ,["W01 01 200", CR, LF] 'Write velocity limit value
serout FM,T9600,["P01 0", CR, LF] 'Send MOVETO_ABSOLUTE command
ENDIF

if (DOWN = 1) AND (UP = 1) then ' <=== Switch is in central POS
LOW Break_Pin
endif

goto MAIN
End
Just connect a PIC i/o directly to the controller BREAK pin... this have to work... i guess.

or if you feel to add extra parts...
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=392&stc=1">
Both should work now!

Spindle
- 1st August 2005, 17:36
mister_e. You Sir are brilliant! I went with your first method the only dif is to make it work i brought break_pin HIGH for the first two IF statements!

mister_e
- 1st August 2005, 17:39
yeah of course OR



if (DOWN = 1) AND (UP = 1) then ' <=== Switch is in central POS
LOW Break_Pin
else
HIGH Break_pin
endif

BTW great to know it's working now :)