Robotic Arm - Servo Motor Problem

Hi guys,
I have problem with my project (I am using Arduino Uno R3).
I am working on a robotic arm with 7 servos controlled by 5 potentiometers.
Problem is, that all servos acting really weird after I turn the switch on (I have Arduino permanently attached to the power supply and then with switch on the controller I can turn on or off all servos).
I don't know how to explain that "weird behaviour" - PLEASE WATCH VIDEO.

All servos on start have to be "freezed" or they shouldn't be moving - How I can do that ?

Sorry for labels I have them in my native language, and sorry for video I had to made like that. :slight_smile:

Video

Arduino Code

#include <Servo.h>
#define DEFAULT_PULSE_WIDTH  1500    // standartní ší?ka pulzu, když je p?ipojené servo

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
Servo servo7;

int hodnota1 = 0;
int hodnota2 = 0;
int hodnota3 = 0;
int hodnota4 = 0;
int hodnota5 = 0;
int hodnota6 = 0;
int hodnota7 = 0;
 
int Potenciometr1 = 0; 
int Potenciometr2 = 1;
int Potenciometr3 = 2;
int Potenciometr4 = 3;
int Potenciometr5 = 4;

int servo1Pin = 3;
int servo2Pin = 5;
int servo3Pin = 6;
int servo4Pin = 9;
int servo5Pin = 10;
int servo6Pin = 11;
int servo7Pin = 13;

void setup() 
{ 
 servo1.attach(servo1Pin);
 servo2.attach(servo2Pin);
 servo3.attach(servo3Pin);
 servo4.attach(servo4Pin);
 servo5.attach(servo5Pin);
 servo6.attach(servo6Pin);
 servo7.attach(servo7Pin);
} 
 
void loop() 
{ 
 hodnota1 = analogRead(Potenciometr1);
 hodnota1 = map(hodnota1, 0, 1023, 0, 179);
 servo1.write(hodnota1);

 
 hodnota2 = analogRead(Potenciometr2);
 hodnota2 = map(hodnota2, 0, 1023, 0, 179);
 servo2.write(hodnota2);

 
 hodnota3 = analogRead(Potenciometr3);
 hodnota3 = map(hodnota3, 0, 1023, 0, 179);
 servo3.write(hodnota3);

 
 hodnota4 = analogRead(Potenciometr4);
 hodnota4 = map(hodnota4, 0, 1023, 0, 179);
 servo4.write(hodnota4);

 
 hodnota5 = analogRead(Potenciometr5);
 hodnota5 = map(hodnota5, 0, 1023, 0, 179);
 servo5.write(hodnota5);

 
 hodnota6 = analogRead(Potenciometr2);
 hodnota6 = map(hodnota6, 0, 1023, 0, 179);
 servo6.write(hodnota6);

 
 hodnota7 = analogRead(Potenciometr3);
 hodnota7 = map(hodnota7, 0, 1023, 0, 179);
 servo7.write(hodnota7);

 
}

Please Help! =(

There may be two separate issues here.

The servos may be acting in an uncontrolled fashion or run to one extreme of their movement during the time between power being applied and the Arduino sending the first valid signals to them.

The servos may not be at the appropriate "home" position when the Arduino starts. That is, when the arm was last used it was not put back in the home position before everything was switched off.

For one of my servos I found that the first problem is solved by connecting a 4k7 resistor between the signal wire and ground.

The second problem is more complex. One solution may be to build in a shut-down routine to put everything into the home position.

...R

How are your servos powered? Servos used in arms need a large external power supply. Below is some servo test code that you might use to individually test the servos for issues.

// zoomkat 12-25-13 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// Send an a to attach servo or d to detach servo
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include <Servo.h> 
String readString; //String captured from serial port
Servo myservo;  // create servo object to control a servo 
int n; //value to write to servo

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println("servo all-in-one test code 12-25-13"); // so I can keep track of what is loaded
  Serial.println();
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 

      // attach or detach servo if desired
    if (readString == "d") { 
      myservo.detach(); //detach servo
      Serial.println("servo detached");
      goto bailout; //jump over writing to servo
    }
    if (readString == "a") {
      myservo.attach(7); //reattach servo to pin 7
      Serial.println("servo attached");
      goto bailout;
    }    

    n = readString.toInt();  //convert readString into a number

    // auto select appropriate value
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n); 
    }

bailout: //reenter code loop
    Serial.print("Last servo command position: ");    
    Serial.println(myservo.read());
    Serial.println();
    readString=""; //empty for next input
  }
}

zoomkat:
How are your servos powered? Servos used in arms need a large external power supply.

I have external power supply 6V 2250mAh. Ground from arduino and power supply for servos are connected together.

Here is my schematic:
http://imageshack.com/a/img543/7831/oo7y.png

I think it is something wrong with my programme. It is gonna be something really dumb :slight_smile: :slight_smile:

Thx for the test code.

Some servo/pot test code from the past that is set up for printing to the serial monitor to see if the expected results are being achieved.

//zoomkat multi pot/servo test 3-23-13
//includes dead band for testing and limit servo hunting
//view output using the serial monitor

#include <Servo.h> 
Servo myservo1;  //declare servos
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;

int potpin1 = 0;  //analog input pin A0
int potpin2 = 1;
int potpin3 = 2;
int potpin4 = 3;
int potpin5 = 4;

int newval1, oldval1;  //pot input values
int newval2, oldval2;
int newval3, oldval3;
int newval4, oldval4;
int newval5, oldval5;

void setup() 
{
  Serial.begin(9600);  
  myservo1.attach(2);  
  myservo2.attach(3);
  myservo3.attach(4);
  myservo4.attach(5);
  myservo5.attach(6);
  Serial.println("testing multi pot servo");  
}

void loop()
{ 
  newval1 = analogRead(potpin1);           
  newval1 = map(newval1, 0, 1023, 0, 179); 
  if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){ //dead band 
    myservo1.write(newval1); //position the servo
    Serial.print("1- ");
    Serial.println(newval1); //print the new value for testing 
    oldval1=newval1; //set the current old value
  }

  newval2 = analogRead(potpin2);
  newval2 = map(newval2, 0, 1023, 0, 179);
  if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){  
    myservo2.write(newval2);
    Serial.print("2- ");    
    Serial.println(newval2);
    oldval2=newval2;
  }

  newval3 = analogRead(potpin3);           
  newval3 = map(newval3, 0, 1023, 0, 179); 
  if (newval1 < (oldval1-2) || newval3 > (oldval3+2)){  
    myservo1.write(newval3);
    Serial.print("3- ");
    Serial.println(newval3);
    oldval3=newval3;
  }

  newval4 = analogRead(potpin4);           
  newval4 = map(newval4, 0, 1023, 0, 179); 
  if (newval1 < (oldval1-2) || newval4 > (oldval4+2)){  
    myservo1.write(newval4);
    Serial.print("4- ");
    Serial.println(newval4);
    oldval4=newval4;
  }

  newval5 = analogRead(potpin5);           
  newval5 = map(newval5, 0, 1023, 0, 179); 
  if (newval1 < (oldval5-2) || newval5 > (oldval5+2)){  
    myservo1.write(newval5);
    Serial.print("5- ");
    Serial.println(newval5);
    oldval5=newval5;
  } 
  delay(50);  //to slow loop for testing
}

I think I found the source of the problem.
Is it supposed to happend, that If I turn on the switch, the voltage on signal wire fall even below 0V (something about -0,1), standart voltage on signal wire is about 0,17V - after the shaking stops.
I don't think that supposed to happend. Right?

Have you tried putting a resistor between the signal wire and ground wire as I suggested earlier?

...R

Robin2:
Have you tried putting a resistor between the signal wire and ground wire as I suggested earlier?

Not yet, but I will try that, it is good idea!
It may help with that interference on the signal wire.
I will give info after I try that.

Hi guys, I am back.
So I did what I did and somehow it seems to be ok, but now I have another problem :smiley:
I think it is just because I don't have any "delay();" in my program, but I have to be sure.
Where I have mistake? It is only because I don't have delay?

VIDEO

MY FINAL CODE

#include <Servo.h>
#define DEFAULT_PULSE_WIDTH  1500    // standartní ší?ka pulzu, když je p?ipojené servo

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
Servo servo7;

int hodnota1 = 0;
int hodnota2 = 0;
int hodnota3 = 0;
int hodnota4 = 0;
int hodnota5 = 0;
int hodnota6 = 0;
int hodnota7 = 0;
 
int Potenciometr1 = 0; 
int Potenciometr2 = 1;
int Potenciometr3 = 2;
int Potenciometr4 = 3;
int Potenciometr5 = 4;

int servo1Pin = 3;
int servo2Pin = 5;
int servo3Pin = 6;
int servo4Pin = 9;
int servo5Pin = 10;
int servo6Pin = 11;
int servo7Pin = 13;

void setup() 
{ 
 servo1.attach(servo1Pin);
 servo2.attach(servo2Pin);
 servo3.attach(servo3Pin);
 servo4.attach(servo4Pin);
 servo5.attach(servo5Pin);
 servo6.attach(servo6Pin);
 servo7.attach(servo7Pin);
} 
 
void loop() 
{ 
 hodnota1 = analogRead(Potenciometr1);
 hodnota1 = map(hodnota1, 0, 1023, 0, 179);
 servo1.write(hodnota1);
 
 hodnota2 = analogRead(Potenciometr2);
 hodnota2 = map(hodnota2, 0, 1023, 0, 179);
 servo2.write(hodnota2);
 
 hodnota3 = analogRead(Potenciometr2);
 hodnota3 = map(hodnota3, 0, 1023, 0, 179);
 servo6.write(hodnota3);
 
 hodnota4 = analogRead(Potenciometr3);
 hodnota4 = map(hodnota4, 0, 1023, 0, 179);
 servo3.write(hodnota4);
 
 hodnota5 = analogRead(Potenciometr3);
 hodnota5 = map(hodnota5, 0, 1023, 0, 179);
 servo7.write(hodnota5);
 
 hodnota6 = analogRead(Potenciometr4);
 hodnota6 = map(hodnota6, 0, 1023, 0, 179);
 servo4.write(hodnota6);
 
 hodnota7 = analogRead(Potenciometr5);
 hodnota7 = map(hodnota7, 0, 1023, 0, 179);
 servo5.write(hodnota7);
}

Do you know if your servos are actually capable of moving 180 degrees ?

Yes I am pretty sure. They can even move little bit over 180 degrees.

but now I have another problem smiley-grin

You really need to give a written description of what you are doing and the failure you are experiencing. Is the problem encountered when the arm is powered up, when you try to move a single servo, more than one servo, etc? It looks like a possible power issue where when a servo tries to move, the voltage to the arduino drops too low causing the arduino to reset.

All servos are conected, power supply is 6V 2500mA. Pots is not in control (they are set to one position).
I think the power supply have enought amp, or not? But at the beginning of this project I tested all the servos and this behaviour was the same like when I have all the servos powered from arduino (yeah, I was dumb). But now they have separated power supply so I don't think that this is the same issue like before. Maybe the whole arm is heavy, so the servos want more amps for moving. Btw. servos can move with weight up to 10kg.

VlcekCZ:
So I did what I did and somehow it seems to be ok, but now I have another problem :smiley:
I think it is just because I don't have any "delay();" in my program, but I have to be sure.
Where I have mistake? It is only because I don't have delay?

"I did what I did" is probably the most accurate statement in the universe but it's not great at conveying information :slight_smile:

What problem have you now?
And why do you think the absence of a delay() might be the cause?
Where do you think the delay should go?

Taking the trouble to describe the problem clearly (rather than showing a video) may help you to realize what is the cause of the problem.

...R

So, what I did is that I put 4k7 resistor between the signal wire (from servo) and the ground for stable signal to servo.
Everything else is the same like before (except the program, I changed it for the final version).
But the issue is now that the arduino gives to servos delayed signal (like on the video), I think it might be, because it is not enought amps from the power supply. But I am not sure. Now I use 6V with 2500mA for whole project - I think it is enought, but what else it could be, right?

Below is some servo test code you can to test individual servos (change the servo pin # in the code as needed) using the serial monitor. Are your batteries charged? Measure the battery output voltage with a multimeter when the servos are under load.

Pots is not in control (they are set to one position).

This could result in all servos trying to move at the same time causing an under voltage condition. Is the arduino powered from the USB port and the servos from the batteries?

// zoomkat 12-25-13 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// Send an a to attach servo or d to detach servo
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include <Servo.h> 
String readString; //String captured from serial port
Servo myservo;  // create servo object to control a servo 
int n; //value to write to servo

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println("servo all-in-one test code 12-25-13"); // so I can keep track of what is loaded
  Serial.println();
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 

      // attach or detach servo if desired
    if (readString == "d") { 
      myservo.detach(); //detach servo
      Serial.println("servo detached");
      goto bailout; //jump over writing to servo
    }
    if (readString == "a") {
      myservo.attach(7); //reattach servo to pin 7
      Serial.println("servo attached");
      goto bailout;
    }    

    n = readString.toInt();  //convert readString into a number

    // auto select appropriate value
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n); 
    }

bailout: //reenter code loop
    Serial.print("Last servo command position: ");    
    Serial.println(myservo.read());
    Serial.println();
    readString=""; //empty for next input
  }
}

I am not using batteries, I am using wall adapter. Arduino and all servos are powered from one power supply, but it is seperated (servos are connected directly to the power supply, not through arduino. Grounds are connected together). The voltage on the power supply is normally 6,12V and when it is under load it drops to 6,03V (lowest was 5,98V).

I'd say your wall adapter is not sufficient to power all the servos and the arduino at the same time. What is the voltage on the arduino 5v pin? Note that if the arduino is being powered via the barrel jack, there will be an additional voltage drop across the voltae regulator. you can use the given test code to test the servos in various positions and measure the voltage drop when the servos are in those positions.

Yeah, I think it is problem with weak power supply too, but it is strange. How it can use more than 2500mA.
The voltage on the 5V pin is normally 4,27V, lowest was 4,24V (under load).

VlcekCZ:
Yeah, I think it is problem with weak power supply too, but it is strange. How it can use more than 2500mA.
The voltage on the 5V pin is normally 4,27V, lowest was 4,24V (under load).

A standard hobby servo can use as much as 1A when under load, and you have seven servos.