So, these shapes are pretty but what do you do with them? Imagine that this pattern is fixed to a shaft so that it spins at the same rate as a motor shaft or the wheel, and you put an optical sensor at one spot along the edge of the wheel. The sensor tells at any time whether it sees black or white. Then, if there are 24 divisions in the wheel, you can look at the pattern of black/white reading to see how fast the wheel is turning around. Because 360 degrees divided by 24 divisions is 15 degrees/division, you can sense whenever the shaft turns 15 degrees. But note that with one sensor you can't tell if the wheel is moving clockwise or counterclockwise. For this, we would need another sensor.

If the wheel is moving counterclockwise, sensor 1 sees a light or dark area before it reaches sensor 2. If the wheel direction is reversed, then sensor 2 sees the light or dark first. (In the waveforms, high represents light and low represents dark. Depending on your circuit it might be the opposite.) These sensor readings are 90 degrees out of phase. A simple program in a microcontroller can detect these transitions and turn it into a count that increases when the wheel goes one direction and decreases when the wheel goes the other direction. With two sensors there are two bits of digital information, so you will need two input pins per optical encoder.

Here comes the algebra... The circumference of the circle is 2*PI*r, so when it's divided into d divisions, the width of each division (along the circle) is 2*PI*r/d. I'm taking a shortcut and assuming that each division is small enough that the circle is basically flat for the width of the division. Mathematically, I'm using the approximation sin(theta)=theta for small theta. Now, we have seen that a distance between sensors (s) of one half division gives the two waveforms 90 degrees out of phase. Also, you can use 1.5 divisions, 2.5 divisions, 3.5 divisions, etc. So the distance between sensors can be 2*PI*r/d times (n/2) where n is an odd integer. Solve for d and you get d=(n*PI*r)/s. The next diagram shows the graphical meaning of different values of n. The marked distances represent the distance between sensors for values of n=1, n=3, n=5, etc.

Why did I solve for d? I believe it is easiest to build the motor shaft and attach the sensors first and measure r and s. The sensors should be about as close as they can be. Then, choose a value of n, compute d and round to the nearest even number, and make an encoder wheel with d divisions. Other variations are possible of course, but it's much easier to measure accurately than to build accurately. And it's easy, cheap, and quick to make optical encoders for any value of n and d. A few considerations when choosing n and d:

- n must be odd
- d must be even. When you compute d, it will probably be some wierd fraction so just round to the nearest even. If you're wondering why d must be even, try to divide a circle into 5 divisions and color them alternating black and white.
- If d is too large, you can exceed the resolution of your printer or optical sensors. On a 600dpi laser printer, with a radius of 1 inch you might get up to about d=600 divisions before the quality deteriorates. You could use more divisions if you increase the radius of the encoder wheel. Or you would probably get better resolution on a better quality printer. The specs on optical sensors will often mention the smallest size of object they can resolve, and with large values of d this will start to matter as well.
- With more encoder divisions, your processor will need to sample the encoder inputs more frequently to avoid missing any transitions. If you are running short on processor cycles, this could be important.
- Even when you compute the ideal values for the encoder and create it, you may find that the waveforms are not really 90 degrees out of phase. The radius measurement is tricky because it should be measured from the center of the axis of rotation to the point where the optical sensor is most sensitive, but you may not know where that is until you try it. Also, my assumption that sin(x)=x is only perfect if d is very large, so it could contribute to error. The best solution may be to print a few encoders close to the computed d, and see which ones work best.
- It's not critical that the waveforms are precisely 90 degrees separated. But if they are close to 0 degrees separated (in sync) or 180 degrees separated, the transitions in the two sensors will be so close that you lose all the benefits of having two sensors.

Here are a few types of optical sensors available. I have used the Omron EE-SX1031 in a wheel encoder for a mobile robot. It's convenient because it has two sensors in one package, and the datasheet tells you exactly how far they are apart. Jones and Flynn suggest a Hamamatsu P5587 as a reflective sensor, but I don't have a picture of it.

With a reflective sensor, the encoder wheel can be printed onto a sheet of paper and mounted on some opaque surface. Jones and Flynn suggest that the opaque surface should include several pieces of blank white paper to reduce the amount of light that passes right through the white segments of the encoder. It should probably also be attached to something rigid; you don't want the paper flapping around.

When using a transmissive sensor, the encoder wheel needs to pass through the channel to block the beam. An encoder pattern can be printed onto a transparency and mounted on a clear surface. For best results, print onto a transparency with a laser printer, or photocopy onto a transparency. (Ink from an inkjet printer will smear if anything touches it. If you insist on using an inkjet, then carefully place a wide strip of packaging tape over the whole wheel to reduce smearing.) Then I suggest mounting it on a clear, thin disc to keep it rigid. I make clear discs using a scroll saw:

- Draw the right size circle on paper using a compass.
- Take apart a CD case and tape the paper to it.
- Cut through both the paper and plastic with scroll saw, using the circle on paper as a guide. Use a slow speed to avoid cracks. Wear eye protection!
- File the edges to smooth any sharp spots.

The first encoders I made were drawn with Adobe Illustrator. After making 10 or 20 different kinds, I got tired of the process and wrote a perl script to quickly generate encoder wheels with a variable number of divisions. When you run the script you get one page of Postscript output with up to four encoder wheels on it. Here's a sample output, converted to a GIF so that you can see it in your web browser.

In Unix, to get this output you would type:

./make-encoder.perl 40 100 > encoders.ps lpr encoders.ps

Download make-encoder.perl

Download sample output in Postscript

For Windows users: Perl is available for Windows too. Look for ActiveState perl or download Cygwin (a whole UNIX-like environment, large download). If you don't have any software or a printer that can handle postscript, check out www.ps2pdf.com which can convert postscript to a PDF file, which almost everybody can read. Email me if you have trouble.

Please let me know if you have any suggestions for these pages. I'm not a robotics expert, but I want to share what I have learned.