[Solved] TowerPro MG995 broken? Very strange behavior ...

EDIT-1: The solution to the problem is (partly) given in my next post (#7).
EDIT-2: A pin / wiring layout of this (small) project is given in post #13 and #14.

Hello all,

I am encountering strange behavior when connecting a TowerPro MG995 to my Arduino UNO. I've tried many setups, e. g., connecting it directly to the Arduino or using a potentiometer to control the final position of the servo---always with the same behavior: The servo roughly drives to the commanded position but than moves back randomly. Using a for-loop to let the servo occupy all possible angles (0-179°), was weird too: At first, the motions were comparable to the first test case (moving back and forward) but after some seconds the servo stopped moving at all (just a humming noise when a new position was send by the Arduino). Note that I am using the (default) "Servo"-Arduino library.

I've uploaded a video demonstrating this behavor (using the "poti-setup"). You can download it here. The code for this setup is as follows (taken from here):

#include <Servo.h>

Servo myservo;

int potpin = 0;
int val;

void setup()
{
   myservo.attach(9);
}

void loop()
{
   val = analogRead(potpin);
   val = map(val, 0, 1023, 0, 179);
   myservo.write(val);
   delay(15);
}

Additionally, I've tried the following:

  • Used an external power plug: The servo appeared to be more reactive but the overall "strange" behavior was the same.
  • Connected another servo (TowerPro SG90): This servo worked well. Using the "poti-setup", I was able to set the position of the servo using the poti (as expected).

Does anyone have any idea what the problem is? I am assuming that the servo devices (BTW: both servos I am owning have this problem, except for the SG90) are simply broken ...? Any hints / suggestions are highly appreciated!

Thanks in advance!

Best regards,
CodeFinder

PS: I have another video showing the (working) result of connecting the SG90. If you need it, I can upload it as well. If you need more information, just ask me.

Does anyone have any idea what the problem is? I am assuming that the servo devices (BTW: both servos I am owning

You need to use an external power supply similar to the below. Large servos cannot be powered from the arduino without crashing the arduino.

servo-wire.jpg

Hi, zoomkat, you are going to wear that file out eventually.

Tom...... :slight_smile:

Are you using digital pin 0 to read a analog value from a pot. :o
You should also use pinMode to declare the pin an input.

Assuming those aren't the cause of your issues, sounds like either no grounding or intermediate grounding between external power supply and arduino, or you have a very sloppy feedback on your servo.

harddrive123:
Are you using digital pin 0 to read a analog value from a pot. :o
You should also use pinMode to declare the pin an input.

BZZZZT.... wrong on both counts hd123.

The code below produced the attached output.

// test pot on analog 1

void setup()
{
  Serial.begin(9600);
  Serial.println("Starting....");
}

void loop()
{
  Serial.println(analogRead(0));
  delay(1000);
}

analogpin.JPG

TomGeorge:
Hi, zoomkat, you are going to wear that file out eventually.

Tom...... :slight_smile:

Yes, but it saves so much typing, especially when the OP will probably say something like "I am using an external power supply, I'm using a 9v battery connected to the arduino barrel jack!".

Clearly pin 0 is an analog if it works. Usually A0 is used for analog pin 0.

You don't need to use pinMode when using it as a input, but you should.

Thanks for all the replies (zoomkat's in particular)! I've managed to get it working. :slight_smile: The following code controls two servos (of type "TowerPro MG995") using an (external) "power circuit" (some more information and links are given in the comments of the code for posterity):

// ------------------------------------------------------------------------------
// This code shows how to control two servos of the "pan-tilt-construction kit"
// available on eBay (see http://www.ebay.de/itm/161296853624).
// For connecting high power (or simply many) servos to the Arduino, see also:
// http://rcarduino.blogspot.de/2012/04/servo-problems-with-arduino-part-1.html
// ------------------------------------------------------------------------------
// Created by CodeFinder on 30th of December 2014.
#include <Servo.h>


#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))

Servo panServo, tiltServo;

#define PAN_SERVO_PIN   5 // "rotation"
#define TILT_SERVO_PIN  6 // "moving up and down"

// Servo- / application-specific constants:
#define MOTION_DELAY       20
#define MIN_ANGLE_PAN       1
#define MAX_ANGLE_PAN     178
#define MIN_ANGLE_TILT      1
#define MAX_ANGLE_TILT    129
// With respect to the product (see above), these angles depend on how the kit is
// actually being assembled. You may need to adapt these values appropriately.

void setup()
{
	panServo.attach(PAN_SERVO_PIN);
	tiltServo.attach(TILT_SERVO_PIN);
}

void loop()
{
	static const uint16_t MIN_ANGLE = min(MIN_ANGLE_PAN, MIN_ANGLE_TILT);
	static const uint16_t MAX_ANGLE = max(MAX_ANGLE_PAN, MAX_ANGLE_TILT);

	for (int i = MIN_ANGLE; i <= MAX_ANGLE; ++i) {
		panServo.write(map(i, MIN_ANGLE, MAX_ANGLE, MIN_ANGLE_PAN,  MAX_ANGLE_PAN));
		tiltServo.write(map(i, MIN_ANGLE, MAX_ANGLE, MIN_ANGLE_TILT,  MAX_ANGLE_TILT));
		delay(MOTION_DELAY);
	}
	delay(1000);
	for (int i = MAX_ANGLE; i >= MIN_ANGLE; --i) {
		panServo.write(map(i, MIN_ANGLE, MAX_ANGLE, MIN_ANGLE_PAN,  MAX_ANGLE_PAN));
		tiltServo.write(map(i, MIN_ANGLE, MAX_ANGLE, MIN_ANGLE_TILT,  MAX_ANGLE_TILT));
		delay(MOTION_DELAY);
	}
	delay(1000);
}

As the code comments state, I've used it as a starting point to control a "2 DOF Pan and Tilt With MG995 Servos Sensor Mount for Arduino Robot DIY" available on eBay (see here). Maybe it is helpful to someone else, too. :wink:

However, there is still one weird issue: As you can see from the code and this video, the code commands the servo to move forwards and backwards with a delay of 1s. Sometimes (!), the servos stop (somehow randomly) at the end of both for-loops and creates a humming noise (probably like described in this post). Then, sometimes and after some (random?) time, the servos continue to move (sometimes as desired, but sometimes "too quickly"). Re-connecting the Arduino's USB (= power) connection solves this issue. Is this a (PWM-related) timing problem "encapsulated" in the Servo library? (Side note: The problem occurs in the very end of the video linked above. Unfortunately, I've pressed the "stop record" button too quickly so that you just can see the start of the stopping servos.)

Any other ideas for this behavior? Thanks! :wink:

Servo's use ppm not PWM, they are similar in design but the key difference is with ppm the high time is the only part that matters, where PWM is more of a ratio of high and low time over a period of time.

If its getting jittery and moves randomly over small distances as I said before, my guess is that its the servo and its position control is sloppy/poor quality.

It gets within a few degree's of the set-point but because the distance is so small the force applied so to small to overcome at rest friction. The motor while stalled builds up a magnetic field, eventually pushes past the friction and but because the built up release is greater then the initial input, it over shot by a few degree's, now it has to come back. Repeat.

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?
As well as a picture of your project please'

Thanks..Tom....... :slight_smile:

Servo's use ppm not PWM,

I think the general consensus is that PPM is used between an RC transmitter and RC receiver, as the servo being targeted is a function of the position of the pulse in the pulse train being transmitted between the tx/rx. The RC receiver sends pulses of a certain pulse width to the servo, which the servo electronics translates to a typical PWM control signal to the H-bridge contained in the servo.

Re-connecting the Arduino's USB (= power) connection solves this issue.

Sounds like you are trying to power the servos and the arduino from the same power supply when the problem occurs.

harddrive123:
Servo's use ppm not PWM, they are similar in design but the key difference is with ppm the high time is the only part that matters, where PWM is more of a ratio of high and low time over a period of time.

I said exactly that, here, and got some interesting comments.

zoomkat:
The RC receiver sends pulses of a certain pulse width to the servo, which the servo electronics translates to a typical PWM control signal to the H-bridge contained in the servo.

I might sacrifice a cheap servo (oh wait, I have only cheap ones...) and see if I can grab the internal signal on one 'scope channel to see that in action.

Meantime, OP might be interested to see how the pulse is on a 50Hz cycle by default, attached. However, that 20ms refresh may be changed: it's the variable REFRESH_INTERVAL in servo.h, and the second trace shows it as 10ms with a frequency of 100Hz.

servo attached.jpg

10ms servo refresh.jpg

Interesting insights. 8) I would have also bet on poor build quality of the (china :wink: ) servos.

TomGeorge:
[...]
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?
As well as a picture of your project please'
[...]

Have you seen the video I've uploaded ( Zippyshare.com - [now defunct] Free File Hosting )?

Additionally, please find attached some more annotated photos.

zoomkat:
Sounds like you are trying to power the servos and the arduino from the same power supply when the problem occurs.

I don't think so. See the photos attached. :wink:

Additionally, here is a schematic figure (created with Fritzing) showing the wiring and pin layout. Hope that helps anyone else. :wink:

I don't think so. See the photos attached.

Why do you have the wall wart selected to 4.5v when the minimum recommended voltage for the servos is probably 4.8v? How many ma does the wall wart put out? 2000ma would be a good value for the two servos if they have to move a load. Use your multimeter to measure the actual voltage being supplied to the servos when they are being moved.

First of all, happy new year and all the best for 2015!

zoomkat:
Why do you have the wall wart selected to 4.5v when the minimum recommended voltage for the servos is probably 4.8v? [...]

Because it can only provide 1.5V, 3V, 4.5V, 6V, 7.5V, 9V, or 12V (discrete steps). And 4.5V was simply the closest match. :wink: 6V was too much (tested shortly: caused weird behavior of the servos).

zoomkat:
[...] How many ma does the wall wart put out? 2000ma would be a good value for the two servos if they have to move a load. Use your multimeter to measure the actual voltage being supplied to the servos when they are being moved.

I don't have the circuit at hand but anyways: I am currently having no other power supplies to try the recommended voltage of 4.8V. (I've ordered a power supply unit with adjustable voltage output which hasn't arrived yet.) Note that the "pan"-servo's load is simply the "tilt"-servo which iteself has no load (just the negligible (?) mount plate, see photos / videos). Interestingly, the label on the power supply states an output of 270 mA when "4.5V" is selected. Can this possibly be not sufficient?

Thanks again for your help! 8)

hi i use the same servos , and i want to make a robotic arm with 3 servos, i use arduino uno and matlab. my problem is that the angles that im giving is not exactly correct . servos are from 0-180 but i think that does more than 180 degrees. i want to working from 0-180 exactly and do all angles correct,does anyone knows how to make it?

Hi xoustoulios! I do not know exactly the source of your problem, but I can say something that I used on a project I worked on.

I disassembled a servo motor and solder a wire, which is similar to a coaxial cable, with its internal potentiometer. Once the shield of the wire is connected to the common ground, this wire connected into an analog input would provide a reference of the servo position.

I would recommend you to use the sweep function ranging the servo from 0 to 180 degrees and verify this analog reference to see how it behavior. Maybe you can send to the servo a different output to reach the desired angle. Use this value as an advantage to calibrate the output angles as well to measure where the arm joint is positioned.

With these values calculated, use the map function (https://www.arduino.cc/en/Reference/Map) to adapt to the correct range. Be aware of the limitation angles of your robot. The high increase, for instance from 0 to 180, could break your robot due to the high speed of the extremity of an arm.

If you desire I could post some pictures of how I did the solder.

CodeFinder:
EDIT-1: The solution to the problem is (partly) given in my next post (#7).
EDIT-2: A pin / wiring layout of this (small) project is given in post #13 and #14.

Hello all,

I am encountering strange behavior when connecting a TowerPro MG995 to my Arduino UNO. I've tried many setups, e. g., connecting it directly to the Arduino or using a potentiometer to control the final position of the servo---always with the same behavior: The servo roughly drives to the commanded position but than moves back randomly. Using a for-loop to let the servo occupy all possible angles (0-179°), was weird too: At first, the motions were comparable to the first test case (moving back and forward) but after some seconds the servo stopped moving at all (just a humming noise when a new position was send by the Arduino). Note that I am using the (default) "Servo"-Arduino library.

I've uploaded a video demonstrating this behavor (using the "poti-setup"). You can download it here. The code for this setup is as follows (taken from here):

#include <Servo.h>

Servo myservo;

int potpin = 0;
int val;

void setup()
{
  myservo.attach(9);
}

void loop()
{
  val = analogRead(potpin);
  val = map(val, 0, 1023, 0, 179);
  myservo.write(val);
  delay(15);
}




Additionally, I've tried the following:

- Used an **external power plug**: The servo appeared to be more reactive but the overall "strange" behavior was the same.
- Connected **another servo** ([TowerPro SG90](http://www.servodatabase.com/servo/towerpro/sg90)): This servo **worked well**. Using the "poti-setup", I was able to set the position of the servo using the poti (as expected).


Does anyone have any idea what the problem is? I am assuming that the servo devices (BTW: both servos I am owning have this problem, except for the SG90) are **simply broken ...?** Any hints / suggestions are highly appreciated!

Thanks in advance!

Best regards,
CodeFinder

PS: I have another video showing the (working) result of connecting the SG90. If you need it, I can upload it as well. If you need more information, just ask me.

I got the same MG995 servo and unable to rotate it to a particular position either.

Then I finally figured it out after checking the specification. Extra care on the power supply
design too. Totally not recommended to use power output from arduino itself. The Halt current
is 1.5A! Here check the youtube video explaining it: https://youtu.be/oOm4Zm79sCg

If you don't want to see the video, basically MG995 is not a positioning servo
but it is continuous servo, so you only can control the rotation direction clockwise or anticlockwise,
its speed or stop it completely.