Servo tangles up wires

I am using a servo with a UNO R3 and Elegoo Car kit. I am moving a servo to 90, 10, 90 and 180 degrees. If I increase the delays inbetween the servo.write commands, the servo turns opposite to what it should and tangles up the wires holding an ultrasonic sensor on it. This code works fine.

#include <Servo.h>  //servo library
Servo myservo;      // create servo object to control servo

void setup() {
  myservo.attach(3);  // attach servo on pin 3 to servo object
}

void loop() {
  myservo.write(90);  //setservo position according to scaled value
  delay(500);

  myservo.write(10);              
  delay(500); 

  myservo.write(90);              
  delay(500);

  myservo.write(180);              
  delay(500);

  myservo.write(90);              
  delay(1000);
}

Increasing the delay to 1500 between servo.write for 10 and 90 makes the servo tangle up the wires.

myservo.write(10);              
delay(1500); 

myservo.write(90);              
delay(500);

I would like to know why the Servo library (Michael Margolis, v1.1.2) behaves this way.

The servo "turns opposite to what it should"? So you're saying the servo is at angle 10 (i.e. almost hard over one way) and then a second and a half later you write(90) to it. So where exactly does the servo move to?

Steve

This is something to do with the partiular servo, or the power supply being inadequate, the Servo library doesn't have any timeouts like this.

@slipstick: 90 is center. 10 is 80 degrees clockwise. 90 is 80 degrees counter-clockwise. That is the right operation. When delay is increased, for the last step, servo rotates clockwise. It might reach 90, but is held by the tangled wires at around 180.

@MarkT: If there is insufficient power, the problem would be exacerbated by reducing the delay. But it only happens when delay is increased.

Evenif it is indeed Servo specific, how is it 100 percent reproducible? The UNO must be sending different pulses when it misbehaves.

I read your description of the misbehaving and I get an impression that the servo can operate a sector larger than 180 degrees. If that's the case, your servo needs other commands than what you are using. Find out what the datasheet of your servo says. I believe 1000 - 2000 µs is the normal pulse range and that corresponds to 0 - 180 degrees, if you use a myservo.write(angle) command. But if your servo can operate larger than 180 degrees, maybe the pulse range is something else than 1000 - 2000 µs, too. Maybe you send commands to your servo, which are on an undefined range. Sometimes it works, Sometimes it doesn't. And it might depend on very peculiar things. Like a previous delay.

Sounds like this is not a true servo but a continuous one if the wires get "tangled up".

Thank you all for the help. I carried out several experiments to reach these conclusions:

If the servo is not given sufficient time to turn from 90 to 10 and the pulse to turn to 90 is issued, it usually turns from around 20 degrees back to 90. Thus shorter delay between commands always turns it back from "10" to 90 counter-clockwise. If given sufficient time to settle at 10, the servo gets confused and turns to less than 0. This may not be a generic problem with the Tower Pro SG90 servo but it is a problem with the one I have.

There should be no issues with the library. It is the short pulse width of <= 0.5ms that the servo cannot recognize correctly.

Once again, appreciate all the forum posts and offline messages.

If you signal the servo to go to 90, it should go there and stay there. Does it?
Have tou tried the servo sweep tutorial? It would help us confirm what you are dealing with.

90 or 180 are never an issue. It is the 10 degrees or less with its short pulse that causes the problem.

I played with the Sweep code to reach my conclusions. I changed Max and Min angles, angle increments and delays between myservo.write commands. Modified code below:

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

#define DELAY 500
#define SERVO_PIN 3
#define MIN_SERVO_ANGLE 20
#define MAX_SERVO_ANGLE 170

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(SERVO_PIN);  // attaches the servo on pin to the servo object
}

void loop() {
  for (pos = MIN_SERVO_ANGLE; pos <= MAX_SERVO_ANGLE; pos += 15) { // goes from 0 degrees to 180 degrees
    // in steps of 15 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(DELAY);                       // waits 15ms for the servo to reach the position
  }
  for (pos = MAX_SERVO_ANGLE; pos >= MIN_SERVO_ANGLE; pos -= 15) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(DELAY);                       // waits 15ms for the servo to reach the position
  }
}

What do you expect this latest code to do? What does it do differently than you expect?

To me, it looks like it tells the servo to go to 20 and wait a half second.
Then 35 and wait.
50 and wait.
65 and wait.
80 and wait.
95 and wait.
110 and wait.
125 and wait.
140 and wait.
155 and wait.
170 and wait.
Then the second loops walks it back down with the same half second wait between each.
170
155
140
125
110
95
80
65
50
35
20

Then it starts over, having spent about 11 seconds to sweep.

Is that what you see?

If you compare the code to the original Sweep tutorial, you'll see I changed the following:

  • Max Angle from 180 to 170
  • Min Angle from 0 to 20
  • Step Angle from 1 to 15 to speed up rotation[
  • Delay between myservo.write's to 500ms so the servo gets plenty of time to turn

The published code is the final version which works reliably for my servo and does not tangle up the wires. Changing MIN_SERVO_ANGLE to 10 or less makes the problem appear. I had changed MAX_SERVO_ANGLE to 180 and even 240 but that does not turn the servo beyond 180. Hence the conclusions I had stated earlier.

Let me see if I understand.
You have confirmed that the sweep example works as coded in your last posting of your code.
You say that if the servo is moved to 20, and then moved to 90, it properly moves to 20, then moves as expected to 90.
You also say that if the servo is moved to 10, and then moved to 90, it tangles the wires.
Does that mean that after the servo moves to 10 (which it does as expected) and you issue the command to move to 90, it moves to 90 by traveling all the way around the wrong direction?

Hi

Can you please post a picture of your project?
As an attachment.

Thanks.. Tom.. :slight_smile:

@vinceherman Yes, that's how it behaves. If the servo is 10 degrees or less, the next turn will be clockwise.

@TomGeorge Photo attached. Sensor wires disconnected for experiment. Servo facing 90 degrees in photo. Camera is at 0 degrees.

Photo added.

Hi,
Thanks for a very clear picture,

Do the wires get tangled OR just pull tight because the wires are not long enough?

Tom.... :slight_smile:
PS Can you show a picture of tangled?

So you have a continuous servo that actually is a servo. To my knowledge, servos usually have a working sector of 180 degrees or slightly less. And they turn to any angle inside that sector. Then there are continuous servos that are like motors, and you just set the speed and direction (but not a desired position) by sending them similar signals to the ones the "normal" servos get.

But your servo turns more than 360 degrees, since it apparently can go from 10 to 90 either way around. Please, show us a link to the datasheet of that servo.

In your place, I'd switch to a regular hobby servo and save that peculiar servo for something else, where 360 degrees is needed.

Hi,
OPs pic.

The Tower ProSG90 is a regular servo.

Tom.. :slight_smile:

Perhaps post a video of it doing the "tango(le)".

Servo works as expected from 20 to 170
Servo can move to 10
Commanding servo to 90 after it moves to 10 does go to90 but the wrong way round

The servo is broken. Can you live with 20-170? Keep using it! Otherwise, replace it.