Tag Archives: fun

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.


Measuring Projectile Velocity

(Updated 9/6/2010 – scroll down for final results)

I’ve got a couple friends who enjoy building spud guns and other sorts of “just for fun” air rifles. They’re pretty nifty to shoot, especially since ammo is flexible. Even a wad of paper towels wrapped in tape will do the trick. All you need is something that forms a relatively good seal with the inside of the barrel.

So being the EE that I am, this got me to thinking: wouldn’t this be even more fun if we could measure muzzle velocity? It shouldn’t be all that hard; we could just hook up a couple LEDs and photo-detectors, fire through the beams, time it with a microcontroller, and voilà! So, that’s precisely what I did, except that I decided to go with a couple cheap laser diodes instead of LEDs. Here’s the end-product in all its wooden glory:

The Box

Top View

In the first image you can see one of the two laser diodes poking through the right side of the wooden enclosure (and held precisely in place by hot glue). The two lasers are aimed at PIN-type photodiodes which are mounted on the other side of the box, spaced 2″ apart, and covered with IR-blocking film (to prevent difficulties with ambient light):

Photodiodes Plus IR-Blocking Film

The two photodiodes are wired in reverse-bias as shown in the following schematic:

Sensor Schematic

Now if you’re unfamiliar with photodiodes, you can essentially think of them as light-dependent resistors. (Although to be precise, they should really be modeled using a light-dependent current source as discussed here.) In total darkness, they’ll exhibit very high resistance when reverse-biased. However, expose them to light, particularly infrared light (at least in this case), and their resistance drops substantially. Thus, whenever the laser beam is striking a photodiode, its resistance is quite low. When this happens to D1 in the schematic above, the voltage at point A rises closer to the 5V supply. However, if the beam is broken, the photodiode’s resistance rises, causing the voltage at point A to drop towards 0V (GND).

We can use this change in voltage to determine when the laser is being blocked by a projectile. This is done using a high-speed operational amplifier (op-amp) wired as a comparator. The potentiometer (POT) shown in the schematic above is tuned so that its output voltage is just between the “blocked” and “unblocked” voltages of the photodiodes. The outputs from the op-amp then saturate at 5V whenever the lasers are unblocked. However, if the lasers are blocked, the op-amps will output approximately 0V. This change from 5V to 0V then represents the entry of a projectile and is detected by an AVR microcontroller, the ATMega128. It’s part of a development board I’ve had for several years now, the Olimex AVR-MT-128 (details here). The development board really isn’t important at all – it simply provides screw terminals for easy connection to the AVR’s I/O.

So once the microcontroller powers up and initializes its LCD display, it sits and waits for its two inputs to change state. If the leading photodiode goes low (0V), an interrupt is triggered that starts an internal counter. The counter runs until the trailing photodiode goes low, at which point the counter is stopped, the projectile’s velocity is calculated based on the known separation between photodiodes, and the LCD display is updated like so:

Display Closeup

The “mode” you see displayed above indicates the speed of the MCU’s internal 16-bit counter. If a slow-moving projectile (less than ~150ft/s) is expected, you can use the pushbuttons to specify slow mode, which causes the internal timer to count at a much lower frequency. This allows slow-moving projectiles to be measured without counter overflow. However, if you’re firing high-speed projectiles, you’ll want to use fast mode. This will kick up the counter’s frequency to 16Mhz to provide better speed resolution.

My initial testing was performed by shooting rubber-bands through the lasers. It turns out they fly at between 40 and 80 ft/s depending on how much you initially stretch them. I also tested out the timing accuracy of the system by using an arbitrary waveform generator in place of the photodiodes. Results looked very good: fast mode accuracy should be less than 0.1% at speeds of about 1000 ft/s. Max speed is limited to 10,000ft/s.

Code for the ATMega128 can be downloaded here: fps_meter_code.zip.

Finally, the following is a fairly complete bill of materials in case you want to try this out:

  • PIN photodiodes: BPW34
  • Operational Amplifier: EL5444
  • 5V switching regulator (to power development board): V7805-500
  • Linear 3.3V regulator (to power lasers): UA78M33C
  • 1k resistors (in series with photodiodes)
  • 10k potentiometer (to set the photodiode “trigger” threshold)
  • Laser diode modules (pulled from two cheap laser pointers)
  • AVR development board: AVR-MT-128 (but really, a single ATMega will do)
  • IR-blocking film: Wowfil samples
  • Some scrap wood and screws

Update (8/29/2010): I have now tested the meter successfully with two different air rifles – a .20 and a .22 caliber pellet gun. The .22 was tested first and proved rather anemic. Initially it couldn’t even break through the cardboard box we were using to catch the pellets. With a few extra pumps its rounds reached 140ft/s, but that’s still rather slow. The rifle seems to have difficulty holding pressure. We had better luck with the 0.20 cal – its pellets reached a top speed of 590ft/s – this was enough to penetrate two layers of cardboard and nearly the full thickness of a piece of 1×6 pine wood. I should also note that using such small rounds made it slightly difficult to trip the laser sensors. However, once we had the rifle lined up properly and leveled, everything worked great!

Update the Second (9/6/2010): This afternoon I took the meter out to my uncles’ shooting range for a bit of live-fire testing. The first thing I learned is that the device I’ve made is called a chronograph and that apparently you can buy these for not much money. No doubt the store-bought varieties provide many additional features and are easier to use; but where’s the fun in that?

Well, we started out “testing” with a .45 ACP using standard Remington FMJ rounds (230 Grain). The chronograph was setup about eight feet in front of the table from which we were firing. I had considered firing at point-blank range, and while this would have been much easier, the smoke and flames from the barrel may have presented a problem for my electronics (i.e. inaccuracies, melted plastic, etc). Of course, the long-distance alternative could have led to my blasting my poor development board into oblivion. Thankfully, I’m a better shot than that; although just barely. To perform the test, I pinned a little black target to the back of the device, then aimed for the center of the dot. After a few tries, the round passed through both beams and registered about 850 ft/s – pretty much what you would expect for this type of ammunition (see this Wikipedia entry on the .45 ACP).

Range Test: .45 ACP SetupNext up, we tried out some Magtech Auto+P rounds – 185 Grain, JHP. As promised, these provided substantially more power. You could certainly hear and feel the difference. That is, when they would fire – a number of them were just a bit too long to fit completely in the chamber. I’m not sure whether this was a defect or if they were just too big for this particular gun. But anyway, a couple different shots both registered about 1150 ft/s:

Range Test: .45 ACP ReadoutSo after all of this testing, I’m thinking about making a couple of changes to the system. For one thing, having to adjust the threshold potentiometer for changing lighting conditions is a little frustrating. The IR-blocking film just isn’t quite cutting it, although I’m sure it helps. But I’d like to try using the AVR to dynamically generate one or two analog outputs for use as thresholds. I’ve actually done something very similar in the past with the same photodiodes. I simply programmed the AVR to ramp up its output voltage until the comparator switched state. Then it automatically reduced the output voltage a little to give some room for noise. This varying analog output, by the way, was created by adjusting the duty cycle of a low-pass filtered PWM output. Setting the filter’s cutoff frequency to less than 1/100th of the PWM frequency nicely converts a square wave into a DC value (and the lower the cutoff frequency, the smoother your final output will be).

To compensate for changing lighting conditions, I might also try connecting the two photodiodes directly to the analog inputs of the ATMega128. I’d still use the external comparator for timing measurements, but this would allow me to directly determine the best analog threshold to be generated by the AVR without the need for scanning. I could also add transistors to the lasers so that the AVR could turn them off briefly for calibration. I might also just high-pass filter the photodiode output to completely eliminate any shifting DC offset. I’ve tried this before on a similar project with good success.

The other thing I’d like to do is make the sensing area a little wider. It’s pretty tough to reliably hit two 1/8″ laser beams. Perhaps a couple of line lasers and photodiode arrays would do the trick. Or maybe there’s a better non-optical sensing option out there I haven’t heard of yet…?

Three Down, Forty-three to Go!

Last weekend I was back in the Adirondacks, hiking two more of the high peaks with a couple good friends. The weather was absolutely gorgeous – temperature no more than 60F, sunny, nearly unlimited visibility. We started out from the Adirondak Loj parking lot and headed south to Wright peak, elevation 4580 feet. As usual I brought along my Nikon D80 and all its paraphernalia. Here’s the view from Wright peak to the east (if I recall correctly):

Eastern View from Wright Peak

Looking the other direction, the peak of Algonquin still towered another 500 feet above us:

View of Algonquin from WrightWhile on Wright we had a quick lunch, then headed back to the trail for Algonquin. Again, the views were spectacular, and if anything the weather was even better. Here’s a panorama I stitched together with Microsoft Image Composition Editor (the peak just to the right of center is Colden, my very first):

Panorama from Algonquin
That 37.6-megapixel composite came from eight separate shots taken over about 200 degrees. I must say, ICE is a pretty impressive program. All you do is open it up, feed it a batch of images, and away it goes. I’ve been using it for a number of months now and it’s performed exceptionally fast and its stitching is accurate. It definitely tops Auto-stitch, which I used previously.

Our sum total for the day: eight miles, seven hours, 3000′ elevation gain, and so much fun. So for me, three high peaks down, another forty-three to go! 🙂

For a list of all the high peaks in the Adirondacks, try: http://www.adk46r.org/listf.html.