Servo pulse width range with Arduino

I recently bought a couple of cheap MG996R high-torque servos on ebay, and I want to use them with my Arduino.

Arduino + MG996 + Dusty Breadboard

These have the “JR” servo pinout, so orange = signal, red = V+, brown = V-.

You control these servos by sending a 50Hz pulse width modulated signal. The pulse width determines the position of the servo. Arduino wraps this in a nice Servo library. So you can just use servo.write(<angle>) to set the servo to a certain angle. Cool!

The servo library defaults to pulsing 544ms to 2400ms for angles zero to 180. This is too wide for the MG996R, the servo only moves when you write angles through 20-150 or so. Setting the value outside this range stresses the servo and can wear it out!

I wrote a quick sketch to interactively find the real minimum and maximum values: . You just watch the serial port and follow simple prompts:

Download the sketch here.

Servo Range Sketch (running)

Using that sketch, I found my MG996R servos to have minimum pulse width around 771 and maximum around 2193 when running off 5v1. The full sweep is approximately 0-130 degrees.

So, to use the servo library with correct angles the sweep will be 771 to 17982. So I can call:

servo.attach(servopin, 771, 1798);
servo.write(0); // Min
delay(2000);
servo.write(65); // Midpoint
delay(2000);
servo.write(130); // Max

Yay Arduino!

  1. While the servo is unloaded I’m powering it from the Arduino via USB, but this won’t supply enough current for a loaded servo. []
  2. The adjusted max of 1798 is calculated as ( (MaxPW – MinPW) * (MaxAngle / 180) ) + MinPW, ie ( (2193 – 771) * (130 / 180) ) + 771 []
 

Leave a Reply

Powered by WP Hashcash