Two Servos with Basic Stamp
Boots451
Posts: 5
I am trying to run two servos with the Basic Stamp Home Work Board. The servos to alternate action not simultaneous. Servo A to raise arm, servo B to start position, Servo A to lower arm, Servo B to sweep, Servo A to raise arm, Servo b to return to start and A to lower arm to docking. The code doesn't work. Any help?
Thanks,
Boots451
Dual counter #2
' {$STAMP BS2}
' {$PBASIC 2.5}
counter VAR Word
DO
IF (IN3 + 1 ) THEN
FOR counter = 1 TO 100
PULSOUT 10, 750
PAUSE 7
NEXT
FOR counter = 1 TO 100
PULSOUT 14, 725
PAUSE 50
NEXT
FOR counter = 1 TO 100
PULSOUT 10, 700
PAUSE 7
NEXT
FOR counter = 725 TO 590 STEP 2
PULSOUT 14, counter
PAUSE 750
NEXT
FOR counter = 1 TO 100
PULSOUT 14, 590
PAUSE 50
NEXT
FOR counter = 1 TO 100
PULSOUT 10, 750
PAUSE 7
NEXT
Thanks,
Boots451
Dual counter #2
' {$STAMP BS2}
' {$PBASIC 2.5}
counter VAR Word
DO
IF (IN3 + 1 ) THEN
FOR counter = 1 TO 100
PULSOUT 10, 750
PAUSE 7
NEXT
FOR counter = 1 TO 100
PULSOUT 14, 725
PAUSE 50
NEXT
FOR counter = 1 TO 100
PULSOUT 10, 700
PAUSE 7
NEXT
FOR counter = 725 TO 590 STEP 2
PULSOUT 14, counter
PAUSE 750
NEXT
FOR counter = 1 TO 100
PULSOUT 14, 590
PAUSE 50
NEXT
FOR counter = 1 TO 100
PULSOUT 10, 750
PAUSE 7
NEXT
Comments
A high-going pulse of a particular width (1.5 mSec being center position) repeated every 20 msec. Very important that -- REPEATED EVERY 20 MilliSeconds. Some people try to "improve" on this by repeating (as you have) every 7 milliseconds. However, since 7 milliseconds is not 20 milliseconds, this is not a "better" control signal, it's simply incorrect.
I'm curious -- why are you repeating one every 7 milliseconds, and the other every 50 milliseconds?
Anyway, attached is a fix.· I've created a "SetServos" subroutine which will "refresh" both servo's, so they both hold position all the time, AND guarantee you get that 20 millisecond pause each time.· So you simply change the "Servo1Pos" then call SetServo repeatedly to move Servo1, and change "Servo2Pos" and call SetServo repeatedly to move Servo2.
Post Edited (allanlane5) : 10/23/2009 1:44:51 PM GMT
Thanks again,
Boots 451
Even when controlling speed of the servo, you'll need to refresh it every 20 milliseconds. To slow it down, you'll want to change the step-size less often.
Let's see. 725 to 590 is 135 steps. 50 seconds / 20 mSec == 2500 commands to the Servos. 2500/135 == 18 times at each step value.
So:
· For Count = 725 to 590
··· Servo1Pos = Count
··· For I = 1 to 18
··· · GOSUB SendServos
··· NEXT
· NEXT
So, let's confirm. The above will send each 'step' to the servo 18 times. 18 * 20 mS == 0.36 seconds. Then we do that for 135 steps. 135 * 0.36 == 48.6 seconds.
Yup, there's your solution.
· Servo1Pos = 725
· FOR I = 1 to 50 ' 50, because 50 * 20 mSec == 1 second
··· GOSUB SendServos
· NEXT
See, the servo contains a very simple 'comparator' with a variable resistor tied to the shaft of the servo. Each position of the shaft (and thus the variable resistor) generates a pulse-width inside the servo. Then your PULSOUT commands send to the servo another pulse-width. The servo electronics compare the internal pulse-width with your "commanded" pulse width, and moves the internal electric motor to bring the two pulse-widths to be the same size. This process usually takes longer than 20 mSec, so multiple 'refreshes' of the same "commanded" pulse-width are needed for the servo to complete its move.
Once the servo reaches the commanded position, if you want it to hold that position against resistance, then you need to keep commanding the servo to the same position -- which is what the subroutine does. If you stop commanding the servo, it stops energizing its motor, and you can turn the shaft by hand (or any weight on the shaft will turn it).
'Dual counter #1
' {$STAMP BS2}
' {$PBASIC 2.5}
counter VAR Word
Servo1 CON 13
Servo2 CON 12
Servo1Pos VAR Word
Servo2Pos VAR Word
Servo1Pos = 850
Servo2Pos = 725
FOR Counter = 1 TO 10 ' Initial Setting
GOSUB SetServos
NEXT
MAIN:
FOR counter = 1 TO 100 'servo 2 lifts arm
PULSOUT 12, 7760
PAUSE 20
NEXT
FOR counter = 1 TO 50 'servo1 moves to start position
PULSOUT 13, 725
PAUSE 20
NEXT
FOR counter = 1 TO 100 'servo 2 lowers arm
PULSOUT 12, 600
PAUSE 20
NEXT
FOR counter = 725 TO 590 STEP 2 ' servo 1 sweeps
PULSOUT 13, counter
PAUSE 750
NEXT
FOR counter = 1 TO 25
PULSOUT 13, 590
PAUSE 20
NEXT
FOR counter = 1 TO 100
PULSOUT 12, 760 ' servo 2 lifts arm
PAUSE 20
NEXT
FOR counter = 590 TO 850 ' servo 2 returns to over rest position
PULSOUT 13, counter
PAUSE 7
NEXT
FOR counter = 1 TO 100 'servo 1 lower to rest position
PULSOUT 12, 760
PAUSE 7
NEXT
END
SetServos:
PULSOUT Servo1, Servo1Pos
PULSOUT Servo2, Servo2Pos
PAUSE 20
RETURN
END
For Count = 725 to 590
Servo1Pos = Count
For I = 1 to 18
GOSUB SendServos
NEXT
NEXT
and it runs much smoother. But it makes other aspects of the servo run a little buggy( hops a little her and there). So I think that I will have to rewrite some of my header about position of servo #2.
Thanks for your help
Boots451