Friday, October 29, 2010

Happy Halloween!

Pokey couldn't think of anything else to be for Halloween this year...

Happy Halloween from Pokey and Bot Thoughts!

Friday, October 22, 2010

Wheel Encoder Generator

Announcing a full-featured, cross-platform, Java-based wheel encoder generator application for all us DIY roboticist types to print our own encoder wheels (as I did on Data Bus).

Download, documentation, source code: WheelEncoderGenerator

Wheel Encoder Generator screenshot; absolute encoder
Flexibility. The application will create incremental encoder discs (below) of any diameter with or without quadrature and index tracks; it'll also make absolute encoder discs (above) of any size using either binary or gray code.

Speed. It instantly displays a preview of your encoder disc as you make changes. The interface is streamlined to put all the configuration a few clicks and keystrokes away. Toolbar buttons and accelerator keys speed operation.

Convenience. The window and preview image are resizeable so you can get a giant preview image if you want. The interface is simple and (I hope) intuitive.

This is an incremental encoder with quadrature.
Save Your Work. You can save, load and print encoder patterns. You can export them as images.

High Resolution. Encoder resolution is theoretically limited only by the dpi resolution of your printer but the code enforces some (arbitrary) limits: 4096-positions, 12 tracks, 0.088° resolution for absolute encoders and incremental encoders with 0.1° resolution.

Cross Platform. The app runs with native look and feel on Windows and Mac OS X.  It should run fine on anything with a JVM.

Friday, October 15, 2010

Comparator With Automatic Voltage Reference

I'm working on building a circuit to adapt the output of wheel encoder sensors to a microcontroller. The output of these IR reflectance sensors is a sine wave, with some issues. Here's the general problem:

Let's say you have a sine wave, and the amplitude varies over time, and the signal is modulated by a lower frequency sine wave.  (In my head I was thinking it was kind of like if the DC offset were varying over time but of course DC doesn't vary...)  The sine wave has to be converted to a pulse train with a voltage comparator. Just pick a reference voltage and anytime the signal is higher than the reference, the comparator output is +5V (ish) and if it's below then it's 0V (ish). You can use a simple voltage divider or a potentiometer to set the reference voltage like so.

Comparator with potentiometer voltage divider for Vref

Simply using a voltage divider as a voltage reference to trigger the comparator isn't good enough. At best, the pulse width will vary as the sine wave varies. That can cause some inaccuracy in measuring speed and distance.

At best, pulse width varies and so does accuracy
At worst, you might miss pulses entirely if you can't get the voltage reference set just right or if the DC offset varies too widely.

It's possible to miss pulses with a fixed reference voltage
Wouldn't it be nice if we could automatically remove the signal component and leave behind the modulation and use that for the comparator reference voltage? Well, we can, and it's not that hard.

All we have to do is use a low pass filter. We filter out the higher frequency output of the wheel encoder sensors, and retain the modulation signal.  Basically what we're trying to do is adjust Vref to be a value between the upper and lower peak of our signal.  We take care of amplitude modulation at the same time.  This same approach can be used to automatically detect the DC offset of a signal and use that as Vref.

A simple low pass filter is more than adequate and keeps parts count low on the 1"x1" printed circuit board I'm designing. Pick a resistor in series with the signal input, and place a capacitor in parallel, and feed the output to the reference pin of your comparator. Like this:

Auto Vref using low pass filter to detect DC offset/amplitude fluctuation
You can experiment in LTSpice or in real life with different values for R and C but the formula to find the cutoff frequency is given by:

A higher value of R and C means the circuit cutoff frequency decreases, approaching but never reaching 0 (DC). You can imagine that a giant capacitor and resistor would filter out most ripple and a tiny resistor and capacitor wouldn't.

I measured the encoder frequency at approximately 100-200Hz. The slope of the frequency response curve for this type of filter is somewhat shallow so there is a tradeoff between the amount of higher frequency attenuation and how quickly the circuit reacts to changing DC offsets.

Frequency response of filter with higher cutoff frequency; -30dB at 100Hz

This first picture (above) shows a higher cutoff frequency and so it is more sensitive to changing DC offsets, but doesn't attenuate the encoder signal as much (-30dB at 100Hz). Which really isn't that big of a deal, as long as there is some attenuation.

Lower cutoff frequency attenuates the signal at 100Hz by -50dB
The picture above shows a lower cutoff frequency and so there's greater attenuation of the higher frequency encoder signal (-50dB at 100Hz). But if the DC offset fluctuates too rapidly, this circuit won't keep up. Because it's attenuating lower frequencies more, too.

In my case, a value of R=10k and C=1uF is a nice happy medium for my particular situation. More compact, low value capacitors didn't attenuate enough and higher capacitance prevented the circuit from tracking DC offset properly.

In the first video below you can make out the larger encoder waveform and the attenuated waveform that makes Vref. Notice how it tracks nicely between the peaks of the signal.

The second video shows the comparator output versus the encoder signal. Notice that the pulse width of the output remains fairly stable despite the DC offset and amplitude fluctuations in the signal.

Some of you may have noticed the phase shift introduced by the filter. This has the added bonus of adding hysteresis to the circuit making it more immune to noise.  [EDITED 11/07/2010]

Friday, October 1, 2010

Simple & Cheap Breadboard Arduino

If you're like me, you want to play with Arduino but you're on a ridiculously tight budget.   Some nice, inexpensive Arduino-compatible kits are available like the Solarbotics Ardweeny or the Boarduino.

Here's how to make a simple, cheap breadboard Arduino. Depending on the chip and bootloader, you can end up with an Arduino Uno or Duemilanove.

  • Atmel ATmega328P w/ bootloader $5.50 + shipping from Sparkfun
  • Electronics parts $4 + shipping
  • FTDI programmer $14 (which you can reuse) + shipping
  • Breadboard ($5-15 but if you're like me, you have several laying around)
We're talking $15 for the basic parts and shipping. Add some extra money for an Arduino-compatible programmer, wire, and a breadboard, all of which you will no doubt use for many projects. Not bad. Not as cheap as an Ardweeny, which you could substitute onto a breadboard leaving more room for circuits... but what the hey.

Breadboard and Protoboard Arduinos

Buying Parts

To make it super simple, here are most of the parts at Mouser (just order qty 1 of the whole project). Now just buy the wire, the FTDI programmer for Arduino, ATmega328P with Arduino bootloader (from Sparkfun; they are now using the Uno bootloader) and a breadboard from Radio Shack, etc.

If you want to source parts on your own here's the list. You can use this list as a guide to order from Digikey to get free shipping by mail order.
  • ATmega328P with Arduino Uno bootloader (Sparkfun)
  • 5V FTDI breakout board programmer (Sparkfun)
  • Breadboard (30 row minimum) (Sparkfun, Radio Shack 276-0003)
  • (opt) 2 x 1K resistors
  • 6 pin breakaway header
  • 4 x 0.1uF capacitors (MLCC)
  • (opt) 3 x 1uF electrolytic capacitors
  • 3mm diffused LED (or, really any standard LED)
  • 470 ohm resistor
  • 16.0000 MHz crystal and 2 x 22pF capacitors -or- 16MHz ceramic resonator (try Sparkfun, Electronics Goldmine, etc)
  • Tactile momentary switch (take apart that broken DVD player, VCR, etc)
  • 10K resistor
  • Hookup wire (red, black, and one other color for the reset line)
  • (opt) 7805 voltage regulator (available just about everywhere)
  • (opt) 9V battery connector (Radio Shack)

Assembly Instructions

These instructions are for the type of breadboard with two power rows at top and bottom (like the Radio Shack 276-0003) and it uses a two-pin crystal/resonator, that is, one without capacitors built in.

An older Arduino with Duemilanove bootloader
  • Install the ATmega328P on the board with pin 1 at row E9.
  • Install a 6 pin header at D1-6 for the Sparkfun FTDI programmer
  • Wire up power and ground wires as shown above (the AVR uses VCC, Analog VCC, and Analog REFerence)
  • Install 0.1 (104) capacitors across 9V power at F1-2 and across G15,17
FYI, the 7805 will be installed at I1-3. I got sick of 9V pigtails pulling out of proto boards, so I finally solder a pigtail right onto a 7805. (below) with marine (gluey) heatshrink holding the pigtails to the case.

Now install optional 1uF electrolytic capacitors as above, across 9V power G1-2 and both 5V power rails.

Install the 7805 at I1-3.

Install a reset button at H6,8 with a line from I6 to ground and G8 to pin 1 of the ATmega, D9. I used a reset button I salvaged from a junk CD player.  I chose a right angle as it fit best. I cut off the support part of the case to make it fit. See below.

Install the 1k TX/RX resistors across C5,11 and A4,10 (pins 2 and 3 of the ATmega) The serial ports and the reset port are used by the Arduino bootloader.

Install the 10k pull-up resistor across A3,9, that is, between VCC on the FTDI header and ATmega pin 1.

Now squeeze a 0.1 uF (104) capacitor between C6,9, that is DTR on the FTDI and ATmega pin 1

Might as well put a 0.1uF (104) capacitor across the ATmega Vcc/GND pins C15,A16. Install 27pF capacitors for the crystal: one at D16,17 the other at C16,D17. Install the crystal across ATmega pins 9 and 10. I had to install mine diagonally: A16,C17 as below: Or, use my eeZee Breadboard Crystal.

For the final touch, to make it fully compatible with the Arduino, add the LED circuit: a 470 ohm resistor from G18,23 and an LED at F23,24 (digital pin 13 on the Arduino).

And that's it, you now have an Arduino on a prototyping breadboard. I've built a half dozen of these along the way for various prototyping and experimenting.

They work great, they're easy to do once you've done a few. Even better when your Arduino bootloader enabled ATmega has a decal on top labeling pins. Most do, nowadays.