The codewheel generator is a versatile, simple program that lets a user design
a codewheel for just about any type of homebrew optical encoder project, then
easily print the wheel image on a home inkjet or laser printer.

With a good codewheel in hand, and having cobbled some way to mount said codewheel
to a shaft, building and mounting suitable photodetector arrangement(s) will let
the experimenter replace very expensive commercial optical encoders in home-built
equipment. For projects where encoders were previously cost prohibitive, the
homebrew encoder option expands a hobbyists design horizons.

Although some hobbyists have addressed the encoder problem by
cannibalizing old computer mice for their codewheels, such encoders lack
the resolution required for high precision tuning and sensing. This program
is a step toward solving the cost vs resolution equation at the hobbyist level.

The codewheels generated by this program may be used for a wide variety of encoders,
including quadrature encoders for tuning digital equipment, wheel speed and odometer
sensors for robotics, motor control applications, and many more that haven't even
crossed my mind.

Even some folks who aren't interested in electronics might be interested in this
program. For instance, using the custom wheel type, you can even generate "bullseye"
targets for rifle and pistol target practice!

Image quality is limited only by the resolution of your printer. With a modern high
resolution photoprinter, resolutions available only in the most expensive commercial
encoders become possible to achieve in an inexpensive encoder included in a homebrew
project.

The program runs on XP and Vista operating systems, and is provided as freeware for
personal, non-commercial use. Microsoft .NET is not required to run this program.

I guess the very first topic I should cover is "what is an optical encoder, and
how does one work?"

I had started to write a little tutorial on the subject, when I realized that
I couldn't write just a "little" tutorial. So I Googled aroud the net a bit,
thinking that someone might have already written one.

I found a humdinger, written by Alex Brown for his ARobotics site. Even if
you're conversant with the technology, I recommend that you read his excellent
introduction.

When you have finished, come back here and I'll talk about decoding
quadrature signals, then discuss mounting the codewheel.

Finally, I'll cover the features of the program in detail, which is probably
what you wanted to know in the first place. If so, feel free to skip down to
the "Wheel Types" section.

There are a number of methods of decoding optical encoders, implemented in both
hardware and software. (See the sections below) Every decoding method, though,
will require clean square wave signals with sharp transitions.

The traditional signal conditioning method places a
Schmitt trigger
circuit between the photodetector and the decoding circuitry. The Schmitt trigger
circuit produces the nice, sharp transitions required by your decoder circuit or
software.

If you are using a microcontroller to decode your optical encoder, read the data sheet carefully. You might find that your chosen microcontroller is designed with Schmitt trigger inputs. You might be able to save some external hardware.

The quadrature decoder produces two square wave signals, 90 degrees out of phase
with one another. When the encoder is rotated in one direction, Phase A leads
Phase B. When the encoder is rotated in the other direction, Phase B leads
Phase A.

With a quadrature encoder, you can both count the number of rotation pulses and
detect the direction of rotation.

This is what a quadrature signal looks like, when the encoder is rotated both
clockwise and counterclockwise:

A software quadrature decoder is often implemented as an interrupt-driven
state machine, based upon a state table.

Let's build a state table by referring to the phase diagram, above. For the moment,
just consider the clockwise rotation case.

Starting with the Phase A = 0, Phase B = 0 condition and moving left to right, the
states you encounter are these:

Phase A

Phase B

State 0

0

0

State 1

1

0

State 2

1

1

State 3

0

1

Now look at the diagram for counterclockwise rotation. Find the Phase A = 0,
Phase B = 0 state. Moving left to right, the next state will be Phase A = 0,
Phase B = 1. Then Phase A = 1, Phae B = 1, and finally Phase A = 1, Phase B = 0.

Compare the CCW states with the CW state sequence in the table above.

Phase A = 0, Phase B = 0 is State 0. Phase A = 0, Phase B = 1 corresponds to
State 3. The next corresponds to State 2, and the last corresponds to State 1.
Notice that the state sequence is the same for either direction of rotation. Only
the direction you take to step through the state table varies.

So you can use the same state table for both clockwise and counterclockwise rotation.

The state table is actually circular, with State 3 wrapping around to
State 0, and State 0 wrapping around to State 3, as shown in the figure below.

If you measure your current state and find it in the table, the next state must be
either the state directly above or the state directly below your current state. If
the state in question is the one directly above your current state, then the direction
of rotation is counterclockwise. If the state in question is the one directly below
your current state, then the direction of rotation is clockwise.

Note that "Clockwise," "Counterclockwise," "Phase A," and "Phase B" are relative
terms. In reality, the phases can be reversed with respect to the direction of
rotation. And in the real world, if you build a decoder that's telling you the
wrong direction of rotation, just swap the Phase A and Phase B connections.

Let's assume that you want a counter to increment when Phase A leads Phase B, and you
want the counter to decrement when Phase B leads Phase A.

Set up your state table to match the states in the table above, and establish a
state table pointer. Configure your interrupts for interrupt-on-change for both
the Phase A and Phase B inputs.

Initialization:

Intialize the counter.

Measure the current state of the Phase A and Phase B inputs. Locate that state in
the table. Initialize your state pointer to that state.

Enable interrupts.

Interrupt routine:

If the state is the one preceeding your state pointer, decrement the counter.

If the state is the one following your state pointer, increment the counter.

If neither of those state conditions are true, you have missed a pulse. Set an error
condition. (Depending upon your application, you might just ignore errors, flash an
LED, increment an error counter, etc.)

Point the state pointer to the current state.

The resolution produced by this algorithm depends upon your interrupt configuration.

If you generate interrupts on only one transition, say the positive-going transition
of either the Phase A or Phase B line, you will produce half the number of counts
per revolution as there are cells in your track. For a 250 cell track, you will
recover 125 counts per revolution.

If you configure your system to generate interrupts on two transistions -- say, the
positive-going transitions on both the Phase A and Phase B lines -- you will achieve
the same resolution as your wheel. If you have 250 cells in your track, you will
recover 250 counts per revolution.

If you are able to generate interrupts on all four transitions, that is, both the
postive and negative-going transitons on both the Phase A and Phase B lines, you will
double your wheel's resolution. A 250 cell track will produce 500 counts per revolution.

I've written a little example program for the PIC 12F683, that implements the algorithm
described above. This routine generates interrupts for all possible transitions of the
Phase A and Phase B lines, so it produces the maximum resolution possible from a quadrature
encoder.

There are a plethora of quadrature hardware decoder circuits on the net. A Google
search will turn up more of them that you ever wanted to see!

I've tested the following two simple decoder circuits using
Multisim. For simple
applications, either should work well for you.

The first circuit, shown below, uses a single Dual-D flip flop IC (such as the
CD4013 shown in the sketch) to generate two output "pipes." One pipe squirts out
pulses when Phase A leads Phase B. The other pipe squirts out pulses when Phase B
leads Phase A.

This circuit produces 1/2 the number of pulses as there are cells in your quadrature
track, or for each quadrature track if you're using a two-track wheel. In other words,
if you've built a quadrature wheel with 200 cells per track, this decoder will produce
100 pulses per revolution.

Although this circuit doesn't recover all the resolution availble from quadrature
encoding, it is attractive due to its low chip count. One IC does all the decoding.

The following circuit produces more pulses per revolution, but isn't as low in
chip count as the first circuit.

This circuit uses a single D Flip Flop and a single XOR gate. In the example, I've
chosen 1/2 of a CD4013 Dual_D Flip Flop IC and 1/4 of a CD4030 Quad XOR IC.

The Q output of the flip flop is high when Phase A leads Phase B, and low for the
other direction of rotation.

The XOR gate produces one pulse per cell. In other words, if you've generated
a track with 200 cells, this decoder circuit will produce 200 pulses per revolution.
(If you were doing a simple, non-quadrature decode of a 200 cell track, you would
develop 100 pulses per revolution.)

Gil, N5UK, emailed me to say that he wanted to adapt a quad encoder to add a tuning
knob to a radio receiver that only used a pair of pushbuttons for tuning. I first
recommended the dual flip-flop single 4013 solution, above, but quickly realized that
there was a big problem using that circuit with Gil's radio. Depending upon the position
of the tuning knob when he removed his hand, one or the other of the flip-flops might
remain set. If the radio's pushbuttons auto-repeat, the radio would continue tuning
up or down until he moved the knob. That wouldn't be a workable solution at all.

So I brewed him up a "button pusher" decoder, shown above, that uses a pair of 555 monostables
for both the quad decoder and for timing the output pulses. This circuit gives one pulse for
each synthesized button push, and doesn't have the inadvertent continuous tuning problem
that the single 4013 decoder exhibits.

Roderick Wall, VK3BKO, uses this IC in his homebrew quadrature encoder IC. In
one package, the IC contains a dual infrared photosensor arrangement and full
decoding circuitry, providing direction and pulse outputs. This IC produces
one pulser per cell. For instance, if you've built your codewheel with 200
cells, this IC will produce 200 pulses per revolution.

There's a lot to be said for this IC. Its wire leads provide simple and flexible
mounting. This IC eliminates the need for critical alignment of the two separate photodetectors required for a conventional quadrature encoder, and eliminatds the
board real estate that might be required for other hardware decoder schemes.
Use of one of these ICs and a single infrared LED would greatly simplify your homebrew
encoder project.

Unless you own or have access to a screw-cutting lathe, the likeliest source of
a codewheel mount is a salvaged potentiometer. Here's an example showing how
Lawrence Glaister, VE7IT, mounted a codewheel, salvaged from a computer mouse,
to the innards of a 2-watt pot:

Roderick has designed a very clever quadrature encoder using nothing but
off-the-shelf parts. His original approach results in a very solid encoder
design that's very easy to construct and requires no special machining.

He also arrived at a very neat solution to the problem of punching an
accurately-located center hole in the codewheel: he clamped the codewheel between
two metal washers, then melted the center hole using a soldering iron! Much more
elegant and simpler than my method, using a Pittsburgh hand punch, and provides
goof-proof centering. Nice work, Roderick!

In his own words, here is how Roderick built his encoder:

"Shaft encoder was made up with a ball bearing clamped between two Car mud-flap washers.

The centre of the two washers was drilled (15mm diameter) to allow space for the two nuts that clamps the shaft (a bolt) onto the inner part of the ball bearing. Three 4mm diameter holes (120 deg apart) are drilled in the washers for three 4mm screws that are used to clamp the bearing between the washers and for mounting the shaft encoder to the front panel.

The shaft is a ¼ inch bolt with the head cut off. You may need to file the thread on the ¼ inch bolt to allow the 6mm inside diameter of the bearing to fit onto the bolt thread. Or use any 6mm outside diameter bolt.

Two Car Mud-flap washers with two nuts are used to clamp the optical disk to the shaft.

The top four wheel types, Unencoded, Unencoded with Index Track, Two-Track
Quadrature, and Two-Track Quadrature with Index will probably be of most use to the
experimenter.

The two Absolute
Position wheels will be of possible interest to very advanced experimenters who
might wish to experiment with absolute positioning. Or might be used as a source
of abstract art. <g>

The Custom (User-Defined)
wheel type is there to cover any bases not addressed by the other wheels.

The illustration above might lead you to believe that the program generates
poor quality images. Not so. The jagginess is an artifact of reducing the
full-size .BMP images to web-size. The illustration below is a small chunk chopped
out of a full-size image generated at 4800 pixels per inch, showing that the
program can produce high quality imagery.

The Unencoded and Two-Track Quadrature wheels are the ones you'd want to try if
you want to build a quadrature encoder, as I do.

As you learned from Alex Brown's tutorial, you can implement a quadrature encoder
using a single track wheel, with the two photosensors offsent by 1/2 of the wheel's
cell width. When you consider the narrow cell width of very high resolution wheels,
the experimenter must precisely align the two photodetectors.

I don't really have the facilities in my workshop to precisely fabricate the small,
precision assemblies that I think might be required, so I included the Two-Track
Quadrature wheel to possibly reduce the precision required in photodetector positioning.

When I actually get around to building my encoder (hopefully very soon, now that this
program is finished), I'll make my first attempt using
a two-track quadrature wheel as shown in the figure above. This wheel will provide
accurate quadrature encoding with only a simple vertical alignment of the
photodetectors.

I can't build a precision, finely-adjustable photodetector mount, but I can easily drill
two tiny holes in precise alignment. So I'll fabricate a pinhole mask as shown above.
With a good mask, phototransistor mounting location is no longer critical.

I included this design so hobbyists who experiment with robotics, motor control,
and even folks who are building their own personal transport vehicles could build
cheap and simple encoders for wheel position and speed measurement, odometry,
navigation, etc.

One of these wheels might be in order for applications where the direction of
rotation is known. Because the code track and the index track are separate,
photodetector mounting location isn't at all critical in either the horizontal
or the vertical directions. You can quickly dash out a real "quick and dirty"
encoder that performs as well as the $$$ commercial encoders.

This wheel design would also be suitable for a single-code-track quadrature encoder
that requires an auxiliary index output. (If you'd like a two-track quadrature encoder
with an index mark, I'm afraid that you'll have to fabricate your design using the
custom wheel type.)

While these are of little use for hobbyists (I think... but I've been massively
wrong before), they might have some use in amateur industrial control applications
built by very experienced constructors.

An absolute position wheel's code output is a direct function of the angle of rotation.
As the shaft turns, the code increases until it reaches the maximum value
(or decreases until it reaches zero) and then rolls over.

These sensors require lots of tracks and lots of precisely-aligned photodetectors. A
256-position absolute positiong wheel (the largest this program can generate) requires eight tracks and eight photodetectors.

There are some multi-track SMD photosensors on the market that might ease construction
of an absolute positioning wheel, if your application absolutely demands one of these.

Personally, I think that if one of these wheels is actually ever used, it will be used
as the background for nametags at radio club meetings, and not as encoders. <g>

The program can generate codewheels encoded in either
Gray code or binary, and can be
configured to have the code value either increase or decrease as the wheel is rotated
in a given direction.

I've included the custom wheel design for applications not covered by the other five
wheel types.

You can build a custom wheel of from 1 to 8 tracks. Each of your tracks may contain
coding or can be configured as a blank track.

You define your coding for each track by entering a string into the appropriate
track data box. Strings don't have to be of equal lengths. If you want 250 cells
on the outer track and 6 cells on the next one, the program will accommodate your
desires. You'd enter a 250-character string for the outer track, and a 6-character
string for the next track.

In the string entries, "1" represents a filled cell, and "0" (zero) represents a
blank cell.

You can even enter a single digit for each track. For instance, if you build a
5-track custom wheel with each track defined by only a "1" or a "0", you'll wind
up with a pretty neat bullseye target!

The information in this section pertains to the overall operation and
application of the Codewheel program. For specific information on the use of
any particular feature, refer the the program's help file. To open the help file, press the F1 key after you've launched Codewheel.

At your first program launch after installation, the program should come up with
tool tips enabled. After you've learned the program's controls, you can turn
tool tips off by clicking the Tool Tips choice on the Help menu.

The program should work with any Windows-qualified graphic printer, including
virtually all the inkjet and laser printers on the market. For final output of
your codewheel image, I'd recommend either transparent stock or single-weight
glossy photo paper. Of course, for drafts, or if you're just fooling around with
the program, use the cheapest paper you have on hand.

Select the wheel type. As you click each button, a thumbnail will pop
up in the preview window so you'll have an idea of the structure of the chosen
wheel type.

Enter your desired number of tracks, the outside and inner diameters, and your
desired resolution. (Enter a resolution value that is at least as high as your
printer's best resolution, and preferrably even higher than that.)

(Note that the read-only .BMP file size box will automatically display the
estimated .BMP file size as you change the outer diameter and resolution
settings, and that the number and size of the track data boxes in the lower screen
area will vary in number and size based upon the wheel type and number of tracks.)

If you've selected an Absolute Position wheel, choose the direction for increasing
code value -- either clockwise (CW) or counter-clockwise (CCW).

Check the Negative box if you'd like to print a negative image.

If you wish, you can generate a low-resolution preview of your wheel's actual
configuration by clicking the Preview button.

Enter your track information in the track data boxes on the lower section of the
screen. For all but the Custom wheel type, you'll need to enter the number of
cells for a given track. For Custom wheels, enter the string that corresponds to
your desired track pattern. ("1" for a filled cell, "0" for a blank cell)

For the wheel types not mentioned below, you can select one or more blank
tracks by checking the appropriate No Code checkbox. You might choose a blank track
to provide spacing for a nice, professional-looking wheel.

If you don't select any blank tracks, the coding will extend from the periphery to
the wheel's inner diameter (or hub) circle.

The Unencoded with Index wheel's geometry is fixed at two tracks, with only the
number of cells on the outer track variable. You'll only see a single track data
entry box for this wheel type. If you choose more than two tracks, all extra tracks
will automatically be generated as blank space.

When you choose an Absolute Position wheel, the track data is fixed. You won't
be able to change the track data, or configure any blank tracks, for either of these
wheel types.

To print your wheel, click the Print choice on the File menu, or press Ctrl+P.

A printer selection box will appear. Choose the printer you'd like to use, then
configure the printer's settings. If you have the option, set your printer and
print driver to the maximum quality settings. Click OK.

Another box will pop up, showing you the configured print resolution, and asking if
you would like to proceed. If you click the Yes button, your codewheel will print.

To save your codewheel to a .BMP file, click the Save As... choice from the file
menu. A file selector box will appear. After you enter the filename, click the OK
button. The program will save your program to the named .BMP file.

If the program detects a setup data error, it will prompt you with either an
appropriate error message or turn one of the edit boxes red.

If you see a red box error, just click that box to clear the error condition and
enter the correct data.

2) Install the program by locating and double-clicking your downloaded .msi file.

The program will be automatically installed in C:\Program Files\Codewheel, and the installer will create a desktop icon.

3) Double-click the desktop icon to launch the program.

If you have installed a previous version of this program, the procedure listed
above will cleanly install V1.1.0 over your old installation. You do not have to
uninstall your previous version prior to installing this version.

To "Frank," for his support and encouragement, his diligent alpha and beta testing,
superb feedback, and lots of great suggestions and ideas. This program is a much
better product because of his hard work.

Lots of good information about the ins and outs of industrial rotary encoder design and application. You can read this blog to see how and what "the big guys" are doing, and perhaps gain some information and ideas that will help you with your own projects.