Servo will always go from 0 to 180 regardless of input

Hello,

I'm making a warhammer model that has several servos inside of it. 2 of the 3 servos are working fine but the third seems to always jump from 0 to 180 (actually seems to be more than 180 degrees) regardless of the input I give it. It also seems to want to go further than 0,180 where you'll here it hitting its limits.

I'm running an Nano 33 IOT currently have the servo hooked up to a DC power supply set to 5.5v with common ground to my Arduino thats powered by double A batteries.

I've tried several different scripts, I've attached one below. I've tried limiting the range in the Attach statement, but no matter what the input is it always either goes to 0 or 180.

With default Attach args I get some really inconsistent behavior.

If i enter 550 it goes to what I assume is the 0 degrees.
If i enter say 600 nothing happens.
If i enter 650 it then goes all the way to what i assume is 180 degrees
If i enter 550 and then 800 it will go to 0 and then 180 but then if i enter 650 it goes back to 0

Any advice here would be great. I unfortunately didnt spend enough time testing the servo before I built the model, I knew it worked but didnt look closely at its behavior So i'm in a position where I cant replace the servo.

Thanks

/*
 Try this test sketch with the Servo library to see how your
 servo responds to different settings, type a position
 (0 to 180) or if you type a number greater than 180 it will be
 interpreted as microseconds(544 to 2400), in the top of serial
 monitor and hit [ENTER], start at 90 (or 1472) and work your
 way toward zero (544) 5 degrees (or 50 micros) at a time, then
 toward 180 (2400). 
*/
#include <Servo.h>
Servo servo;

void setup() {
  // initialize serial:
  Serial.begin(9600); //set serial monitor baud rate to match
  servo.write(0);
  servo.attach(8);
  prntIt();
}

void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {

    // look for the next valid integer in the incoming serial stream:
    int pos = Serial.parseInt();
    pos = constrain(pos, 0, 2400);
    if (pos > 544) {
      servo.write(pos);
      prntIt();
    }
  }
}
void prntIt()
{
  Serial.print("  degrees = "); 
  Serial.print(servo.read());
  Serial.print("\t");
  Serial.print("microseconds =  ");
  Serial.println(servo.readMicroseconds());
}
  • Print pos what do you get.

Always show us a good schematic of your proposed circuit.
Show us good images of your ‘actual’ wiring.
Give links to components.

  • Try swapping servo cables.
  • Confirm battery voltage with a DMM.

Try:


servo.writeMicroseconds(pos);

As your code only has one servo connected (pin 8), I understand that you use the same code to test the 3 servos. Right?

But 2 work well and when testing the third with the same code it doesn't work correctly?

If what I described is correct, I believe it is a defect in the servo.

Thats correct. I have a large script that runs everything, the code of all 3 is very similar, but one of the 3 servos didnt work. So i created a much simpler project to test out the 1 failing servo which is the code I linked above.

I also just bought another servo and hooked it up and it works as expected so I fear something is wrong with that servo. Its just weird that it moves but only 0 and 180. I also noticed for lower requested angles (say 20 degrees) it moves to 180 much slower than if i asked for 50 degrees

Here's the output:

pos: 600
degrees = 5 microseconds = 600
pos: 700
degrees = 15 microseconds = 700

Here 600 keeps it at 0 degrees, 700 sends it to 180. This code uses the writeMicroseconds. Script below.

Unfortunately the actual wiring is hidden inside of the model so it cant be seen. I'm looking up how to make those pretty images now.

/*
 Try this test sketch with the Servo library to see how your
 servo responds to different settings, type a position
 (0 to 180) or if you type a number greater than 180 it will be
 interpreted as microseconds(544 to 2400), in the top of serial
 monitor and hit [ENTER], start at 90 (or 1472) and work your
 way toward zero (544) 5 degrees (or 50 micros) at a time, then
 toward 180 (2400). 
*/
#include <Servo.h>
Servo servo;

void setup() {
  // initialize serial:
  Serial.begin(9600); //set serial monitor baud rate to match
  servo.write(0);
  servo.attach(8);
  prntIt();
}

void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {

    // look for the next valid integer in the incoming serial stream:
    int pos = Serial.parseInt();
    pos = constrain(pos, 0, 2400);
    if (pos > 544) {
    servo.writeMicroseconds(pos);
    Serial.print("pos: ");
    Serial.println(pos);
    prntIt();
    }
  }
}
void prntIt()
{
  Serial.print("  degrees = "); 
  Serial.print(servo.read());
  Serial.print("\t");
  Serial.print("microseconds =  ");
  Serial.println(servo.readMicroseconds());
}

Are they all the same make and model?

All the behaviour you describe with servo #3 seems consistent with its being a continuous rotation servo.

a7

Yes, bought them all through amazon as a single package. They are SG90s. I was actually able to take apart the model and take it out and replace it. Going to test it thoroughly before I close it up.

Previously I was running the servo's off of the same power supply the arduino was recieving, 2x3.7v AA batteries. Instead now I'm going to give these servos their own dedicated 2x3.7v batteries with common ground to the arduino and a DC stepdown to ensure I'm getting 5.5v.

I'm guessing I somehow damaged the servos, i'm really not sure.

If you feel like investigating, this video shows how the servo works by modifying parts of a servo.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.