PDA

View Full Version : PBP IF,THEN help



paulcox82
- 22nd September 2009, 21:19
I am writing some code for a PIC16F648A using PicBasic Pro. The idea for the circuit is for the PIC to monitor 6 comparators. The comparators go high based on the angular position of a potentiometer. The comparators are set up in 15 degree increments spanning 45 degrees to each side of center.

The circuit is to activate an LED and flash it when either 45 degree limit is reached. This portion of the code works correctly.

The other function of the code is to drive a motor to return the potentiometer to center. The idea is for the PIC to look at which comparator is active, drive the motor accordingly and stop at the 15 degree from center mark. I was then going to use a timed event to get it close to center. I cannot reach exact center due to potentiometer hysterisis. That is OK.

I believe there is an issue with my If,THEN statements. I have limited experience using them. When I activate the button to command the centering function, I get a latching voltage that will not go low until the other extreme limit is reached, not at 15 degrees as it should.


Here is my code:

TRISA=%11111000 'make A0, A1 & A2 outputs
TRISB=%11101111 'make B0, B1, B2, B3, B5, B6 & B7 inputs

CCWDRV var PortA.0 'change port name
CWDRV var PortA.1 'change port name
LED var PortA.2 'change port name
CNTR var PortB.0 'change port name
PT1 var PortB.7 'change port name
PT2 var PortB.6 'change port name
PT3 var PortB.5 'change port name
PT4 var PortB.3 'change port name
PT5 var PortB.2 'change port name
PT6 var PortB.1 'change port name


cycle:

if (PT1=0) and (PT2=0) and(PT3=0) and(PT4=0) and(PT5=0) and (PT6=0) and (CNTR=0) Then '000 000 right stop
low LED
pause 10
high LED
pause 500
low LED
pause 500
goto cycle
endif

if (PT1=1) and (PT2=1) and(PT3=1) and(PT4=1) and(PT5=1) and(PT6=1) and (CNTR=0) Then '111 111 left stop
low LED
pause 10
high LED
pause 500
low LED
pause 500
goto cycle
endif

if (PT1=0) and (PT2=0) and(PT3=0) and(PT4=0) and(PT5=0) and(PT6=0) and (CNTR=1) Then '000 000 center from right stop
low LED
pause 10
high CCWDRV
gosub CCWCENTER 'go to sub-routine to center from right
goto cycle
endif

if (PT1=1) and (PT2=1) and(PT3=1) and(PT4=1) and(PT5=1) and(PT6=1) and (CNTR=1) Then '111 111 center from left stop
low LED
pause 10
high CWDRV
gosub CWCENTER 'go to sub-routine to center from left
goto cycle
endif

if (PT1=1) and (PT2=0) and(PT3=0) and(PT4=0) and(PT5=0) and(PT6=0) and (CNTR=1) Then '100 000
low LED
pause 10
high CCWDRV
gosub CCWCENTER 'go to sub-routine to center from right
goto cycle
endif

if (PT1=1) and (PT2=1) and(PT3=0) and(PT4=0) and(PT5=0) and(PT6=0) and (CNTR=1) Then '110 000
low LED
pause 10
high CCWDRV
gosub CCWCENTER 'go to sub-routine to center from right
goto cycle
endif

if (PT1=1) and (PT2=1) and(PT3=1) and(PT4=1) and(PT5=0) and(PT6=0) and (CNTR=1) Then '111 100
low LED
pause 10
high CWDRV
gosub CWCENTER 'go to sub-routine to center from left
goto cycle
endif

if (PT1=1) and (PT2=1) and(PT3=1) and(PT4=1) and(PT5=1) and(PT6=0) and (CNTR=1) Then '111 110
low LED
pause 10
high CWDRV
gosub CWCENTER 'go to sub-routine to center from left
goto cycle
endif

GOTO cycle

CCWCENTER
if (PT1=1) and (PT2=1) and(PT3=1) and(PT4=0) and(PT5=0) and(PT6=0) Then
low CCWDRV 'stop motor at 111000 position
high CCWDRV 'start motor for last leg of travel
pause 1000 'run time to go from 15 degrees to center CCW
low CCWDRV
endif
return

CWCENTER
if (PT1=1) and (PT2=1) and(PT3=1) and(PT4=0) and(PT5=0) and(PT6=0) Then
low CWDRV 'stop motor at 111000 position
high CWDRV 'start motor for last leg of travel
pause 1000 'run time to go from 15 degrees to center CW
low CWDRV
endif
return

end


Thank you for the help,
Paul

mackrackit
- 22nd September 2009, 21:50
Sometimes a bunch of ANDs will cause some trouble.
Might try just reading the port
if porb = %00000000 then

Dave
- 23rd September 2009, 11:29
paulcox82, I notice that you don't wait for the motor to stop before you are telling it to go again.

if (PT1=1) and (PT2=1) and(PT3=1) and(PT4=0) and(PT5=0) and(PT6=0) Then
low CCWDRV 'stop motor at 111000 position
high CCWDRV 'start motor for last leg of travel

and in the statement,

if (PT1=1) and (PT2=1) and(PT3=1) and(PT4=0) and(PT5=0) and(PT6=0) Then
low CWDRV 'stop motor at 111000 position
high CWDRV 'start motor for last leg of travel

Why is that? In the time it takes to execute the low statement which is probably in the range of a few uS. the output port is being told to go high once again... Your code will probably overshoot the limit..

Dave Purola,
N8NTA

paulcox82
- 23rd September 2009, 15:50
I will modify the AND condition statements and include a 100ms pause between motor movemnts.

Thanks for the help.

paulcox82
- 24th September 2009, 00:00
I removed the "AND" functions and replaced them with direct port readings and added 100ms delays between motor commands. I have also added a command to set the inputs to digital. The problem still persists, though my memory usage has greatly reduced.

Anybody have any other ideas that may work to resolve this issue?

It may be the hysterisis of the potentiometer, but I am scratching my head on how to eliminate this in code as each comparator is set high.

Thanks for the help,
Paul Cox

here is my updated code:

TRISA=%11111000 'make A0, A1 & A2 outputs
TRISB=%11101111 'make B0, B1, B2, B3, B5, B6 & B7 inputs

CCWDRV var PortA.0 'change port name
CWDRV var PortA.1 'change port name
LED var PortA.2 'change port name
CNTR var PortB.0 'change port name
PT1 var PortB.7 'change port name
PT2 var PortB.6 'change port name
PT3 var PortB.5 'change port name
PT4 var PortB.3 'change port name
PT5 var PortB.2 'change port name
PT6 var PortB.1 'change port name

CMCON = 7

cycle:

if PortB=%00000000 then '000 000 right stop
low LED
pause 50
high LED
pause 500
low LED
pause 500
goto cycle
endif

if PortB=%11101110 then '111 111 left stop
low LED
pause 50
high LED
pause 500
low LED
pause 500
goto cycle
endif

if PortB=%00000001 then '000 000 center from right stop
low LED
pause 50
high CCWDRV
pause 500
gosub CCWCENTER 'go to sub-routine to center from right
goto cycle
endif

if PortB=%11101111 then '111 111 center from left stop
low LED
pause 50
high CWDRV
pause 500
gosub CWCENTER 'go to sub-routine to center from left
goto cycle
endif

if PortB=%00000011 then '100 000
low LED
pause 50
high CCWDRV
pause 500
gosub CCWCENTER 'go to sub-routine to center from right
goto cycle
endif

if PortB=%00000111 then '110 000
low LED
pause 50
high CCWDRV
pause 500
gosub CCWCENTER 'go to sub-routine to center from right
goto cycle
endif

if PortB=%00101111 then '111 100
low LED
pause 50
high CWDRV
pause 500
gosub CWCENTER 'go to sub-routine to center from left
goto cycle
endif

if PortB=%01101111 then '111 110
low LED
pause 50
high CWDRV
pause 500
gosub CWCENTER 'go to sub-routine to center from left
goto cycle
endif

GOTO cycle

CCWCENTER
if PortB=%00001111 then
low CCWDRV 'stop motor at 111000 position
pause 1000 'change to 250ms after debugging
high CCWDRV 'start motor for last leg of travel
pause 2000 'run time to go from 15 degrees to center CCW
low CCWDRV
endif
return

CWCENTER
if PortB=%00001111 then
low CWDRV 'stop motor at 111000 position
pause 1000 'change to 250ms after debugging
high CWDRV 'start motor for last leg of travel
pause 2000 'run time to go from 15 degrees to center CW
low CWDRV
endif
return

end

mikendee
- 24th September 2009, 04:30
Don't know if it's just a typo, but the sub-routine labels need colons.

CCWCENTER:
CWCENTER:

I don't think they work otherwise

Mike

Dave
- 24th September 2009, 11:39
paulcox82, Is there any dynamic braking on the motor drive circuits? How big is the motor and is there any gearing involved? Where is the pot in relationship to the motor(ie, any gears in between?) I dont beleive 100 milliseconds is enough to stop the motor especially if there is no dynamic braking of the motor itself.. How long does it take for the motor to come to a complete stop after commanding to shut off? This time should be the minimum time for the "off delay" and the travel in degrees should be the minimum for the comparators sensing position... Could you please supply a circuit diagram to better understand the drive?

Dave Purola,
N8NTA

paulcox82
- 25th September 2009, 17:11
Mike,

The missing colons were a typo. Thank you. I added them, but still have the same issue.

Dave,

The motor is a small piezo driven motor that will eventually move through some gearing, but very slowly. On the order of 2 RPM. I am simulating the motor position potentiometer by moving an external pot by hand. I will increase the wait periods between motor movements and let you know the results.

Thanks for the help.
Paul

paulcox82
- 25th September 2009, 17:34
As requested, here is the schematic for the motor controller section.

-Paul

comwarrior
- 25th September 2009, 22:57
I can't help but think your solution is overly complecated...

if i got you right you've got POT's setup (6 i believe?) to measure some sort of angles ( :confused: ) and feed these into a comparator which i'm assuming has some sort of reference pot so that you can tune it to the angle you want.
Your then reading the output from your comparators from your pic and controlling a set of motors...

Far too complecated...

if i may, can i surgest a more acurite way...

Something like a pic16F877A has 8 analogue ports that can read a POT directly...
So, use 10K or 100K pots, connect one end of pot to +5V the other to ground and the middle pin goes to your ADC port (acts as a voltage devider)...
In the program you read the ADC, if it's anything other than 2.5volts (50% of the ADC max value) then it's off center and you can take action directly with the pic...
You will find this method much more precise as it will measure less than 1 deg off center...

Also, if you are measuring say pitch and roll, you therefor only need two pots and 4 outputs (2 per motor)...

I'f i've got what your trying to do completely wrong then tell me...

:edit
Actually, the pic your using has 4 analogue lines...

Dave
- 27th September 2009, 20:08
paulcox82, comwarrior beat me to the final suggestion.. Why not use the internal A/D and just read the pot position directly. This way you can eliminate all of the comparators and hystorisis involved with them. That way you can place different limits on the position of the actuator and possibly in the future make the output PWM controlled with a PID closed loop. The bang,bang approch must account time wise for the braking and acceleration of the motor and also different loads on the actuator. This can be solved with the use of a PID control loop and PWM control of the actuator.. There are quite a few examples here on the forum. Type in the keywords Motor PWM and PID....

Dave Purola,
N8NTA