Codewheel Generator Page


Codewheel V1.1.1, Released June 10, 2008




Page Contents




Optical Encoders

Alex Brown's Optical Encoder Tutorial   (external link)

Optical Encoder Signal Conditioning

Decoding Quadrature Signals

Software Decoding

Quadrature Decoder Algorithm

A Quadrature Decoder for the PIC 12F683

Hardware Decoding

Honeywell HLC2705 Integrated Sensor/Decoder IC


Mounting Your Codewheel

Lawrence Glaister, VE7IT

Roderick Wall, VK3BKO


Wheel Types

Quadrature Wheels

Unencoded with Index Track

Two-Track Quadrature with Index Track

Absolute Position Wheels

Custom (User-Defined)


Program Operation

Generating a Codewheel

Printing a Codewheel

Saving a Codewheel


Installation Procedure for XP and Vista Users

Installation Procedure for Win98 Users


Revision History








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.



  • Windows 98, 2000, XP, and Vista supported
  • Very easy to use
  • Generates seven different types of codewheels of 1 to 8 tracks each
  • Hassle-free printing: the program automatically prints the codewheel at the specified size, with no print driver magic required by the user.
  • Physical size and resolution are limited, for the most part, by the printer's capabilities.
  • Prints both positive and negative images. Negative images facilitate photo-reproduction of your wheel images. The program automatically accommodates printers having unequal vertical and horizontal resolutions.
  • For project documentation purposes, the program can also save the generated codewheel images as 1-bit-per-pixel .BMP files.

  • The absolute position wheels may be generated with the code increasing in either the clockwise or counterclockwise direction.
  • Oh, and did I mention that the program is free? (Well, it's free for your personal, non-commercial use, that is...)



Optical Encoders

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.

Alex Brown's Optical Encoder Tutorial



Optical Encoder Signal Conditioning

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.



Decoding Quadrature Signals

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:



Software Decoding

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.


Quadrature Decoder Algorithm
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.


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.


A Quadrature Decoder for the PIC 12F683
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.


Download the 12F683 Quadrature Decoder Listing


Hardware Decoding

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.


Honeywell HLC2705 Integrated Sensor/Decoder IC
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.

As of July 29, 2008, this IC was available from Allied Electronics for USD $5.57.



Mounting Your Codewheel

Lawrence Glaister, VE7IT

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:

VE7IT Codewheel Mount

Roderick Wall, VK3BKO

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.

Parts: 4 x Car mud-flap washers (31.5mm outside diameter with inch hole) 1 x inch bolt (select one that has a shaft 6mm diameter) or any bolt with an outside diameter of 6mm. 4 x Nuts to fit above bolt 3 x 4mm 35mm long metal thread screws 6 x 4mm Nuts for above screws 1 x 6mm inside diameter, 19mm outside diameter, 6mm wide ball bearing 1 x Tuning knob (6mm shaft) (Rockby Electronics - Australia) Lead to balance the tuning knob (fishing sinker), an unbalanced knob will always turn.

All the above parts except for the ball bearing, tuning knob can be purchased from BUNNINGS WAREHOUSE (in Australia). "

Thanks very much, Roderick. A very impressive and clever design! --Tom



Wheel Types

The program can generate the seven wheel types shown below.


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.


Full-size Image generated at 4800 pixels / inch


Quadrature Wheels

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.

At least it sounds good in theory...


Unencoded with Index Track
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.)


Two-Track Quadrature with Index Track
This wheel might be used for motor control applications where you need to detect the direction of rotation, measure speed, and count the number of revolutions.


Absolute Position Wheels
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.


Custom (User-Defined)
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!



Program Operation

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.


Generating a Codewheel

Generating a codewheel is a very simple task.

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.

You're now ready to print and/or save your codewheel.


Printing a Codewheel

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.


Saving a Codewheel

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.



Installation Procedure for XP and Vista Users

1) Download Codewheel.msi, 620 kB

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.


Installation Procedure for Win98 Users

If you have installed a previous version of this program, navigate to the installation directory and delete Codewheel.exe and CodewheelHelp.chm. Then complete the following procedure.

1) Download, 430 kB

2) Unzip the archive into any empty folder.

3) Navigate to that folder using Windows Explorer.

4) Right-click Codewheel.exe. From the popup menu, select Send To... Click the Send to Desktop as Shortcut menu choice.

5) Locate the Codewheel icon on your desktop. Select it. Press F2. Rename the icon to something like "Codewheel"



Revision History

  • Version 1.1.1 - June 10, 2008 - Bug fix: the Absolute Binary wheel would be genrated as CW-increasing, no matter what the setting of the Direction button.
  • Version 1.1.0 - June 7, 2008 - Added the Two-Track Quadrature with Index wheel and cleaned up the user interface
  • Version 1.0.0 - June 4, 2008 - Initial Release




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.




Quantum Devices Rotary Encoder Blog

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.



Copyright © 2008 Tom Lackamp
All rights reserved