Servos killing my robot arm

Apologies if this is a FAQ, I found some similar questions but not quite the answer :slight_smile:

I've built a robot arm that has a "resting position" in the typical "question mark" shape, with the upper arm pivoted 45 deg from the base, the lower arm roughly horizontal and the wrist hanging down. I'm using an Adafruit 12-channel PWM servo shield to drive the servos, with an external 6V 10A supply for them.

In normal use it's nice and sedate, I've written code to break moves down into discrete steps with graduated times between the moves so that the limbs move reasonably slowly and smoothly.

However when I power up, the servos appear to move to their zero positions at full speed. This causes the arm to stretch out to its full extent and then fly backwards - because of its length the momentum is substantial and it's likely to self-destruct pretty soon.

Any ideas for how to minimise the damage ?



One solution is to stop the arm at the extreme positions that the servos will take at startup.

Another possible solution is to write the desired position for the servo before you attach it.

If neither of those ideas helps then you need to post your program.

Have you experimented with a single servo to learn the startup behaviour?


I was wondering about parking it near the extreme position, but I found there are too many :slight_smile: :slight_smile:

I have 7 servos and they all have extreme positions far from each other, but two in particular are 90-deg apart so when it wakes up, one or other of them will be thrashed.

I'm still learning how to work with servos - do they need to find their zero position when they're first asked to move, or can they seek to a position from whatever position they happen to be at when they power up ?

I think your idea of trying with one servo is a very good one ... it might be something in my initialisation code. I'll do some experimenting and see what I find.

Thanks !


I'm still learning how to work with servos - do they need to find their zero position when they're first asked to move, or can they seek to a position from whatever position they happen to be at when they power up ?

Unfortunately there is no "standard" so you will need to determine what your servos do.

For example I have some cheap HobbyKing analog servos that move a few degrees clockwise every time they are powered up even without a signal. If you power them up enough times without giving them a signal they will run against the end stop. HobbyKing told me that the cheap digital servos do not move at powerup and a friend bought some and that seems to be true.

Then there is the question of what the Arduino does when it attaches the servo. I think the default is the mid point, but, as I said earlier, you can change that.

What you cannot do is get the Arduino to figure out where a regular servo happens to be at startup so you must ensure an orderly shut down.

You can get servos with a 4th wire that allows the Arduino to read the position but they are not common and I don't know if there are version equivalent to whatever you are using. It may be possible to adapt a servo to give it a 4th wire - try Google. I have no experience of them and I don't know whether having a 4th wire would be useful for your problem.


I've never heard of an Adafruit 12-channel servo shield. Do you have a link to its specification?

How to set up a default starting position for the servos will depend on how you're driving them.


Hi Steve,

Sorry, typo ! I should have said 12-bit, 16-channel shield. Adafruit 16-Channel 12-bit PWM/Servo Shield - I2C interface : ID 1411 : $17.50 : Adafruit Industries, Unique & fun DIY electronics and kits



:-[ :-[ :-[

Operator error !

So my servos (mg996r and sg90) don't do anything when powered up other than jitter a little for a second. When they're given a position to go to they go there as fast as they can.

So the problem turned out to be this - in case some other newbie ever has the same issue :-[

I wanted to move them more slowly than their usual speed, and have them accelerate and then decelerate as they move, so I move them in steps in my loop() rather than just sending them to the target position.However In order to allow them all to move concurrently I don't use a delay() between steps, but have three arrays.

The first contains the current position for each servo, the second contains the target position for each (which will be the same value as the current position if the servo is stopped) and the third contains the next millis() time that the servo will be sent an update. So in my loop I check the next time for each, and if it has arrived and the current position is not the same as the target I increment/decrement it, update the "next time" and send the new position to the servo.

Of course I initialised the target positions in setup() but forgot to initialise the current ones, which were all zero :-[

So the first command each servo was sent was "move to position (0 + 1) = 1" ... hence the mad thrashing ...

I'm glad you found the problem. And now you can probably also see why many people round here don't like answering questions without being able to see the code that the question is about.