PDA

View Full Version : Two Servos with Basic Stamp



Boots451
10-23-2009, 03:07 PM
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

allanlane5
10-23-2009, 08:27 PM
The servo control signal is:

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

Boots451
10-23-2009, 10:21 PM
Allan, First thanks for your help. I am building a record cleaning machine, knock off of the Loricraft. After wet cleaning a suction arm sweeps the record to take away the dirt and dry the record. The reason for the 7 millisecond and 50 millisecond difference is a matter of sweep speed. The initial sweep of the arm has to be slow in order to let it perform properly and the return sweep is faster just a matter of getting it back to the start position. I need the first sweep ( 725 to 590 ) to take about 45 to 60 seconds and this seemed to work with pause of 50. It is not smooth but does what is needed. The return of the sweep is just to get the arm out of the way and backed to dock. The pause 7 is just a smooth way of doing it. All of this is because of being very ignorant of the mechanics of servos and programming. I am eager to try your solution as I have never seen the type of program that you wrote.

Thanks again,

Boots 451

allanlane5
10-23-2009, 10:55 PM
Interesting. I've normally been using servo's modified for "continuous rotation", and haven't done much 'speed control'.

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.

allanlane5
10-23-2009, 11:05 PM
And you'll have to measure the max speed the servo can move from 590 to 725. If I assume it will take a second, then:

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).

Boots451
10-24-2009, 06:55 AM
Alan- I couldn't get some of your code to work for me so I put this crude program together. It does what I need if not to elegant.

'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

MichelB
10-24-2009, 03:25 PM
Interesting this thread. I'm a beginner and I want to know what is the "job" of the following line in Main: "IF (IN3 + 1) THEN". Thank you.

Boots451
10-26-2009, 07:05 AM
Michel.........I started out trying to put a on-off button[ "IF ( in3 = 1 ) then "] on the machine but took it off for simplicity sake. I'll try to add it back in at a later date when all is well with the rest of the works.

MichelB
10-26-2009, 07:27 PM
OK, thank you for your reply.

allanlane5
10-26-2009, 08:51 PM
Hey, whatever works for you is fine.

Boots451
10-27-2009, 12:41 AM
Alan.... Because it works doesn't mean it is right.... This is a work in progress. I put in the


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