Servo control

From OpenCircuits
Jump to: navigation, search



            [ encoder ]-+-(rc ppm)->-[RF modulator]--antenna
 joystick---|           |
    +-------|           +-(rc ppm)->-[buddy box connector]

   antenna--[RF demodulator]->-(rc ppm)->-[decoder]
                                                  |-(rc pwm)->-servo1
                                                  |-(rc pwm)->-servo2
                                                  |-(rc pwm)->-servo3
                                                  |-(rc pwm)->-servo4


Many (perhaps most) radio control transmitters multiplex all the "RC PWM" channels into a single physical wire, using a system called "RC PPM" (radio-control pulse position modulation). [1] [2] [3] [4] [5] [6] [7]

Often this "PPM" signal is transferred from the a student's RC transmitter through the buddy box wire to the teacher's RC transmitter. (see "PPM2USB - RC PPM to USB-Adapter" and "R/C buddy box plugs/ pin assignment" for a variety of "standard" connectors for this buddy box wire).

The "combined signal" -- the "RC PPM signal" -- looks something like this (based on diagram from Richard J. Prinz[8]): [9] [10] [11] [12] [13] [14] [15] [16]

   "RC PPM signal"
   Sync    1       2     3     4        5    6    7   8   Sync...
   ---+ +----+ +------+ +-+ +-------+ +--+ +--+ +--+ +-+ +----...
      | |    | |      | | | |       | |  | |  | |  | | | |
      | |    | |      | | | |       | |  | |  | |  | | | |
      | |    | |      | | | |       | |  | |  | |  | | | |
      +-+    +-+      +-+ +-+       +-+  +-+  +-+  +-+ +-+
       *      *        *   *         *    *    *    *   *
    * - low separator pulse, always 0.5 ms
    1..8 - high "RC PWM pulse" for channels 1..8      0.5 – 1.5 ms

Is decoded to:

       "RC PWM signal"
                |        |
                |        |
                |        |
       ---------+        +-------------------------------------...
                         |   |
                         |   |
                         |   |
       ------------------+   +--------------------------------...
    2: - high "RC PWM pulse" as sent to servo 2.      1.0 – 2.0 ms
    3: - high "RC PWM pulse" as sent to servo 3.      1.0 – 2.0 ms
    etc. for all 8 channels.

(FIXME: tweak illustrations to show at least 2 complete cycles?)

The long "sync pulse" between frames is typically at least 5 ms long. All the other pulses are no more than 2 ms long. Most transmitters have a fixed frame rate somewhere in the range of 40 Hz to 200 Hz.

While most servos use 1.5 ms as the neutral centered position, some servos have a wider range and require 0.5 to go all the way counterclockwise, and 2.5 ms to go all the way clockwise.

When the pilot moves the positions of the joysticks on the transmitter, the width of the corresponding "RC PWM pulse" for that channel will grow proportionally longer or shorter. (The Phillips NE5044 is a typical RC encoder).

The corresponding radio control receiver decodes the radio signal to a RC PPM signal on a single physical wire.

Often the receiver includes either a 4017 decade counter[17] or a 4015 shift register -- that chip decodes the RC PPM signal at its CLK input into to several independent "RC PWM" outputs. The various RC servos[18] are connected to those outputs with standard 3-pin connectors with 0.1" spacing. The RC PWM signal on the "signal" wire of the 3-wires coming out of the servo has a pulse width that typically varies from 1.0 ms to 2.0 ms (proportional to the position of the joystick), but only one pulse for each frame.

(The standardized "RC PWM" works differently enough from the PWM used to control DC motor speeds that some people say that RC PWM signals "are not really PWM signals" [19] [20] [21] [22] [23]. [24] Alas, none of those people give any suggestions as to what we *should* call these signals, so I call them "RC PWM signals" for lack of a better name. Perhaps I should call them "RC control signals"[25] ?).

"I have been campaigning for years on this forum to avoid calling the servo pulses PWM because analogWrite is the way Arduino produces PWM and driving a servo using Arduino analogWrite can destroy servos. ... Avoiding references to PWM controlling servos should help reduce confusion with the output from analogWrite, so I will continue to evangelize the use of PPM to refer to servo signals." -- mem[26] [27]

If two transmitters are transmitting at the same time, then yes, there will be an overlap of pulses. However, people at RC flying parks are very careful to assign each pilot (and the transmitter and receiver he uses) a different "frequency channel", so that the receiver in each airplane can easily pick out the signal from its own transmitter and ignore the radio signals from every other transmitter.

A 6-channel receiver uses only one "frequency channel", but it has 6 output channels (6 servo channels), i.e., it has 6 rows of output pins for up to 6 servos to plug into -- typically one channel each for pitch(elevator), roll(aileron), yaw(rudder), throttle, and some optional AUX channels.

During a single RC frame, the a 6-channel receiver cycles through every servomotor, putting one "RC PWM" pulse at a time on each of its 6 outputs. Only one of its outputs is ever active at any one time -- there is no overlap of its pulses.

((Add illustration of the below text here))

With a typical 50 Hz 6-channel transmitter and receiver, the first "separator pulse" occurs at a fixed width and position every 20 ms. All the other pulses start wherever the last pulse left off, which changes every time the control stick for that previous pulse(s) moves.

With a typical 50 Hz 6-channel transmitter, when all the control sticks are pushed to turn all the servos all the way counterclockwise, the receiver spits out

  • a 1 ms pulse on channel 1, then -- as soon as that finishes -- a 1 ms pulse on channel 2, for all 6 channels -- a total of 6 ms -- and the (relatively long) sync pulse is however long it needs to be to fill out the rest of the 20 ms frame.

When all the control sticks are pushed to turn all the servos all the way clockwise, the receiver spits out

  • a 2 ms pulse on channel 1, then -- as soon as that finishes -- a 2 ms pulse on channel 2, for all 6 channels -- a total of 12 ms -- and the (much shorter) sync pulse is however long it needs to be to fill out the rest of the 20 ms frame.

The servomotor case contains a gearhead motor, a small motor driver circuit, and a potentiometer used to measure the position of the output shaft. Often the circuit consists of a single chip and a few transistors, resistors, and capacitors. The H-bridge handles the high current required to drive the motor. (Darren SAWICZ, "Hobby Servo Fundamentals" [28] ). The chip in a servomotor case is often (?) a Mitsubishi M51660L, RS ZN409 / GEC PLESSEY ZN409CE, KC2462 to KC8801, NE544, NJM2611, MC33030, etc. [29] [30]

continuous rotation servos

(say a few words here about servos modified for continuous rotation)

Martin Locker. "Servo-encoder: odometry sensor for a simple robot". 2006.

I have an Arduino, and I want to see these servos turn

Have you tried the servo.write(angle) command?

The Sweep tutorial shows how to use servo.write(angle) -- part of the Servo library. (formerly called the MegaServo library[31] ).

"driving a servo using Arduino analogWrite can destroy servos." -- mem[32][33]


  • Tom Igoe. "Servo motor control with an Arduino". 2014.[34]
  • "ServoTimer2 - drives up to 8 servos"[35]
  • "Help with PWM for controlling servos and electronic speed controllers (ESCs)"[36] lists many different libraries designed to drive servos, each with a few features the other one doesn't have.
  • "How does a servo work (PWM or PPM)?"[37]

If you want to control more than a few servos, it's often easier to generate something like a full "RC PPM signal" on one Arduino pin and use a separate cheap chip to separate it into individual "RC PWM signals":

  • ... (FIXME: write up some more details on controlling multiple servos with a single Arduino pin, or link to some other page with those details) ...

(Is there a better page elsewhere on OpenCircuits for General Arduino PWM?)

General Arduino PWM:

  • Ken Shirriff."Secrets of Arduino PWM".[38] lists many different ways to persuade an Arduino to produce PWM. Any one of them could be used for generating a "RC PWM" signal; a few of them could be used to generate the "RC PPM" signal.

( The "LED PWM" used to make LEDs appear to dim and brighten, and set a variety of colors with RGB LEDs, has some significant differences from the "RC PWM" used to make servos move. But is there some way we could adapt such libraries to drive servos?: "ShiftPWM: the easiest software PWM library for Arduino. Control many PWM outputs with only 3 Arduino pins." [39] [40] [41] [42] )

I have a RC receiver, and I want to connect one of its outputs to an Arduino

Have you tried the pulseIn() command?


  • "Read PWM Signal from a RC-Receiver"[43].
  • "3 axis auto stabilized platform"[44]
  • "Reading PWM signals from a remote control receiver with Arduino"[45]
  • "Reading servo PWM with an Arduino"[46]
  • "Read PWM value of a RC rx with an arduino"[47]
  • "How to read PWM from Rx with Arduino UNO?"[48]
  • "connecting an RC receiver to your Arduino"[49]
  • "Arduino Demo: PWM Input"[50]
  • RCArduino: "How To Read Multiple RC Channels" (has a discussion of "volatile")[51]

I have a RC receiver, and I want to connect multiple outputs to an Arduino

If you are trying to listen to *more* than 1 output of the RC radio reciever, it's often easier for the Arduino to decode the PPM signal on a single wire than try to decode multiple "PWM" signals on several wires:

  • Jordi Muñoz. "How to hack the PPM signal from any receiver (Futaba) with Arduino"[52] via "Intercept PPM signal from any receiver with Arduino"[53]
  • "Decoding Radio Control signal pulses"[54]


The people at the OpenServo project have developed an open hardware motor driver circuit that fits inside a typical servomotor case. The OpenServo includes an Atmel AVR microcontroller, feedback of position, speed, voltage, and power, and other features not commonly found in a servo. [55]


Moti is a smart servo motor that includes an Arduino compatible Atmel AVR microcontroller, full-turn position tracking, and other features not commonly found in a servo. Like OpenServo, Moti supports a daisy chain of servos which simplifies wiring. [56] [57]

Further reading

  • Jan's article "Servo control interface in detail" has some good o'scope photos showing pulse trains (the "RC PWM signal") going to a single servo, and the current that servo pulls in response.[58]
  • While servos are convenient low-cost modules that generally do what you tell them to do, some people have an insatiable curiosity about what's really going on inside that mysterious black box, or perhaps you want to add some electronics to some big dumb motor to make it "act like" a servo -- if you are one of those people, perhaps you would be interested in the motors and motor driver articles.
Personal tools