Need two Servo Controllers for simultaneous motion?

Hi,

I have a Pololu 16 servo controller. I am only able to get the servos to move sequentially rather than simultaneously. My understanding was that the 16 servo controller could control multi-servos at the same time.
Did I read too much into it? Is a second controller needed to run two servos at the same time?

Thanks,
Steve

Hi Steve,

The Pololu servo controller only lets you command one servo position at a time, but that doesn’t mean that you can’t get two servos to move ‘together’. Your servo controllers generates servo control signals at 50Hz, or every 20ms (normal for hobby servos), so you can only update a servo’s commanded position that often by design, and you can get servos to move together by sending out a series of rapid commands.

The only limiting factor here is the serial baud rate. Using Mini-SSCII mode with three-byte commands at 9600BPS, you can update six servo positions in 20ms. Using Pololu mode at 38400BPS with the six-byte absolute position command, you can update 12 servo positions in 20ms, and all 16 servos in less than two signal periods.

Hobby servos are awesome, but they’re not terribly high precision devices. Variations between individual motors and the time it takes them to overcome drive train friction and inertia and even start moving are huge compared to the minuscule time it takes to send new position commands, so even if you send the commands in series the servos should move together as far as is perceptible to us humans.

-Adam

Hi Adam,

Thanks for the comments. You are absolutely correct. I had two servers running in a “while” loop. My eye was not able to tell they were working together. Putting a delay in the while loop allowed me to tell when the commands began and ended being executed.
Thanks again.

A followup question. I have code that looks something like the below:
serialPort1.Pololu(“Com3”, 9600, 0, 4250, 100);

serialPort1.Pololu(“Com3”, 9600, 0, 1450, 100);

serialPort1.Pololu(“Com3”, 9600, 1, 1450, 100);

serialPort1.Pololu(“Com3”, 9600, 1, 4250, 100);

In come cases I may actually want to wait between servo Zero going to 1450 and servo One going to 1450. Is there a simple delay command that can be used. I’ve been looping a counter until it gets to 5 million. There has got to be an easier way!

Thanks again.
Steve

There certainly is, but it will depend on the platform and programming language. What language are you compiling this code in?

For example, in C you can use the sleep(int ms) function, which takes an integer number of milliseconds as its argument. So, to delay for half a second, you would write:

sleep(500);

-Adam

Thanks Adam. That sounds a lot cleaner than While loops!
When I insert sleep(500); I get the error “The name ‘sleep’ does not exist in the current context”. Any clues to help resolve.

Steve

P.S. I am using MS Visual C# 2008 Express Edition.

A quick Google tells me that the format for the similar built-in delay function is:
Thread.Sleep(X);
Where X is an integer number of milliseconds.

I haven’t played with C# yet myself, so let me know if that works.

-Adam

I have a pololu Micro ssc with 8 servos and i have the same problem controlling more than one servo simultaneously . I tried with delay but still no results. can u help me ?? I really need to control more than one servo at a time because i’m working on a biped robot made by me for my final year project at university and i really need some help… pls

Thank You.

Just to get us on the same page, what (microcontroller device or computer programming language) are you using to send commands to your servo controller? Can you post the code you’re using at the moment? If you’re using a computer what operating system are you running?

-Adam

I’m using Visual Studio C# 2008 .NET 3.5 on Windows XP

The code is:

            SerialPortClass s = new SerialPortClass();

            string comPort = textBox1.Text;
            int baudRate = Convert.ToInt32(textBox2.Text);
            int servoNumber = Convert.ToInt32(textBox3.Text);
            int servoPos = Convert.ToInt32(textBox4.Text);
            int servoSpeed = Convert.ToInt32(textBox5.Text);

            // this is without delay
            s.Pololu(comPort, baudRate, servoNumber, servoPos, servoSpeed);

            // this is how i used delay
            //for (int i = 0; i < 20; i++)
            //{
            //    s.Pololu(comPort, baudRate, servoNumber, servoPos, servoSpeed);
            //    Thread.Sleep(200);
            //    s.Pololu(comPort, baudRate, servoNumber+1, servoPos, servoSpeed);
            //    Thread.Sleep(200);
            //    s.Pololu(comPort, baudRate, servoNumber+2, servoPos, servoSpeed);
            //    Thread.Sleep(200);
            //}

EDIT : I also used Pololu Serial Transmiter with 5 byte command like : 128, 1, 2, 0, 3000, i usually use comand 2

That might be your problem right there. Command 2 takes a 7-bit position, so your position variable should be between 0 and 127 (not 3000).

An 8-bit serial byte can only be between 0 and 255 (2^8-1) anyway. Commands 3 and 4 let you specify a position more precisely, but you have to split your number up into two 7-bit bytes to use them, since the Pololu protocol uses the high-bit of an 8-bit byte to signal the beginning of a command. When you send 3000 out, what you’re probably actually sending is the lower 8-bits of the number, which equal 184. Since the high bit is set this would confuse the servo controller.

For now you might want to stick with command 2 and specify positions between 0 and 127, but if you’re interested in how to use the other commands you might want to take a look at this thread.

-Adam

Probably I’ve mistaken the command i gave you, but the command i use is ok, if i try to command one single servo, it works ok. but when i try to control the second servo, the first one isn’t working anymore.

Let me explain what i’m trying to do.
This is my robot : http://i89.servimg.com/u/f89/13/69/40/76/plan1_10.jpg

When i send a comand to servo1, it moves to the specified location and the servocontroller send the same command forever to maintain the position, then i send a command to servo2 to move to a desired position, when the servo2 moves, the servo1 falls back because the servocontroller stop sending commands to the first servo to keep it there and now it’s sending that commands to the second servo, and the second servo now stays where it’s supposed to be while the first one falls back dead…

Hope you understand what i’m trying to explain. Sorry if my English isn’t so accurate.
Thank You.

That is very strange behavior! Once you command a servo to a position it should stay there until you reset the servo controller or sent it a new position or the off-setting command. It should be completely independent of the other servos.

Normally I would suspect this was a power problem (and I still do somewhat). Can you describe your power sources and how you’re connecting them? Also, what kind of servos are you using? If you are powering the servo motors and the controller from the same source (battery, power supply, etc…), drawing more power than the source can cause the voltage to drop and the controller to reset. In that case though, I wouldn’t expect the second servo to hold its position.

Can you post the details of your s.Pololu function? Alternatively, can you look at the serial bytes your program is sending out when you see this behavior (for example, using HDD free serial port monitor, the free version is fine)?

-Adam

This is how i power the servo controller, the only difference is that i use a 4 battery pack of 2.7 A/h

The servo i use is “Tower Pro SG-5010”.
The s.Pololu function is the one from PololuServoExample downloaded from here :
http://www.colinkarpfinger.com/pololu/PololuServoExample.zip

I don’t think Colin Karpfinger’s code does anything bad like commanding servos to turn off, so I’m thinking maybe it’s a power issue again.

When you say a four-cell pack, are you using NiCd or NiMH batteries? If so, the voltage is a little low to be running the electronics, so when you try to move your second servo it may be causing the battery voltage to drop enough that it interferes with the motor controller. Still the behavior is very strange.

A quick test can tell us a little more. Can you try running a version of your program that makes the first servo fall back when you move the second servo? Then try running it with the second servo disconnected, and see if the first servo still falls or not. If it stays where it is, your problem is low voltage from the battery pack. If not, it’s likely a software issue.

-Adam

Thank you for this hint. The batteries are NiMh, i don’t know the difference… but i’ll try to power the servo controller from a different source than the servo motors. If i use a single motor it works, but as u can see my robot, i need to power at least 10 servos at once just to keep it from falling :slight_smile: so i really need to hold multiple servos at a specified position independently.
I’m thinking that maybe i don’t send the commands correctly so i’m asking you, which are the steps that i should take in controlling the servo. in what sequence i should send the commands to the servo controller ?

Can i just send : [128, 1, 4, 0, upperBits, lowerBits], or before that i need to send some power on or some other commands, can u tell me which are the steps (commands) for this to work properly ?

Thank you.

Once you’ve powered the servo controller up you don’t need to do any special initialization. Just sending that string of bytes will move the servo to a set position and hold it there. The only other command you might want to look at is command 1: set speed, which will let you do smooth slowed-down servo motions, but you can worry about that later.

These are fairly high-torque servos, so if you want them all working hard at the same time you’re going to want a battery pack that can source at least 10 amps, if not more. If you want to power your electronics from the same pack you’ll probably want to add one more cell to keep the voltage up, so maybe something like this.

You might also consider powering the electronics from a separate, smaller battery that will always stay above 5V.

-Adam

Thanks a lot :slight_smile:

The problem was indeed the power source, now i powered the servos and the electronics from a AT Power supply and it works great :smiley: :D/

Thanks again…

Awesome! Maybe when you get your legs put together you could post some pictures/videos.

-Adam

of course i will :D, now i had modified the frame, at the legs i had some pieces of aluminum of 20cm long and now i replaced them with plexi-glass of 15cm long because the leg was to heavy for the upper servo to move and i had some problems, now it seems to work just fine :slight_smile: i just finished building an application in C# something like this :

i built this only for testing the right values for each servo, so i can make a script or something, to make him walk

:slight_smile:

I’ll be back with news.