Experiences with cheap 4 axis diy robot arm (MG995 Servo) facts and rumours

I recently bought this nice robot arm from ebay for about 100 € :
http://www.ebay.de/itm/380978981094?_trksid=p2057872.m2749.l2649

It comes with 3 Tower Pro MG995 and one MG90 servos, and i tried to control it with a sainsmart Arduino Mega 2560 board. The knob demo application worked fine with one servo when powered via usb/arduino board using pin 10 as servo control output. In order to use all 4 servo´s i connected the + and - (brown and red cables) of the servos directly to an external laboratory psu and the servo control leads (orange) to pwm channel 7-10 of the arduino board, which was powered through usb. I did set the voltage to 6v and the current limit to 1.5 amp. and conected the ground (-) of the laboratory psu and the arduino board.

I used the servo library to move the 4 servo´s :

myservo1-4.write ( value increasing / decreasing between 50 and 90 ) ;
delay (25); // ( see end of mail for code listing )

The robot arm started to move but shaked and rattled randomly to different positions.
By raising the voltage i unfortunately killed 2 of the 3 MG995 servo´s very quickly ;-(

I´ve been reading many posts in various forums now to understand what has happened.
If anybody could help me to distinguish the facts from the rumours i´d be very happy.

  1. People say that the MG995 servo is pure crap, and most ones available today are even worse copies of the crappy originals. They jitter by default. The MG946R is a bit better, but not much. rumour or true ?

  2. the irq handling of the arduino disturbs the pulse width of the control signals send to the servo. It should be better to disable interupts or write your own signal high/low timing code for the pwm outputs.
    rumour or true ?

  3. Everything will work flawlessly if i would use an adafruit servo controll shield. rumour or true ?

thanks for your help.

Arno

code used :

int x1=50;

void setup()
{
myservo1.attach(7);
myservo2.attach( 8 );
myservo3.attach(9);
myservo4.attach(10);

}

void loop()
{

while (x1<90) {

myservo1.write(x1); // sets the servo position according to the scaled value
delay(25); // waits for the servo to get there
myservo2.write(x1); // sets the servo position according to the scaled value
delay(25); // waits for the servo to get there
myservo3.write(x1); // sets the servo position according to the scaled value
delay(25); // waits for the servo to get there
myservo4.write(x1); // sets the servo position according to the scaled value
delay(25);

x1++;
}

delay(3000);

while (x1>50) {

myservo1.write(x1); // sets the servo position according to the scaled value
delay(25); // waits for the servo to get there
myservo2.write(x1); // sets the servo position according to the scaled value
delay(25); // waits for the servo to get there
myservo3.write(x1); // sets the servo position according to the scaled value
delay(25); // waits for the servo to get there
myservo4.write(x1); // sets the servo position according to the scaled value
delay(25);// waits for the servo to get there
x1–;

}
delay(3000);
}

servos directly to an external laboratory psu

I think somebody in the recent past tried using a similar power supply I think for servos and had bad results. I think the problem went away when the lab power supply was ditched for a different type.

Edit, the below may be the discussion. Your limiting to 1.5A is probably the issue.

http://forum.arduino.cc/index.php?topic=319185.msg2208154#msg2208154

It is not relevant to your problem but you only need one of the delay()s in this code

myservo1.write(x1);                  // sets the servo position according to the scaled value 
 delay(25);                           // waits for the servo to get there 
  myservo2.write(x1);                  // sets the servo position according to the scaled value 
 delay(25);                           // waits for the servo to get there 
 myservo3.write(x1);                  // sets the servo position according to the scaled value 
 delay(25);                           // waits for the servo to get there 
myservo4.write(x1);                  // sets the servo position according to the scaled value 
 delay(25);

A single delay() will do for all the servos - but I wonder if 25 millisecs is long enough

If you want a more responsive system you should use millis() (not delay() ) to manage timing as illustrated in several things at a time

...R

Delays should normally not be needed when controlling a servo via a pot (it apparently is an artifact from the servo “sweep” example). Below is some servo/pot test code for a joystick, but should work just as well for pots. You might want to map for 500-2500 instead of 0-179 to ensure full servo movement.

#include <Servo.h>

Servo panServo; // Create a servo object for the pan (horizontal) servo
Servo tiltServo; // Create a servo object for the tilt (vertical) servo
Servo zoomServo; // Create a servo object for zoom (left/right) servo
Servo downServo; // Create a servo obhect for record (down/up) servo

int panPin = 0; // Analog input for the joystick pan axis
int tiltPin = 1; // Analog input for the joystick tiltl axis
int zoomPin = 2; // Analog input for the zoom joystick axis 
int downPin = 3; // Analog input for the down axis

int tiltVal; // Value read from the vertical axis
int panVal; // Value read from the horizontal axis
int zoomVal; // Value read from the zoom axis
int downVal; // Value read from the down axis

void setup()
{
panServo.attach(9); // use pin 9 PWM output for pan servo
tiltServo.attach(10); // use pin 10 PWM output for tilt servo
zoomServo.attach(6); // use pin 6 PWM output for zoom servo
downServo.attach(5); // use pin 5 PWM output for down servo

}

void loop ()
{ 
panVal = analogRead(panPin); // read pan joystick position
panVal = map(panVal, 0, 1023, 0, 179); // scale reading to servo
panServo.write(panVal); //move servo to required position

tiltVal = analogRead(tiltPin); // read pan joystick position
tiltVal = map(tiltVal, 0, 1023, 0, 179); // scale reading to servo
tiltServo.write(tiltVal); //move servo to required postion

zoomVal = analogRead(zoomPin); // read zoom joystick position
zoomVal = map(zoomVal, 0, 1023, 0, 179); // scale reading to servo
zoomServo.write(zoomVal); //move servo to required position

downVal = analogRead(downPin); // read record joystick position
downVal = map(downVal, 0, 1023, 0, 179); // scale reading to servo
downServo.write(downVal); //move servo to required position
}