PDA

View Full Version : Senior project please help



UNFMech
03-16-2010, 01:06 AM
So here is the backround, I have a senior project due in a week and a half and I have been messing around with the Parallax BOE. I am constructing an autonomous waste sorter that must sort glass/plastic/tin-steel/ and aluminum. For sorting the tin-steel(soup can) we have a servo with a magnet attached to an arm that is sweeping under a conveyor belt continuously. For the aluminum we have a proximity inductive sensor wired to the bread board and to a servo arm, such that when the sensor is active the servo door swings open. I need both functions to work at once, aka, the sweeper servo for the tin-steel and the aluminum + sensor setup. Currently I have them both setup, the only problem is that when the sensor actives the door for the aluminum open BUT the sweeper servo stops. I know the problem I am just not very good at programming and PBASIC is still kinda new to me. Any help would be awesome. Below is the current code I am using with pictures.

' {$STAMP BS2}
' {$PBASIC 2.5}


' ---------------[ I/O Definitions ]-------------
PIR PIN 0 'I/O Pin for PIR Sensor
LAR PIN 0


' ---------------[ Variables ]------------------
Setup:

MinVal VAR Word
MaxVal VAR Word
x VAR Word
y VAR Word
z VAR Word
CheckForSensor VAR Word
counter VAR Word
Highest VAR Word
Lowest VAR Word


Lowest=205
Highest=1500
MinVal=205
MaxVal=1600
z=10

' --------------[ Main Program ]-------------------

MAIN:
'Servo Sweeper, just moves from one position back and forth, looping
DO
FOR x=0 TO MaxVal STEP 20
PULSOUT 12, x
PAUSE 5
NEXT

FOR x=MaxVal TO 0 STEP -20
PULSOUT 12, x
PAUSE 5
NEXT
LOOP




Sensor:
DEBUG "Checking for Sensor!" 'checking for sensor
DO
PULSOUT 13, 1100 'returns sensor door to original position
IF PIR = 0 THEN DEBUG "Not Found" 'If sensor isnt sensing anything then servo sweep
'if sensor senses something then open servo door
IF PIR =1 THEN Open

GOSUB Sweep

LOOP
Sweep:

DO
FOR x=0 TO MaxVal STEP 20
PULSOUT 12, x
PAUSE 5
NEXT

FOR x=MaxVal TO 0 STEP -20
PULSOUT 12, x
PAUSE 5
NEXT
RETURN
LOOP


Open:

FOR counter = 1 TO 100
PULSOUT 13, 850
PAUSE 20
NEXT

GOSUB Close



Close:

FOR counter = 1 TO 100
PULSOUT 13, 1100
NEXT

GOSUB Sensor

bill190
03-16-2010, 01:16 AM
The stamps can only do one thing at a time.

Use two stamp boards?

Wolfbrother
03-16-2010, 01:27 AM
Hi,

I don't think you have to use a Servo to sweep the magnet under the conveyor belt to look for steel cans. You could have a continously moving DC motor and just have it oscillate when you turn power on. Otherwise I think you could use the ServoPal to control the servos while your Basic Stamp is doing other things.

Here's the data on the ServoPal http://www.parallax.com/Portals/0/Downloads/docs/prod//robo/ServoPAL_doc.pdf

Mike Green
03-16-2010, 01:32 AM
As bill190 mentioned, a Stamp can only do one thing at a time. It's possible to interleave two or three servo movement loops so one loop drives all the servos and may have time left in the 20ms interval to check one or two sensors. It's much easier to offload the sensor loops to another microcontroller. The Propeller Servo Controller and the ServoPAL are devices that do this. Have a look at their Parallax webstore pages and look at the documentation for them.

By the way, your several "sweep" routines use a pause of 5ms. The servos are actually made to respond to a pause more like 20ms. You can't really move them faster or smoother by shortening the pause time.

You're going to have problems with your program. You're using GOSUB like a GOTO and there is no corresponding RETURN statement. The GOSUB and RETURN have to be matched up. Use a GOTO if that's really what you mean.

W9GFO
03-16-2010, 01:50 AM
You can drive two servos at the same time. Every time you send a command to the sweep servo also send it to the door servo - even though it may not to need to move. Use a sensor subroutine called within the sweep loop to determine if the door pulse needs to be changed.



DO

PULSOUT sweep_servo, sweep_value
PULSOUT door_servo, door_value

GOSUB Sensors ' sensor routine changes door_value if necessary

IF sweep_value => max_value THEN forward = FALSE
IF sweep_value =< min_value THEN forward = TRUE

IF forward = TRUE THEN sweep_value += 5
ELSE sweep_value -= 5
ENDIF

LOOP



Your min and max values for servo pulses should be around 500 and 1000, certainly not zero and 1,600!

You would also need to trim your Senors subroutine down to the absolute minimum, the DEBUG statements will take a lot of time to execute and will cause the servos to be herky-jerky.

Rich H

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The Simple Servo Tester, a kit from Gadget Gangster. (http://www.gadgetgangster.com/206)

Post Edited (W9GFO) : 3/15/2010 6:58:45 PM GMT

Mike Green
03-16-2010, 01:55 AM
Typically, you'd have one master loop and a variable or two that describe the state of the system.


opening con 0
closing con 1
sweeper var bit
sweepPos var word
sweepMin con 205
sweepMax con 1600
gatePos var word
gateMin con 205
gateMax con 1500
loopCnt var nibble
sweepPos = sweepMin
sweeper = opening
gatePos = gateMin
loopCnt = 0
do
pulsout 12,sweepPos
if sweeper = opening
if sweepPos + 20 > sweepMax
sweeper = closing
else
sweepPos = sweepPos + 20
endif
else
if sweepPos - 20 < sweepMin
sweeper = opening
else
sweepPos = sweepPos - 20
endif
endif
pulsout 13,gatePos
if loopCnt > 0
loopCnt = loopCnt - 1
endif
' here your program may check various sensors and make some kinds of decisions about what to do next cycle through the loop
pause 12 ' shorten this delay depending on how much time the above statement take to execute. The typical execution time
' of the loop should take around 20ms, perhaps a little less.
loop


This loop continuously sweeps the servo on pin 12. It also will maintain the position of the servo on pin 13. To open the gate, set gatePos to gateMax. To close the gate, set gatePos to gateMin. It will take a few cycles of the loop for the gate servo to move to the requested position. This can be handled by setting loopCnt to 15 when gatePos is set, then not reacting until loopCnt becomes zero.

------------------

Note change in sweepMax / sweepMin testing.

Post Edited (Mike Green) : 3/15/2010 11:36:37 PM GMT

UNFMech
03-16-2010, 04:43 AM
Awesome, thank you for the quick reply everyone. I am going to mess around with it and let you all know, not knowing this code very well is very frustrating so I'm apologizing for my lack of knowledge on the language in advance lol.

UNFMech
03-16-2010, 06:37 AM
'PULSOUT 13,gatePos
'IF loopCnt > 0 THEN
'loopCnt = loopCnt - 1
'ENDIF
'IF PIR = 1 THEN
'gatePos=gateMax
' FOR counter = 1 TO 50
'gatePos=gaetMin
'ELSE
' gatePos=gateMin
'ENDIF


This code works for the aluminum door, the sweeper servo I am still having trouble with though, the sweeper servo will only stay at the end of the servo range in either direction, I have tried changing the values but am not quite sure what is wrong. The servo sweeper stays at max range then sweeps once and returns to max range and stays there.

Franklin
03-16-2010, 08:34 AM
OK, what code are you using now that it has been changed?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Stephen

UNFMech
03-16-2010, 11:29 PM
I am using Mike Greens code and I just appended on for use of the aluminum door servo. Just can't seem to get the sweeper arm functioning right though.

Franklin
03-17-2010, 01:16 AM
Somebody said...
I am using Mike Greens code and I just appended on for use of the aluminum door servo
Like I said above What code are you using? Please attach it to your post so we can see where you went wrong.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Stephen

UNFMech
03-17-2010, 02:39 AM
PIR PIN 0
MaxVal VAR Word
x VAR Word
opening CON 0
closing CON 1
sweeper VAR Bit
sweepPos VAR Word
sweepMin CON 500
sweepMax CON 1600
gatePos VAR Word
gateMin CON 1100
gateMax CON 800
loopCnt VAR Nib
sweepPos = sweepMin
sweeper = opening


loopCnt = 0
MaxVal = 1600
counter VAR Word

DO
PULSOUT 12,sweepPos
IF sweeper = opening THEN
IF sweepPos + 20 > sweepMax THEN
sweeper = closing
ELSE
sweepPos = sweepPos + 20
ENDIF
ELSE
IF sweepPos - 20 < sweepMin THEN
sweeper = opening
ELSE
sweepPos = sweepPos - 20
ENDIF
ENDIF

PULSOUT 13,gatePos 'Aluminum door servo arm
IF loopCnt > 0 THEN
loopCnt = loopCnt - 1
ENDIF
IF PIR = 1 THEN
gatePos=gateMax
ELSE
gatePos=gateMin
ENDIF

Alright the sweeper is working and the aluminum door arm works but only like once or twice and then stops after the ferrous metal is introduced.

UNFMech
03-17-2010, 04:07 AM
When the only thing that is running (everything else is commented out), this code works flawlessly.

PULSOUT 13,gatePos 'Aluminum door servo arm
IF loopCnt > 0 THEN
loopCnt = loopCnt - 1
ENDIF
IF PIR = 1 THEN
gatePos=gateMax
ELSE
gatePos=gateMin
ENDIF

When introduced with the sweeper arm code its really up in the air if the sensor will activate or not. Sometimes when the sensor is placed right next to the material it will work, but sometimes the sensor just does not read it at all. Something to do with the sensor loop not activating? Individually each code block works perfectly, but when introduced with each other all heck breaks loose and the sensor gets a mind of its own. The base code that I am playing around with is the same as what is posted directly above. Thank You!

Franklin
03-17-2010, 05:33 AM
Your code will only run one time and then stop. Is that what you want?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Stephen

UNFMech
03-17-2010, 05:50 AM
No, I want the code to keep going. I need the sweeper arm to sweep continuously, no matter what state the sensor is in, while the sensor is checking to see if the pin is active, and if it is active then I need the door to open. In other words I need those two functions to loop forever until I switch the board off, but the sweeper arm cannot stop and the sensor needs to continuously check for the presence of the material. All of the code is posted in a DO-LOOP Function.

Post Edited (UNFMech) : 3/16/2010 11:15:27 PM GMT

Franklin
03-17-2010, 09:48 AM
Like I said above What code are you using? Please attach THE ENTIRE PROGRAM to your post so we can see where you went wrong.
Click on the post reply button and use the attachment manager to attach your code.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Stephen

UNFMech
03-17-2010, 12:52 PM
Ok, there we go. I think...

Franklin
03-18-2010, 05:13 AM
OK the code you attached does not even compile. Fix that first and then repost.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Stephen

W9GFO
03-18-2010, 12:56 PM
This is what I would try;


' {$STAMP BS2}
' {$PBASIC 2.5}


PIR PIN 0
sweep_servo PIN 12
door_servo PIN 13

forward VAR BIT
opening VAR BYTE

sweep_value VAR WORD
door_value VAR WORD

min_value CON 400
max_value CON 1100

open CON 850
closed CON 1100

'*********************************

sweep_value = min_value
door_value = closed
opening = 0

DO

PULSOUT sweep_servo, sweep_value
PULSOUT door_servo, door_value

IF PIR = 1 THEN
door_value = open
opening = 1
ENDIF

IF opening > 0 THEN
opening = opening + 1
IF opening >= 50 THEN
opening = 0
door_value = closed
ENDIF
ENDIF

IF sweep_value => max_value THEN forward = 0
IF sweep_value =< min_value THEN forward = 1

IF forward = 1 THEN
sweep_value = sweep_value + 20
ELSE
sweep_value = sweep_value - 20
ENDIF

PAUSE 15

LOOP

'***********************************



Rich H

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The Simple Servo Tester, a kit from Gadget Gangster. (http://www.gadgetgangster.com/206)

Post Edited (W9GFO) : 3/18/2010 6:03:57 AM GMT

UNFMech
03-20-2010, 12:18 AM
Rich H. (W9GFO) from the bottom of my heart. I thank you. The sweeper servo was a little slow for our application and I just removed the Pause and it works FLAWLESSLY. I thank you so much.

W9GFO
03-20-2010, 12:35 AM
You're welcome.

The PAUSE 15 is there to try to keep your loop running at 50 times a second. If the sweep servo is too slow the way to speed it up is to increase the amount that the sweep_value changes each time through the loop.

Put this at the top along with the other declarations:


sweep_change CON 30


Then replace -

IF forward = 1 THEN
sweep_value = sweep_value + 20
ELSE
sweep_value = sweep_value - 20
ENDIF


With this;


IF forward = 1 THEN
sweep_value = sweep_value + sweep_change
ELSE
sweep_value = sweep_value - sweep_change
ENDIF


Now when you want to alter the speed of the sweep servo just change the number assigned to sweep_change at the top of the program.

Put the PAUSE 15 back and only reduce it if the servo is stuttering.

Rich H

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The Simple Servo Tester, a kit from Gadget Gangster. (http://www.gadgetgangster.com/206)

Post Edited (W9GFO) : 3/19/2010 5:40:25 PM GMT

W9GFO
03-20-2010, 01:15 AM
Also, to change the amount of time that the door stays open, adjust the "50" in;


IF opening >= 50 THEN
opening = 0



You could also create another CON for that value (just like we did for sweep_change above) so that you can adjust it from the top of your program rather than having to dig down through the code to find the value. Not really an issue in this short program but it is a good habit to get into.

Rich H

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The Simple Servo Tester, a kit from Gadget Gangster. (http://www.gadgetgangster.com/206)