Why a Mouse?
A rotary encoder is the most common way to measure the speed and direction of a motor shaft. Commercial encoders can cost $20–$100 each. A surplus PS/2 ball mouse costs nothing — it is the kind of thing sitting in a box in a closet or available for free at any computer recycler.
Inside every PS/2 ball mouse are two small optical encoder wheels — one for the X axis and one for the Y axis. Each wheel is a slotted disk that interrupts an infrared LED/phototransistor pair as it rotates, generating a quadrature pulse train that the mouse firmware converts to movement counts. These are exactly the kind of incremental encoder signals needed for closed-loop motor control.
By removing these wheels from the mouse and coupling them directly to motor shafts, then reading the PS/2 data stream in Linux, we get two independent encoder channels for almost no cost.
What You Need
- One PS/2 ball mouse (any brand; older models are easier to disassemble)
- Small screwdrivers (Phillips and flathead)
- Needle-nose pliers
- Drill or rotary tool for mounting holes
- Coupling hardware to connect encoder wheels to motor shafts (set screws, epoxy, or custom mounts)
- A computer with a PS/2 port (or a USB-to-PS/2 adapter)
How Ball Mouse Encoders Work
The rubber ball rolls against two plastic rollers arranged at 90° to each other — one tracking left/right (X) and one tracking forward/back (Y). Each roller shaft has a slotted encoder disk. As the disk rotates, it interrupts the beam of an infrared LED, and the phototransistor generates a series of pulses. A second phototransistor offset by a fraction of a slot provides the quadrature signal needed to determine direction.
The mouse microcontroller counts these pulses and transmits relative X and Y movement to the host
over the PS/2 serial protocol. Linux exposes this data through the input subsystem; raw movement
counts are readable via /dev/input/mice or a dedicated PS/2 driver.
Disassembly
- Remove the ball by twisting the retaining ring counterclockwise and lifting it out.
- Unscrew the mouse body (usually one or two Phillips screws, sometimes hidden under label stickers).
- Carefully separate the top and bottom halves of the case.
- Locate the two encoder roller assemblies inside. They are the small shafts with slotted disks visible between the IR LED/detector pairs.
- Note which roller corresponds to the X axis and which to the Y axis.
- Do not remove the encoder disks or the IR sensor boards — the entire mouse PCB and sensor assembly stays intact.
Mounting to Motor Shafts
The goal is to mechanically couple one encoder roller to each drive motor shaft. There are several approaches depending on the shaft diameter and available tools:
- Direct coupling: If the encoder roller bore is close to the motor shaft diameter, a set screw or small amount of epoxy can fix the roller directly to the shaft.
- Flex coupler: A short rubber tube slipped over both the motor shaft and the encoder roller provides a vibration-tolerant connection.
- Gear/belt reduction: If the motor spins faster than the encoder can track, a simple gear ratio reduces the effective counts per revolution.
The mouse housing can be bolted to a bracket near the motor, with only the encoder wheel shaft protruding to couple with the motor shaft. The full mouse PCB, LED, and sensor remain enclosed and protected.
Reading Encoders in Linux
Once mounted, the mouse appears to Linux as a standard input device. The PS/2 protocol reports signed 8-bit X and Y displacement values at roughly 100 reports/second at the default sample rate.
The robot software reads raw PS/2 data directly, accumulating the signed displacement values
into running position counters for each motor. The custom Mencoder class in the
robot codebase wraps this interface and presents the encoder data to the
PID control loop.
// Conceptual Mencoder interface
class Mencoder {
public:
virtual bool ReadEncoders(void) = 0;
virtual int GetEncoderValue(int motor) = 0; // delta since last read
virtual int GetEncoderPosition(int motor) = 0; // absolute count
virtual void SetEncoderPosition(int motor, int value) = 0;
};
Limitations
The hacked PS/2 mouse encoder is a low-cost solution and carries the expected tradeoffs:
- Resolution is limited (typically 200–400 counts per revolution) compared to purpose-built encoders.
- The PS/2 protocol has a fixed report rate (~100 Hz default); very high motor speeds can saturate the count registers between reports.
- Mechanical wear on the plastic roller shafts can introduce backlash over time.
For a $500 hobbyist robot platform, these limitations are entirely acceptable. The PID control loop compensates for noise and quantization errors, and the resulting motion control is more than adequate for indoor navigation tasks.