This post is part of my series examining VEX sensors, one at a time, to review how each works and what they’re used for in competitive robotics. Shaft encoders are one of VEX’s most widely-used sensors.

Handy-Dandy Table O’ Contents

Quadrature/Optical Shaft Encoders

VEX optical shaft encoders$20 for a 2-pack

The optical shaft encoder, also called a quadrature encoder, is a very popular sensor—sturdy and reliable. My team has shifted our building to use this type of encoder instead of the Integrated Motor Encoder (IME). My earlier post lists the large, large number of ways that IMEs can screw up your robot. I recommend not using them if you have the option to use these instead.

In the middle of last season, while we were struggling with IME bizarre behavior, we took a look around when we were at competitions. Do you know what all of the top teams had on their chassis? Big red shaft encoder boxes, and not one single integrated motor encoder. To the novice team, these may seem bulky and less sophisticated, and one might think that a measuring device connected to the back of the motor itself (an IME) would be better, but one would be wrong…

Plan for It in Your Design

On this VEXU robot from New Zealand you can see the potentiometer in use on the arm, and the shaft encoder by the back wheel.

As with potentiometers, using these encoders requires advance planning. As you can see from the product image above, these items take up space (they’re more than 3/4″ thick). On a chassis they are typically installed in between the wheel’s supporting c-channels (the structure of one side of the chassis is something like: c-channel, wheel, encoder, c-channel, with spacers & shaft collars thrown in as needed). These sensors come in a handy 2-pack because you often use one on each side of your robot’s chassis to help you keep the robot driving straight in autonomous mode, in addition to knowing how far you’ve gone.

The chassis is not the only place to use these sensors, but it is the most popular.


As shown above in the product image, there are 2 wires leading out of each shaft encoder that get plugged into neighboring digital ports on the cortex. In RobotC in the Sensors setup window, once you tell it you’ve got one of these wires plugged in, it prompts you to tell it where the second one will go. In easyC, you just need to make sure they are plugged into neighboring digital ports, and label them respectively in the setup window.

If they are not plugged into the correct ports, you will get junk data; you’ll know (e.g., changing only between -1 and 1, large jumps, etc.). Use the online window/debugger to make sure that when you manually move the wheel with the encoder on it, the numbers are counting up or down smoothly.

A Special Note About Ports 4 & 10

Once you’ve got a lot of sensors on your robot, the analog & digital ports can fill up fast. 4 shaft encoders = 8 ports; you get the idea.

The VEX cortex has an important limitation, the understanding of which will save your team lots of agony of the “why is it doing this?!?” variety. The way the cortex is constructed, digital ports 4 and 10 use the same bit of memory; if you have an input on each, it will overwrite port 4’s information with what it reads a moment later from port 10. What this means for shaft encoders is that you cannot use encoders on both ports 4 AND 10 at the same time.

The safest bet is to only use digital 4 OR 10 on your robot. If, however, your cortex is jammed up with stuff, and you must make use of every port, then either port 4 or port 10 must be connected to a bumper or limit switch, pneumatics, or an ultrasonic sensor’s input wire, which involve different types/speeds of data communication to the cortex.

See this VEX Forum thread, or this other thread for the technical details.

How Does It Work?

Diagram of shaft encoder

Schematic of the sensor’s working parts from the PDF info sheet.

Inside the red box is an infrared light and a sensor on opposite sides of a wheel with lots of little holes/slots in it (image at right). The sensor can tell when light is shining through the holes and when it is not, and thus can count the number of “clicks” that have gone past its viewing window. One full revolution includes 360 clicks (not 90 clicks, as described on the downloadable info sheet).

The reason that these encoders have 2 wires (the older model had only one sensor/one wire) is that the second wire—attached to a second sensor inside the device—allows the cortex to know which direction the wheel is spinning. One could use these sensors with just one wire plugged in—simulating the older version of the component—if (a) you don’t care what direction the wheel is moving, (b) you know it will only move in one direction in your usage, AND (c) you have so many sensors and gizmos that you have run out of digital ports on the cortex (my team is not there yet).

Sensor Output

It’s Digital?

Hey! I thought a digital sensor just returned 1s and 0s. What’s the deal?

Underneath it all, these shaft encoders are indeed digital sensors. When the infrared light makes it from the light to the light sensor through one of the open slots, the encoder spits out a 0 (LOW). When the light is blocked it spits out a 1 (HIGH). The cortex keeps track of these 1s and 0s to generate a running count of clicks. Combined with information from the second wire to the cortex (which gets data from the second infrared sensor inside the device), it knows what direction the shaft/wheel/encoder is moving: the cortex knows whether to add to its click count or subtract from it.

Values Can Be Negative

As with integrated motor encoders, your sensor data may include negative numbers, and that’s just fine! If the wheel turns in one direction from its starting place, the clicks count up. Spin it back to the start and then a little more, and you’ll see negative numbers. Your programmers should be aware of this possibility when writing mathematical functions using the sensor output.

Relative vs. Absolute Position

There’s an important distinction to be made here between encoders and potentiometers; understanding it will help you figure out which sensor you need for the task at hand.

Shaft encoders (and IMEs) count the number of “clicks” that your robot has moved—relative to its starting position. Think of it like your car’s trip-counter, which you can set to 0 whenever you please. The trip counter tells you how many miles (or kilometers) you’ve travelled since you pressed the button: it’s your current position RELATIVE TO your starting position. A shaft encoder is like a trip counter for your robot—you can set it to 0 whenever you please and, unlike a car’s trip counter, it has the added ability to count backwards, all the way into the negative numbers. And like your trip counter, the encoder can count up very high, until it gets to the maximum set by the manufacturer.

When you turn off the robot, it’s like disconnecting your car’s battery: when you turn it back on, the trip counter/click counter is reset to 0 automatically.

Encoder ==> Relative position

GPS satelliteNow think about GPS. If you check your GPS location right now, the satellite system will give an ABSOLUTE location on the globe of where you are via latitude & longitude numbers. A potentiometer is more like GPS. It has a value of 0 at its lowest point and a value of 4095 at its highest point; that’s it. When it’s attached to a robot’s movement arm, the potentiometer returns a number from 0 to 4095 that represents the arm’s exact location.

If I go on holiday and come back to my house, the GPS will give me the same location as when I left. The potentiometer is the same way. If you turn off the robot with its arm in a specific place, and the last reading it gives you is 1000, when you turn the robot back on it will still read 1000 (provided you haven’t moved the arm when it was off). It does not reset to 0, ever.

Potentiometer ==> Absolute position


Basic Autonomous Movement

The most basic use of encoders is for autonomous movements. Instead of “drive forward for ## milliseconds” your instruction would now be “drive forward for ## clicks.” The VEX info sheet describes how you can calculate the number of clicks your robot needs to travel by using the wheel diameter combined with basic geometry and algebra.

  1. Calculate the circumference of your wheel using 2 * π * r or π * d.
  2. For a 3″ diameter wheel, one revolution of the wheel makes the robot move about 9.5 inches (3 * 3.14159).
  3. From above, you know that one complete revolution of the wheel is 360 clicks.
  4. Put it together: 360 clicks = 9.5 inches for a 3-inch wheel. (You’ll get a different #inches when using other wheel sizes.)
  5. Using a tape measure, determine the distance on the field that your robot has to move; employ a little middle-school algebra with these known click-and-inches values, and you can get a starting point for programming an autonomous movement.

Other ways to figure out clicks:

  • Trial and error; the old stand-by.
  • Use the online window (easyC), debugging window (RobotC), or LCD screen. Place your robot on the field and either push it or drive it to its final destination. Note the starting and ending number of clicks and VOILA!

Fine-tuning and getting drive-distance clicks is then a matter of trial and error, no matter how you get your starting estimate. Inertia will move a robot forward even after its designated number of clicks and motor-shutoff. Effects like this will be different for every robot, so getting this just right requires that your programmers have TIME with the robot. You cannot expect to program even a 15-second autonomous movement the night before the tournament.

Driving Straight

Shaft encoders are frequently used to help keep a robot moving straight ahead, in both autonomous and driver-control modes (the latter being rather more complex).

Even with brand-new motors, the 4 motors on a robot chassis will perform slightly differently from each other; that difference can become more pronounced when the motors get some wear & tear on them. Add to that the fact that a robot may not have its weight evenly distributed side-to-side, or that different axles may be under different amounts of friction. So, how to make your robot still drive straight? How can you prevent it from veering off to one side?

Enter encoders! If the robot has one encoder on each side of the chassis (e.g., the back-left and back-right wheels), then you can count the number of clicks registered from each side. With this comparative information, via programming one can make frequent small increases or decreases in power to a one side (the “follower” — formerly known as the “slave”) to help it stay on track with the other (the “leader”, formerly known as the “master”). If these power adjustments are too large, however, the robot will zig-zag as it over-compensates on each oscillation.

The type of algorithm used for this on-the-fly power adjusting to achieve straight driving is called PID. It is far too involved to add to this post, though I will put this topic on my list of future posts. Readers can also start with a Google search of “PID + vex.” There are also numerous YouTube videos available that are quite helpful and clear. {Edit: See my 2018 post for links to numerous PID resources.)

Calculating Speed

Speed = Distance / Time

That’s a pretty basic physics formula, well known & loved. In VEX, you may on occasion need to calculate RPMs (or more likely revolutions per second, RPS) on some part of your robot—such as a flywheel—that you would like to stay at a constant speed for consistency of operation. In VEX, there’s no way to know your speed without an encoder. Yay! Encoders to the rescue!

Again resorting to basic algebra from above, we know that one rotation of the axle is 360 clicks. Both easyC and RobotC have built-in timers that are available for you to use. You can tell your program to check the encoder count every ## milliseconds. Example:

  • set a timer to check the click count every, say, 500 milliseconds
  • ##clicks since the previous measurement / 360 = XX rotations of the axle
  • XX rotations / 500 milliseconds / 1000 = ZZ rotations per second, or RPS (a.k.a. *revolutions* per second; means the same thing)
    (Note that you must convert your milliseconds into seconds in the equation above by dividing by 1000)

As above with using encoders to keep a robot driving straight, *doing* something with your calculated speed will require some more sophisticated programming and probably a PID algorithm, as noted above.

(Note: if you’re measuring speed, and your motor and wheel are connected with gears, make sure you understand what you’re measuring. Attach encoder to the motor’s axle ==> measuring RPS of the motor; attached to the wheel’s axle ==> measuring speed of the wheel.)

JPearman’s Smart Motor Library

See my post from a few weeks ago about using jpearman’s Smart Motor Library (for RobotC users, only; sorry easyC users). His library is a big batch-o-code that monitors motor speeds via encoders, and estimates their current draw and temperature; if it senses things are getting out of hand, it puts the brakes on before you get to the motor-overload-now-my-robot-is-dead stage. BUT, in order for the library to keep track of a motor’s speed, it needs encoders, as described above.

♦          ♦          ♦

Additional Posts on VEX Sensors