Category Archives: Hobbies

LabVIEW: The Simple Talking Voltmeter

A couple of weeks ago I spent some time examining a fairly complex circuit board from my old, but still functional, clock radio/CD player.  I was using the probe of my handheld multimeter to measure voltages at various IC pins and circuit traces.  At one point during the process I thought, “Gee, wouldn’t it be nice if I had someone here to read the voltmeter to me as I test various points?  That way I could focus on my probe and not accidentally short neighboring pins.”  But then I realized that I did have someone to do just that: Microsoft Sam.  I present to you the NI LabVIEW talking voltmeter:

For those of you without LabVIEW, here are a few screenshots of the subVIs shown in the video above.  Don’t forget that you can always download a free, unrestricted 30-day trial of LabVIEW from the NI website (seriously, it’s awesome, you should try it).

First, the initialization VI, which opens the Microsoft ISpeechVoice reference:

Initializing the Speed Interface

Next, the blocks responsible for detecting new steady-state voltages:

Detecting New Steady-State Voltages

Finally, the code which converts numbers into strings and sends them to Sam:

Convert and Speak the Values

Many thanks to Grant Heimbach, whose sample speech VI saved me a lot of development time (his original code is available on the NI Developer Community).

Click here to download a simple example VI which utilizes the code shown above.

The full, unmodified IOBoard Voltmeter program, as well as all of its supporting components, can be located at the bottom of the Mobile Studio Downloads page.

Got questions or comments?  As always, feel free to leave them below!

Measuring Telluric Currents – First Trial

Way back in November of last year (2010), I wrote a short little article on telluric currents, their history, and related applications.  Now, in case you’re unfamiliar with this topic (as I was prior to November of last year), here’s the executive summary: telluric, or earth currents, are electrical currents which travel through ground or water, primarily near the surface of the earth.  They may be naturally occurring (due to changes in the earth’s magnetic field via solar wind), or man-made (e.g, from mineral exploration).

Well towards the end of my previous post, I expressed a desire to try and measure these currents.  Unfortunately at that time, it was winter, and I was in the process of relocating to Iowa.  But now that I’ve settled in here, and the ground has finally thawed, I’ve gone out and performed a quick first measurement.  Here’s the procedure I followed:

  1. Obtain two 36″ lengths of standard rebar and 100′ of insulated 14 AWG copper wire (solid core works, but I used stranded for better contact with the rebar).
  2. Sand/file any rust from the surface of the rebar (to reduce contact resistance).
  3. Strip about two inches of insulation from the ends of the wire, then fray these ends and wrap them tightly around one end of each piece of rebar.  Cover these attachment areas with electrical tape.
  4. Cut the wire, which is now linking the two pieces of rebar, at any point (this is where the multimeter will be inserted).
  5. Space the two lengths of rebar as far apart horizontally as possible, then drive them into the ground as deeply as possible (in my case, this was about 20″).  For my first test, I configured the two so that they would point north to south based on the map shown here and my location in Iowa).  In other words, if I were to stand at the southern-most length of rebar, facing the other rod, I would be facing north.  They were separated by the 100′ of wire.
  6. Measure both current (short circuit) and voltage (open circuit).
  7. Finally, if anyone should question what the @#$% you’re doing pounding rebar into the ground, simple employ this catch-all excuse: “solar flare protection.

So, without further ado, I give you my results (in low-quality cellphone pic format):

Telluric Current - Well, it is measurable...

If you can’t quite make out that reading, my apologies.  The meter indicates 0.55mA (DC).  Yea, not too incredible, I know.  I also measured the voltage between the two rebar rods, but at just 105mV, it’s not terribly impressive either.  So, at best, we’ve got 14.5uW of power to play with – barely enough to run a digital watch (please see this excellent page on Thevenin equivalent circuits and the maximum power theorem for details on how that number was calculated).

Overall, these results are a little disappointing, both in quality and in quantity.  I had hoped to reconfigure my rods a couple of times so as to measure the current’s heading as well.  Unfortunately, for this test I picked a slightly wooded area that also happened to be teeming with mosquitoes.  I’ll do a lot of things for the sake of science, but serving as a meal for blood-sucking insects isn’t one of those things.

In the future, I’d like to leave the rebar in place for a while longer – say, 24 hours – and record data continuously during that time.  I’ve read in a number of sources that telluric currents tend to vary over the course of a day.  So, when I did my test this morning (8:30AM CST), I may have been measuring things as a low point.  The only trouble with capturing data for such an extended length of time is that I’ll need to find a more controllable location, and I’ll need to figure out how to log the data automatically.  I’ve got a few development boards I can probably re-purpose for that though…

So, in summary, for round two of testing I shall make the following changes:

  • Take measurements with the rods configured along different compass headings.
  • Log data for a consecutive period of at least 24 hours.

If anyone has other suggestions, please leave a comment.  Stay tuned for more.  Thanks!

Explaining the XMega XPlained (Dev. Board)

About two months ago, Atmel announced a smart new set of AVR development boards, the XPlained series.  One of these boards (which I’ve just recently purchased for $30) boasts a shiny new AVR XMega microcontroller.  What?  An XMega you say?  Why yes, haven’t you heard?  Come now, they’ve been around for fully three years at this point.  Well, don’t worry if this is fresh news, you’re not alone.  For some reason, adoption of the powerful new XMega MCU has been slow amongst hobbyists.

The XMega Xplained (click for high-res goodness)

When Atmel introduced their new XMega series of AVR microcontrollers back in 2008, I was pretty sure they’d be a quick sell.  Even in spite of their unavailability in DIP packaging, and this cheesy marketing video.  But sadly, a quick search of Hack a Day currently yields only four articles containing the term “XMega” (versus more than three hundred articles for “ATMega”).  I guess change is hard.  And yet, it’s really not.

The XMegas utilize the same AVR core as the ATMegas, and are fully supported by the free AVR-GCC compiler and AVR Studio (obviously, I guess).  Plus, you can still use your trusty AVRISP mkII programmer to load code onto an XMega.  In other words, the tool-chain is unchanged.  So, with a few register name changes, code from an ATMega will run perfectly well on an XMega.  Sadly though, the XMegas and ATMegas are not pin compatible, so you won’t be able to solder a new XMega onto your Arduino.

Alright, so for those of you keeping track, I guess I’ve now listed three strikes against the XMega which may help to explain its present unpopularity: no DIP packaging, no pin compatibility with the ATMegas, and changes to register names (plus the addition of new registers for new features).  Oh, and odd marketing tactics.  By the way, as a side note, it could be argued that the XMega register scheme is better than that of the old ATMegas.  They’re making good use of structs, so that you now address a port’s direction using PORTX.DIR, rather than DDRX.  And you output to that port using PORTX.OUT.

But let’s now take a look at the data in favor of the XMegas, yes?  To do that, we’ll compare the ATMega1280 (utilized on the Arduino MEGA) against the ATXMega128A1 (utilized on Atmel’s new XPlained development board):

Feature ATXmega128A1 ATMega1280
FLASH Memory 128KB 128KB
Max CLK Speed 32Mhz (PLL) 16Mhz
RAM Size 8KB 8KB
Voltage Range 1.6 – 3.6V 2.7V – 5.5V
ADC 16, 12-bit, 2Msps 16, 10-bit, 76.9Ksps
DAC 4, 12-bit, 1Msps N/A
USARTs 8 (one supports IrDA) 4
Hardware Encryption 128-bit AES, DES N/A
Timers 8, 16-bit 2, 8-bit and 4, 16-bit
Current Draw, 1Mhz, 1.8V 365uA 500uA
Event System Yes No
Price $10.20 $16.13

Not bad, right?  I’d say the XMega wins this round.  It’s faster, provides substantially better analog to digital conversion, offers digital to analog conversion (in other words, analog outputs – a feature not available on any ATMega), hardware-based encryption (again, not found on any ATMega), lower power consumption, and, wonder of wonders, a lower price.  I’m quite impressed (for what that’s worth) and am particularly excited about putting these new analog features to the test.  In fact, as I mentioned, I’ve just received my XPlained development board and have already written a quick test program to do ADC → DAC pass-through.  But I’ll describe my experiences with the XPlained board a bit later (spoiler alert: they weren’t all pleasant).

So what precisely does the new XMega series offer that makes it, in my opinion, such a substantial improvement over the ATMega series?  Let’s talk speed for a moment.  The old ATMega topped out at 20Mhz, at least officially (though overclocking is possible, as seen in the Uzebox gaming system).  But furthermore, there is no way to adjust the system clock on the fly (although you can, of course, adjust peripheral clocks).  You’d have to make fuse adjustments with an external programmer.  With the new XMega series, you can adjust the system’s clock frequency at run-time.  Both a 2Mhz and a 32Mhz internal RC oscillator are provided, plus a PLL which allows for clock multiplication (1x, 2x, 3x, …, 31x).  According to application note AVR1005, you can even use the PLL to increase the clock speed of your peripherals to a maximum of 128Mhz.  This might be useful for generating high-resolution PWM signals, for computing precise time intervals (think range-finders), or for just blinking an LED really really fast (although perhaps not this fast).  Man, I could’ve used this on my MS thesis

Another neat feature of the XMega series is the brand new event system which allows for high-speed signaling between peripherals.  This is not a communications bus in the traditional sense.  It’s actually more like a set of, shall we say, “personalized” interrupts sent between features.  Event signals can be sent quite rapidly – in no more than two clock cycles – and don’t require the CPU to be active.

The XMega Event System

The XMega’s event system opens up a whole new world of possibilities.  With it, you could tie a set of 16-bit counters together to form one highly-accurate 32-bit counter.  Or, how about this application note example:

You could use one event to synchronize two modules. For instance, you could use a pin change event to do an ADC conversion and an input capture on the Timer/Counter to get exact time-stamps for each conversion.

For more details on the event system, see the “Getting Started with XMega” application note AVR1005 or the “Getting Started with the XMega Event System” note AVR1001.

First Impressions of the XMega XPlained Dev Board

Alright, well let’s get down to business here.  As I mentioned earlier, I’m now the proud owner of a brand new Atmel XMega XPlained development board.  I was putting in an order with Digi-Key the other night when I thought to search for XMega products (yes, shame on me, I haven’t tried them out until now).  I found just one, but it was precisely what I was looking for: low cost ($30.16), USB-powered, and covered in blinking lights (well, nine of them anyways).  So of course I bought it.  I mean, it’s not quite as much of a steal as the $4.30 TI Launchpad, but even at $30, I didn’t even bother to do research before adding it to my cart.   I just figured it would work.  🙂  Bad idea, I know…

So what did I get for my money?  A pretty padded box and the board itself.  Nothing more.  No documentation whatsoever, only a printed messages on the outside of the box requesting I go online for any required drivers and data.

XMega Xplained Unboxing

Now the lack of paper is fine with me; if Atmel wants to save some trees, good for them.  I’d have gone online for datasheets and schematics anyway.  My only gripe here is that Atmel’s site isn’t all that easy to navigate.  In fact I don’t think I ever located a link to the ZIP file associated with AVR1927 (instead I just crossed my fingers, manually typed in the assumed link, and bingo).  But maybe I’m just bad at the internet.  Well for the sake of centralization, here are a few URLs I found helpful when getting started:

The XMega XPlained comes pre-programmed with a cute little application that blinks its nine LEDs and plays different sounds (drums, trumpets, etc. – just one- or two-second clips) when each of the eight different buttons are pressed. And I’ve got to say, the little speaker actually impressed me with its sound quality.  It’s not exactly a M-Audio studio monitor, but it’ll probably hold its own against a speakerphone.  And it’s certainly not being driven by square waves; they’re making good use of the XMega’s analog outputs (DACs).  So what else does the XPlained offer?  Well, here’s the official list:

  • External memory (8MB SDRAM, MT48LC16M4A2TG)
  • Atmel AT32UC3B1256
    • Communication gateway
    • Programmer for Atmel AVR XMEGA
  • Analog input (to ADC)
  • Analog output (from DAC)
    • Mono speaker via audio amplifier
  • Digital I/O
    • UART communication through USB gateway
    • 8 mechanical button switches
    • 8 LEDs (plus one bi-color LED)
    • 8 spare analog pins
    • 24 spare digital pins

Programming the XPlained using FLIP

So the pre-loaded software entertained me for about sixty seconds, after which my desire to reprogram the board overcame my fascination with lights and sound effects.  I didn’t have my AVRISP mkII handy (left it at work again), so I started by looking into reprogramming via the board’s USB connection.  The first thing I needed was a driver for the virtual COM port (Windows 7 did not recognize the XPlained), a single INF file:

USB CDC Driver (Virtual COM Port) – required for USART communications.

I was pleased to find that the instructions provided in the “Getting Started” guide (AVR1927) for using the Flexible In-System Programmer (FLIP) for RS232 programming were quite simple.  I downloaded and installed FLIP via this link.  I also had to import an XML configuration file (provided here), although it sounded like this file should have been included in the latest FLIP installer.  But before adding this file to <Install Directory>Flip 3.4.xbinPartDescriptionFiles, I received an error stating that “the device does not exist” when using BatchISP (the FLIP command line utility).  I also attempted to use the FLIP GUI directly, but for some reason the RS232 communication option was greyed out.  No problem though, I simply threw the programming commands given in the instructions into a simple batch file:

batchisp -device ATXMEGA128A1 -hardware RS232 -port COM25 -baudrate 115200 -operation onfail abort memory flash erase f blankcheck loadbuffer c:xmegatestdefaultxmegatest.hex program verify start reset 0


I’ve highlighted the elements you’ll want to change when using this file.  Including that pause command causes the command window to wait for you to press a key before closing, that way you can take a look at the results of your programming attempt:

FLIP (BatchISP) Command Line Programmer

So using BatchISP (FLIP) worked just fine for me.  The whole programming process took a bit longer than I would have expected (maybe 20 seconds), but it’s not terrible.  The one catch is that you have to unplug the XPlained board, and then plug it back in while holding down switch SW0, every time you want to reprogram.  This is required in order to activate the bootloader.  Doing this gets old fast, and it didn’t seem to please my computer (it would occasionally freeze for a few seconds when the device was quickly plugged back in).  But there is an easier way; keep reading…

Programming the XPlained using the AVRISP mkII

So based on the literature I’ve run across, it seems the preferred means of reprogramming (and debugging) an XMega is via JTAG using either the AVR Dragon ($50), the AVR JTAGICE mkII ($300), or the Cadillac of debugger/programmers, the AVR ONE! ($600 – perhaps this is the reason for the exclamation point).  The new XMega series uses the PDI (Program and Debug Interface) programming interface (as opposed to ISP).  However, it is possible to use the AVRISP mkII programmer (though you cannot use it for debugging), which costs just $35.  And if you’ve done anything with AVRs in the past, you’ve probably got one of these hanging around (I should note that the original AVRISP, the one with the DB9 port, will not work with the XMega series).

Now, to get your AVRISP working with the XMega Xplained, you’ll need to create a simple pin adapter.  You cannot connect directly to the board as the pins are arranged for a 10-pin JTAG connection (I guess Atmel really wants you to use JTAG).  However, you’ll only need to connect four of the six pins present on your AVRISP, as shown in this diagram (found on page 9 of the XMega “Getting Started” guide, AVR1005):

AVRISP Pinout Comparison

These pins can be found on the XPlained’s JTAG connector, as shown in the schematics:

XMega XPlained JTAG Connector

Once you’ve made these connections, you can use AVR Studio to reprogram your device as usual.  Well, almost.  First, you need to make sure it’s fairly up-to-date (I used version 4.18, build 700 with success, but you might go straight to AVR Studio 5, which I’ve also tried with success).  You’ll then need to manually specify the ATXMega128A1 before programming or adjusting fuses.  Plus, and this is key, you’ll want to disable the JTAG interface by using AVR Studio to clear the JTAGEN bit on the fuses tab.  If you don’t, your programming may or may not be successful.  I actually got into an interesting cycle where alternate programming/read events would fail.  I’d perform one operation successfully, but on the next I’d see “Entering programming mode…FAILED.”  But disabling the JTAG interface took care of this issue.  And doing so does not prevent you from re-enabling JTAG later, or from using BatchISP (though you may need to reload the bootloader if you’ve erased it, which may be found in this ZIP).

For more details on programming and debugging an XMega, see this article (and actually, check out all of these “Getting Started with XMega” articles, they’re quite good).

A First Test of the Analog I/O

Now I think I’ve stated this already, but again, I’m pretty excited about the new analog I/O offered on the XMega series.  In particular, the 12-bit digital to analog converters (DACs) open up a whole new world of options.  I mean, there are all sorts of applications out there that might benefit from an on-chip DAC: function generators, analog power supplies, audio processors, lighting controls, you name it!

So the first bit of code I wrote for my XMega is a simple ADC → DAC pass-through.  It’s a touch long to include in this post (because of all the comments), but please feel free to download it here.  The code takes an analog input on ADCA1 (PORTA1, pin 96) in the 0-2.1V range and outputs a proportional analog signal on DAC0 (PORTA2, pin 97) in the 0-3.0V range.  Here’s a screenshot of the results taken using my RPI IOBoard and LabVIEW interfaces.  The bottom graph (red line) shows the sine wave signal being generated by the IOBoard and connected to the XMega’s ADC input.  The top graph (white line) shows the scaled sine wave being measured at the XMega’s DAC output:

XMEGA ADC-DAC Pass-through Test

You may be wondering: why the difference in input and output voltage ranges?  Well, here’s one additional problem I see with the XMega: Vcc (max 3.6V) is not directly available for use as a reference for the A to D conversion, only Vcc/1.6V (which is 3.3/1.6 = 2.0625V, in this case).  Now you can select AVcc (typically tied together with Vcc, perhaps via a filter) as a reference for the DACs, although according to the hardware datasheet, both ADC and DAC reference sources are limited to AVcc-0.6V, or 2.7V on a 3.3V source (which is what you get on the XPlained development board).

Now in testing these specifications, I have found the ADC limit to be fixed as stated, although when I’ve selected AVcc as the reference for the DACs I’ve seen max outputs reach just over 3V.  Honestly, I don’t know what prevents the XMegas from using Vcc as a reference, as this is commonly done with ATMegas.  Oh well!  You just may need to throw in a voltage divider and/or op-amp to compensate.

One other issue I noticed was noise in the ADC signal when measuring values near 0V.  This could be an issue with how I’ve setup my code, or with some other aspect of my hardware.  But you can see this effect in the slightly garbled low points of the sine wave shown in white in the above screenshot.  I guess the bottom line is that I’ll need to play around with this a bit more.  (NOTE: I believe we have solved this issue; it is a problem with the XMega chip itself.  The solution is to use a lower (e.g. 1V) reference for the DAC.  See comments section below.)  Apparently there are also calibration registers for the ADC, and some pretty advanced tweaks you can make.  Take a look at this page on configuring and tuning the XMega ADCs – it’s been a great help to me already.


Overall, I’m cautiously optimistic about the XMega and the XPlained development board.  I’ve encountered a couple of minor issues, and the list of problems in the errata section of the datasheet is frighteningly long.  I should also point out that a previous version of the XPlained, the XPlain, apparently had quite a few more serious issues.  You’ll find references and pictures of the XPlain if you do a bit of Googling.  I’m not sure who’s still selling it, but I can tell you that despite the picture and the name, Digi-Key is shipping the newer XPlained, not the old XPlain (this is where I got mine).

So I still say that the XMega a great leap forward by comparison with the ATMega series.  The only question left is what to do next?

I’ve been thinking about going further with this ADC-DAC application and creating an audio compressor and volume control.  You see, I’ve got this cheap portable speaker that I use with my Blackberry for listening to MP3s.  The trouble is, there’s no remote, and each track seems to play at a slightly different volume.  So I’m thinking of using the XMega to receive IR signals from a remote and then adjust the volume accordingly (by scaling the ADC result before sending it to the DAC).  And at the same time, it could automatically adjust volume, based on the incoming audio signal, within a certain range.  This is called compression.  My setup would require a bit of analog work to get the signals into the correct voltage ranges before and after processing, but a couple of op-amps would likely do the trick without much work.

That said, I’m open to other ideas.  Has anybody out there got suggestions for projects?

Home Sweet Garage

Alright, I think it’s about time for this silly article on plasma arc waste disposal to get knocked off the top of my site, don’t you?  It’s just fluff, honestly.  Filler.  And I’m tired of looking at it.  So how about a post on a real project for a change?  Sound good?  Great.

First though, a quick gripe.  I hate waiting for parts to arrive.  Specifically “last” parts.  Like that final DigiKey order, or in my case, a shipment of PCBs from Advanced Circuits.  You see, I now have everything I need to complete this really exciting new device I’m designing at work, except for the PCBs.

Assorted parts, but no PCBs...

And not having boards is kindof a show-stopper.  So I’m crossing my fingers and hoping that Advanced Circuits gets them shipped out early, as they so often do (because they’re totally awesome).

But let’s get down to business.  If you happen to have been reading my blog about six months ago, you may remember that I recently moved to the middle of nowhere Waterloo, Iowa to start working for John Deere.  Now prior to moving here, finding a place to live has been, for me, frustrating.  “Oh, here’s a place that’s nice, but it’s too far away,” or, “That’s way too expensive,” or, “Uh, what’s that growing on the ceiling?”

Not so this time.  Deere actually provided a relocation assistant to show me several nice places around town.  All I had to do was tell her what I was looking for and BAM, there we were.  Plus, the cost of living in Iowa is virtually zero.  So here I am, renting a lovely townhouse, about ten minutes’ drive from work.

Now, nothing’s ever perfect, and this place is no exception.  For instance, it’s got a nice single-car garage with an opener, but there are two problems.  First, the remote control has terrible range.  My landlord warned me about this, but explained that I just needed to find that “sweet spot” for it in my car.  But this thing is kindof a brick and looks rather like some RadioShack project box.

This really is a garage door opener.

The second problem is lighting.  The garage door opener does have a single light bulb which comes on when the unit operates, but it’s pretty anemic.  This isn’t helped by the fact that the inside of the garage is almost all dark wood, either.  Plus it seems to take a few seconds for this light come on, and it only stays on for a few seconds afterwards.

So in Iowa, winters are long, dark, and cold.  Not unlike a mine shaft, I imagine.  But I like light.  So I took a trip to Home Depot one weekend, and for about $50 (those motion-detecting switches are kindof steep) solved problem number two quite simply.

Let there be light!

Yep, that’s a Lutron motion-sensing light switch, wired into an extension cord, and a simple reflective lamp fixture.  And it’s all just clamped to the top of a set of shelves I already own.  Easy peasy.  And it works like a charm.  The switch has two little pots to control sensitivity and on-time.  Which is great, because I love adjusting things.  So now I can pull into the garage, catch those last few minutes of Wait Wait, Don’t Tell Me, and then hop out and voilà, let there be light.  And I saw that it was good (enough).

Now for a while, I lived with problem number one without much complaint.  I had to be in my driveway before the remote would trigger the opener, but it wasn’t a huge deal.  Then for some reason, it routinely started failing me.  My car actually had to be within a few feet of the door for it to open.  And more than once I had to get out of my car (heaven forbid) and wave the remote around in front of it.  I replaced the battery, but this made no apparent difference.

So again, one weekend I decided I’d had enough and sat down at my workbench to sort out the problem.  I popped the project box remote open and started probing.

A very simple garage door opener

To make a long story short, I discovered that the transmitter was simply broadcasting a repeating pulse train via (I believe) amplitude modulation.  Somewhere in the 800kHz range, although I don’t have equipment capable of measuring such high frequencies with any sort of precision.  I can tell you that the DIP switches you see control the sequence of the transmitted pulses to match a particular receiver.

Get on board the pulse train!  Woo woo!

Since I know virtually nothing about RF amplification, and didn’t want to risk damaging the remote, I decided to piece together my own remote from components I had lying around.  Here’s what I used:


  • SparkFun 315Mhz ASK transmitter module ($4)
  • AVR ATTiny13 8-bit, DIP8 microcontroller ($2)
  • 5V Regulator
  • 9V Battery
  • Protoboard
  • Button


  • SparkFun 315Mhz ASK receiver module ($5, discontinued)
  • Olimex AVR-MT-128 development board ($75)
  • 12V wall-wart power supply

Now the precise components specified here aren’t really too important.  I used what I had.  I would recommend the RF transmitter and receiver though (except that the receiver has been discontinued).  These are both pretty amazing for the price; I got them a number of years ago and haven’t yet put them to much use.  But they’re fantastically simple.  Just apply TTL-level serial data to the input of the transmitter, and watch it appear at the output of the receiver.  That’s it.  No configuration/setup required.  The only complication is that there is no error checking.  So you’ll need to be clever about dealing with the occasional garbage data.

So how does this all work together then?  Well, when you press the button on the prototype remote, the 9V battery is then connected to the transmitter module and the MCU (via the 5V regulator).  The MCU then sends out a slew of bit-banged (since the ATTiny13 has no hardware UART) serial data to the transmitter, which then sends it wirelessly to the receiver.

Now this is a garage door opener!  Well, sortof...

The receiver then sends this data to the ATMega128 (on the AVR-MT-128 dev board), which does have a hardware UART.  If the received data is correct, a relay on the dev board is quickly closed and then opened again.  The relay terminals are wired up in parallel with the door open/close button inside the garage.  Thus, the action of the relay simulates a real button press and causes the garage door to open/close.

The receiver

That’s it.  Again, pretty simple, right?  The receiver, since it’s got an LCD display, also indicates how many times the door has been actuated (either opened or closed).  This was a comforting feature during initial testing, because it allowed me to determine whether or not my garage had been opened at any unexpected time.

Sophisticated, yes?Well I’ve been driving around with this silly protoboard taped to my center console for about two months now.  It’s been working great; I can now operate my garage door reliably from the street (a distance of probably 50′), and this little gadget has made for such a nifty conversation piece that I might just leave it in protoboard form.  I mean, a small enclosure would be nice and stuff, but…

Seriously though, if you have any cheap and cheerful ideas for housing the transmitter in a more elegant and robust manner, do let me know in the comments.  By the way, at this point in a post I’d usually provide links to my code, but I’m not going to do that this time.  I’d rather not make it too easy for the tech-savvy thief to break into my garage, you know?  Yea, I’m probably just being paranoid, but still.  Lots of crime in Iowa you know. 🙂

Now ultimately I’d like to extend the functionality of my device so that it automatically opens and closes the door when I come and go.  If you’re curious about how that might be done, take a look at one of my older posts on the subject.  Thanks for reading though, and feel free to pose any questions below!

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.