How to synchronize a pair of servos

Hi everyone

I want to synchronize the movement of a pair of servos but having trouble figuring this out, i know you can only execute 1 command at a time but i figured if you do a loop and move the pair in turn by a small increment it should be pretty close to synchronized (atleast to the naked eye). But i’ve tried this and the result is a very rough synchronization, more like a sequence of actions.

Does anyone have any suggestions as to how to go about doing this? I’ve attached my MATLAB script for viewing. Oh, and I’m using the USB16 servo controller.

Thanks in advance, :slight_smile:

John L

% first pair, channel 0 and 1
pair = [0 1];
% set servo movements
move = 5000;
% set movement stepsize
step = 100;
% step counter
i=0;
%movement increment
dif=(move-3000)/step;
while i<step
i=i+1;
x1=round(3000+i*dif);
moveServo(pair(1),x1);
moveServo(pair(2),x1);
end

function moveServo(s,x)
%moveServo(s,x) for Pololu serial servo controllers, using Pololu mode
%(remember to remove the blue mode-selection jumper!) absolute position
%command #4. You may need to edit the port variable in this file to match
%your com port.
%
%s=servo number
%x=absolute position, 500<=x<=5500

port = ‘COM3’;%Edit to your com port number

ser1 = serial(port);
set(ser1, ‘InputBufferSize’, 2048);
set(ser1, ‘BaudRate’, 9600);
set(ser1, ‘DataBits’, 8);
set(ser1, ‘Parity’, ‘none’);
set(ser1, ‘StopBits’, 1);

fopen(ser1);
fwrite(ser1, [128, 1, 4, s, binvec2dec(bitget(x,8:13)), binvec2dec(bitget(x,1:7))]);

fclose(ser1);
delete(ser1);

The moveServo function is a nice and self contained example, but other than that there isn’t a good reason to open and close the serial port around each servo command, which takes a lot of extra overhead time.

You can move the lines:[code]port = ‘COM3’;%Edit to your com port number

ser1 = serial(port);
set(ser1, ‘InputBufferSize’, 2048);
set(ser1, ‘BaudRate’, 9600);
set(ser1, ‘DataBits’, 8);
set(ser1, ‘Parity’, ‘none’);
set(ser1, ‘StopBits’, 1);

fopen(ser1);
[/code]out of the moveServo function into the beginning of your program, as they only need to be run once before you can start sending servo commands. Similarly you should move the lines:fclose(ser1); delete(ser1); to the end of your function, as they only need to be called once when you’re all done.

Once you’ve done that, the moveServo function should only have one executable line:fwrite(ser1, [128, 1, 4, s, binvec2dec(bitget(x,8:13)), binvec2dec(bitget(x,1:7))]);This should make the commands execute much faster. Actually, you may need to decrease your step size or add delays!

I had good luck with this approach in Matlab making a robot arm follow an computed trajectory, which required six servos to be synchronized. If the servos are moving too quickly from point to point along your synchronization you might also try using the Pololu speed limiting function to smooth out the motion.

-Adam

Hi Adam

Thanks for the tip, it’s now working exactly as i pictured. i have another question tho, say i start my servo control at the neutral position (3000), i make my first actuation to the position A using 100 increments,and then i’d like to move to position B from position A using 100 increments too, how would i do that? as far as i can tell, unless I record down position A, there isn’t a command to determine what position the servo is at.

Also on a differnet issue, i find that if i leave my servo switched off at a position away from neutral, the next time i turn the power back on the servo does a little adjust movement. is that natural? is it good practice to leave the servo off at a position away from the neutral?

Best regards

John L

Glad to hear it!

You will need to keep track of the servo’s position internally in your program. Unfortunately, the standard hobby servo protocol doesn’t have a way for the servos to communicate their current position back to the controller.

If the twitch isn’t causing you any trouble it shouldn’t be a problem for your servos.

-Adam