Pure Analog Servo Control

A Standard Hobby ServoHobby servos, such as the one pictured at right, are wonderfully useful little devices.  You’ll find them moving control surfaces on model planes, in steering linkages on RC cars, and even in the feeding mechanism of an automatic ping-pong ball launcher (one of my simpler college design projects).

Anytime you need something to rotate to a specific position, think of the hobby servo.  They’re fairly low cost, and come in a variety of torque sizes, from tens to hundreds of ounce-inches.

So let’s say you’ve bought yourself a servo from Tower Hobbies (or wherever).  How are you going to control it?  Well, you could purchase a radio and receiver, but if you’re not planning on building your servo into a vehicle of some sort, that’s really overkill (and expensive).  You could program a microcontroller to generate the control signals, but that could get complicated if you’ve never worked with MCUs before.  Instead, what I’d like to discuss today is a purely analog circuit for PWM servo control.

First, let me give you a little background information.  Hobby servos are typically connected by three wires: power (red), ground (black), and signal (yellow/white).   The power and ground lines are typically hooked directly to your battery or power supply.  The signal line, however, is used to command the servo to move to a specific angular position.  This signaling is normally accomplished via pulse-width modulation (PWM).  That is, a digital pulse is sent to the servo on a routine basis (e.g. at 100Hz, or 100 times per second).  The width or duration of this pulse determines the position of the servo’s horn. For instance, a pulse width of 1ms commands a fully clockwise rotation, a width of 2ms commands a fully counter-clockwise rotation, and a width of 1.5ms will center the horn.

Now the question is, how do we generate such a signal?  Why, we simply use the following pulse-width modulator circuit (adapted from Maxim Application Note 3201):

PWM Generator SchematicAlright, so maybe you’re thinking, “Dude, that’s a big circuit.”  Well yea, it sortof is.

But then again, those three op-amps could actually all be housed inside a single 14-pin DIP/SOIC package.  And beyond that, all you need are eight resistors, one capacitor, and one potentiometer (a variable resistor).  So while this may be physically more complex than just plopping down a microcontroller, there’s no software required.

So just how does this circuit create our PWM signal?  Well let’s start with the “Integrator” section.  This group of components (R1, C1, and U1) mathematically integrate or sum the voltage wired into the left terminal of R1 (line label #5).  Put simply, the capacitor C1 is summing up this input voltage over time.  To see how this happens, let’s start by analyzing the node between R1 and C1 (label #2).  Now assuming all of our op-amps are ideal (a fair assumption in most cases), no current will enter or leave their inverting (-) and non-inverting (+) terminals.  Since the current flowing through a series connection of electrical components (R1 and C1) must be equal, we can write the following:

Integrator Equation Derivation

The first half of this formula may look familiar; it’s ohm’s law (V/R = I).  However, we’ve defined the voltage across R1 as (V5 – 2.5).  Why?  This is because the voltage at the input terminals (+ and -) of our ideal op-amp must be equal since we have a negative feedback path (a connection from output to inverting (-) terminal) through the capacitor.  And we know that the voltage at the non-inverting (+) terminal of the op-amp must be 2.5V because of the voltage divider at node #1.  Thus, since C1 is providing a feedback path for the op-amp, we can safely assume that the inverting terminal is also at 2.5V.  The second half of this equation comes from the I-V relationship for capacitors, I = C*dv/dt.

So if we solve this equation for V3, with an initial capacitor voltage of zero, we get:

Integrator Equation DerivationIf we keep the voltage V5 constant, we’re left with just an equation for a straight line.  Basically, the output V3 starts at 2.5V, then ramps linearly up/down, depending on V5, as time (t) goes on.  If left unchecked, the output of U1 would eventually hit a supply limit (either 0V or 5V). However, the second half of the above circuit, labeled “Oscillator Comparator” ensures that this does not happen by switching V5 between 0V and 5V.

Let’s take a look at U2, the second op-amp pictured above.  You’ll notice there’s no feedback path between its output and its inverting (-) terminal.  So what we’ve got is a comparator.  That is, if the voltage on its non-inverting (+) terminal is greater than that on its inverting (-) terminal, the output of U2 will be roughly 5V (our positive supply voltage). Otherwise, the output will be roughly 0V.  I say “roughly” because this op-amp (TL072) can’t operate “rail-to-rail”, which means its output can’t quite reach our supply voltages.

In order to understand this comparator a little better, let’s take a look at the point at which it switches between its high (5V) and low (0V) output.  Since the inverting terminal of U2 is fixed at 2.5V by the voltage divider at node #1, this switching must take place when node #4 passes 2.5V.  Let’s determine the voltage V3 necessary for this to occur.  To begin, I’ll equate the currents through R2 and R3 (since again, no current flows into the + terminal):

Switching Point DerivationNow don’t be confused about where that 2.5V is coming from.  This is the switching voltage for U2.  We’re not saying that U2’s non-inverting (+) terminal is fixed at 2.5V.  It’s not, because we don’t have negative feedback.  This voltage will vary based on V3 and V5.  Anyway, solving for the switching-point voltage V3 we obtain the following:

Switching Point DerivationSo we’re going to have two switching points, based on the two possible values of V5.  When V5 is 5V, V3 will be decreasing linearly, and a switch will occur at V3 = 1.325V. However, when V5 is 0V, V3 will be increasing linearly, and switching will occur at V3 = 3.675V. So this is how the oscillation happens: V3 ramps linearly in one direction until it reaches a switching threshold, at which point the integration reverses and V3 ramps backwards.  So what does this give you?  A triangle wave, as seen in green in this PSpice simulation:

PSpice Simulation (Red = Threshold, Green = Triangle Wave Oscillation, Blue = Output)

Of course, we can’t just use a triangle wave to signal our servo.  What we need now is a third comparator to generate a PWM signal using this triangle wave and a variable threshold voltage (the red line pictured above).   This is where the components around U5 come into play.  Again, since U5 has no negative feedback path, it operates as a comparator.  Thus, its output can only be 5V or 0V (roughly).  So if we feed our triangle wave into its non-inverting (+) input, and a DC threshold voltage into its inverting (-) input, what we get at the output is a square wave (the blue line) whose pulse width is inversely proportional to our threshold (i.e. a higher threshold yields a shorter pulse).

The last trick here is that we can’t just hook up a potentiometer (pot) between power and ground.  That would give us a threshold voltage variable from 0V to 5V. What we actually need is a threshold voltage that varies from about 3.2V to 3.5V, for a pulse width ranging from 1-2ms (based on the form of triangle wave shown above).  Well in order to accomplish this, I’ve placed two additional resistors (Rx and Ry) in series with the potentiometer (Rpot).  In order to determine appropriate values for these resistors, I’ll start with two voltage divider formulae which are based on the two limits of the potentiometer:

Comparator Threshold Resistance DerivationSo when the pot’s screw is turned fully clockwise, the pot’s entire 10kΩ resistance will be placed between Rx and the inverting (-) input of U5.  This will produce our maximum threshold voltage, VH.   However, when the screw is turned fully counter-clockwise, the pot will act as a short between Rx and U5, yielding our lowest threshold voltage, VL.  If we now combine and solve these two formulae, we can determine values for Rx and Ry:

Comparator Threshold Resistance DerivationNote: To determine resistances for different potentiometer values, you’d just need to replace the 10k in the first set of equations with your updated value and re-solve.

Now of course, all we really need here is a means of controlling the threshold voltage at U5’s inverting (-) terminal.  Back when I was working on my automatic ping-pong ball launcher, I wanted to use my laptop and a DAQ card to control my servo.  The DAQ card I had available at the time didn’t allow me to generate precisely-timed digital signals.  However, it did provide several analog outputs, which I could have connected directly to U5 in order to control this circuit’s pulse width.  But I didn’t know about this circuit back then, so I actually just used a microcontroller programmed to generate the appropriate signals based on an ADC input connected to my DAQ hardware.

Finally, you may also be wondering, how can I calculate the frequency of this PWM signal?  (Or maybe you’re getting sick of all these equations?)  Well, given the above formulae, it’s actually quite simple to calculate.  We just need to set the integration formula equal to the switching voltage formula, like so:

Switching Frequency DerivationWe now solve for the time t, then multiply by four (since this equation gives you the time required by one quarter of a full cycle), and invert to find the frequency:

Switching Frequency DerivationAlright, enough of these crazy formulae.  Pictures of the final circuit?  Yes, please!

Protoboard Closeup

You’ll notice that Rx is actually a series combination of three resistors, while Ry is a series combination of two resistors.  This is because I didn’t have suitable values for Rx and Ry just lying around.  Oh well, it just makes things a little messier!  Here’s the full setup:

Full Protoboard SetupFinally, here’s a screenshot of the IOBoard oscilloscope VI I used to test out my PWM circuitry.  You’ll notice that, as I mentioned earlier, the comparator’s output doesn’t quite reach 0V and 5V because these op-amps (TL072) do not have rail-to-rail outputs:

IOBoard Scope - 2ms Pulse Width

One final note on the schematic above.   The resistance R10 should have been unnecessary. I initially included it because PSpice wouldn’t run my simulation with U5’s output floating.  However, after constructing this circuit I found it necessary for reliably servo operation.  I’m not entirely sure why this was the case; perhaps the voltage levels without R10 were slightly outside of the servo’s acceptable range?  The signal on the screen certainly didn’t appear much different with or without it.  Perhaps if I had a higher frequency/resolution scope I’d see something more telling…  Oh well, it may not be an issue with your servo.

Anyway, if you have any questions on this circuit or would like to make suggestions, feel free to leave a comment.  I’d love to hear about your experience.

Also, please help yourself to my PSpice files (from the Orcad 16.0 student demo).  These were used to create the schematic shown here as well to perform simulations.

PWM Generator Schematic 2

Here’s my final bill of materials (BOM):

  • 2x TL072 Operational Amplifier
  • 1x Hitec HS-81 Servo
  • 1x 4.7uF Capacitor (Can be electrolytic, despite the slight negative voltage)
  • 1x 10kΩ Potentiometer
  • 2x 20kΩ Resistor
  • 2x 1kΩ Resistor
  • 1x 470Ω
  • 1x 119kΩ Resistor
  • 1x 166kΩ Resistor

Update (11/2/2010): It was pointed out that the TL072 may require a minimum supply voltage of 7V, so 5V could be cutting it a little close here.  Now I’ve looked through the datasheet and don’t see a specific limit mentioned, but most of the graphs do only go down to ±3.5V (which I suppose you could interpret as 7V).  Regardless, the circuit works fine with a single 5V supply, although the outputs don’t go rail-to-rail (which is normal operation), as I mentioned earlier.  The real concern with most op-amps is their upper supply limit, as you don’t want to fry anything.  Also, you might be more interested in the TL074 for this project, which contains four op-amps in one package.  I didn’t happen to have a quad op-amp lying around when I built this circuit, hence the two duals.


25 thoughts on “Pure Analog Servo Control”

  1. This is a nice project to learn stuff, did a similar thing for an analog electronics course. Using a thermistor in the bridge I created an “analog” thermometer with the servo as a gauge. Setting the sensitivity really high the servo paced back and forward with the warming and cooling of my breath.

    1. Thanks Jonas, I appreciate your comment. Your thermometer project really sounds awesome! I wish I’d thought of that – it would’ve been the icing on the cake for this post. 😀

  2. FYI, I just discovered another (pretty much) analog circuit for servo control here. This one uses a 555 timer and a potentiometer. So you can’t just feed it an analog voltage and get a corresponding pulse width, but it is still adjustable by potentiometer.

    1. Hi Kal,

      Yea, I’ve noticed that my Hitec servo is a little sensitive to changes in control voltage. As I mentioned towards the end of my post, the resistor R10 shown above shouldn’t have been necessary, but the servo I have would not move without it in place. Presumably this was because the voltage was a little too high otherwise.

      According to the Hitech servo manual, all of their servos require a supply voltage from 4.8V-6V as well as a square-wave control signal whose peak-to-peak voltage is between 3-5V. If the output of your circuit is only 3V (I assume that’s what you mean by output?), that’s probably too low. Perhaps try using an op-amp to boost that voltage. Also, do you have any way of measuring your pulse-width? You need to be sure it’s in the 1-2ms range.

      Hopefully this helps! Let me know how it turns out.

  3. Yeap it’s for my Analog Control course so I have access to an electronics lab. I measured the signal generated and I can vary the duty cycle from almost zero ms up to 10 ms (with a 50 hz frecuency). I know It’s a huge range but even when i’m between the 0.5-2ms range the servo doesn’t move (i’m using an osciloscope). I think that the OPAMP will be a great help(I hope!).
    Note: I’m using a pot instead a signal to vary duty cycle, after I achieve some movement on the motor I’ll change it by the output signal from the PID. The power supply Im working with it’s a 6 V and 5 A.

    1. Excellent! If you have access to a function generator, you might just try using it to create your signal. Just put it in square wave mode and then tweak your offset and amplitude settings. That should allow you to vary the output voltage nicely. If that doesn’t work, you may just have a bad servo…

  4. Hi again. The first time the circuit I’m using to control the servo didn’t work I used the function generator but it just has a range between 20 to 80 % of duty cycle. However the motor moves to it’s final position so I assume it works. I noticed something strange, when I wire red and black wires (to vcc and gnd respectively) and I touch the yellow (signal) wire the motor moves a little bit and if I touch the yellow wire again it moves another bit. Is that normal? I started to wire your circuit. Can you tell me please the polarity of the capacitor C1 (electrolitic)?? Thanks!

  5. I assembled the circuit but the servo doesn’t work yet. I put a resistor and a led to the pwm signal of the 3rd opam and I can vary the power on it so the circuit is working… Servo moves when I touch the yellow wire and when i dissconect the yellow wire from the pwm output too…

    1. Hmm, interesting. So it does sound like your servo is working, since you’re seeing it turn a little. The reason it’s moving when you touch the wire (I’d guess) is because you’re introducing a little noise into the signal line. If you have an oscilloscope and you touch one of its probes, you’ll see what I’m talking about – it’s usually 60Hz noise of some kind. Just disconnecting the yellow signal line must be having the same effect.

      If possible, can you check the output of your circuit with an oscilloscope before connecting it to the servo? Just to make sure it’s hitting the right voltage and period specs? If it is, have you double-checked to make sure everything is grounded properly? In other words, are the servo, the control circuit, and the servo’s power supply connected to the same ground? And what voltage are you supplying to the servo’s red line again?

  6. Great tutorial :), I’m gonna use it for my electronic club at college! I do have a doubt though, in the node 1 shouldn’t there be a capacitor? Else the comparator wouldn’t oscillate, also another question: the only way to control a servo motor is with a triangle sign? I thought you were going to use a sine sign, when I read “analog” hehe

    1. Hi Jesús,

      Thanks, I’m glad you like it!

      Actually node #1 doesn’t require a capacitor since it’s merely setting a DC switching threshold (Ra and Rb just form a voltage divider). The capacitance needed for oscillation is found between nodes 2 and 3. If you take away everything else, the components except for R1, C1, and U1, you’re just left with an integrator. Adding the second op-amp causes the oscillation by changing the direction of integration at a certain threshold. Take a second look through the description and equations above and let me know if you still have questions.

      Oh and yea, you could generate a regular sine wave and use a comparator to generate your square wave control to the servo. But adjusting the threshold to that comparator wouldn’t produce a very linear change since your sine wave isn’t linear like a triangle wave is. Make sense? But the bottom line is that you need to end up with a square wave for the servo to be happy, regardless of how you create it.

      1. Oh I get it now, thanks for clarifying! So in other words, the top circuit can have any form as long as the output form is able to generate the square output, right?

        Another question about the servo motor, do I need to implement any short-circuit protection for the motor? Or I don’t have to worry to much about current? Also this motor only works @ 100Hz? Do I get a constant speed output with this circuit, or is there a way to control the speed of the motor with a potentiometer well placed?

        1. Right, these hobby servos expect a square wave signal (for instance, see this Hitech manual).

          So if you’re using a hobby servo like the ones pictured above, no, you don’t need to worry about any short circuit or stall control. The servo takes care of all that itself. And the 100Hz figure is pretty arbitrary, you can send the pulses at a slower rate if desired.

          Now I’m thinking that perhaps you’re getting hobby servos confused with regular DC motors? The hobby servos I’m discussing and controlling here are intended to rotate to a specific angle (controlled by the duration of the square wave pulse) and then stop there. They don’t continuously rotate at a certain speed. Basically this circuit commands a specific position of a hobby servo, and the servo just tries to get there as fast as possible. Does that make sense?

          1. Yes, I did confuse it with DC motors, thanks again! I’ll research a bit about servo motors, well I’ll try to mount the circuit this week, I hope it works! Thanks again!

  7. Hello. I assembled the circuit you designed. I got the pwm signal, i had to modify some values in the pots because I was getting a signal with 8ms at the period and a range from cero to 0.9 ms in the duty cycle. I can vary it in a range from 1 to 2ms however I have the same problem. The oscilloscope sees the square signal but the motor doesn’t react to it. I’m feeding the circuit with 8V and the peak to peak value of the square signal at the output is 5.5V. I don’t know how to solve this…

    1. Yea, that’s a tough problem. It’s hard for me to really diagnose without having the circuit in front of me. But if you’ve checked the signal, checked your grounds, and checked that all your voltage levels are in spec, I’m not sure what more you can do. Do you or someone you know happen to have a working RC car or just a receiver you can use to test your servo? If that works perhaps you can measure and then duplicate that signal. Good luck to you!

  8. Thank you! A very well written article. I’m going to have some free time on my hands in the coming months and I look forward to building this circuit.

  9. Mike, I think this circuit is exactly what I need…almost…
    I’m using an xbee module’s variable voltage output pin in place of the potentiometer for altering the width of te pulses, but the trouble is that the xbee voltage tops out around 3.3v, which if I understand correctly would limit my range of motion on the servo to somewhere between 25-30%. Is there a way to alter this design to output the correct 1-2ns pulses using a lower variable input voltage in the 0-3.3v range? Thank you so much for the great explanation of this circuit! With the popularity of the ras pi and arduino boards everyone now looks to a microcontroller for these applications, but that isn’t really suitable for my application, it’s nice to know some analog folk still exist.

    1. Hi James,

      Actually you may get pretty close with the circuit as it is… it’s been awhile, but at least in simulation, the min and max input voltages you need are 1.325V and 3.675V. Check out the black-background graph above with the green, red, and blue traces. The red line is your input voltage (coming from your XBee). When the green triangle wave is higher than the red line, the output pulses high (blue line), otherwise it’s low. So you only need to go from 1.325V to 3.675V. Which might be enough for you.

      If that doesn’t work out in practice, I think it may be as simple as adjusting Ra and Rb to lower the 2.5V reference voltage.

  10. Hi Mike,
    I am trying to build this circuit to control my servo as a pan camera system. I have some questions about the circuit. First I would like to find out why there are only two op amps in your final built circuit but in your circuit diagram there are three op amps.
    I also want to ask if a daq card is needed and if i can use the pot to control the servo by maybe turning it. Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *