Introduction: DIY Quadrature Encoder for Arduino

This is a simple DIY quadrature encoder, made for position and direction sensing of a motor. I built it to show that an encoder need not cost a lot of money, and to demonstrate the Arduino code used to control the motor's position, which moves a rack and pinion to various positions (manually, and also via settable positions stored in flash memory). I used an I2C motor driver and I2C LCD, plus a resistor ladder network of 5 push buttons connected to one ADC input to minimize the number of wire connections to the Arduino.The encoder uses two digital inputs from the hall sensors, one of which is interrupt pin 2. There is one digital input for a start position microswitch.

The encoder wheel is 3D printed, holding 16 inexpensive 3mm x 3mm cylinder magnets spaced evenly on the outer edge of the disk, alternating north and south poles. The motor used has to have a long enough shaft to fit both the output gear and the encoder; usually, such a motor has a shaft on either end of the motor, one for the output gear and the other for the encoder wheel. The two magnetic sensors used in my design are individual bipolar Hall devices, which change state and latch on each magnetic field reversal. They sell a dual bipolar latch, but it limits you to a specific design encoder wheel because internally the sensors are only 1mm apart. I prepared the sensors by soldering a surface mount 470 ohm resistor and green surface mount indicator LED across the +5 and output lead of each. Next super glued one sensor on to one side of a 3D printed a hall sensor holder, then powered up both sensors and adjusted the position of the other sensor so that the indicator lights flashed 90 degrees out of phase when turning the encoder wheel by hand. The sequence should look like [left on, right off], [left off, right off], [left off, right on], [left on, right on] for one direction, and [left off,right on], [left off, right off], [left on, right off], [left on, right on], for the other direction. Glue the other sensor down when these sequences are observed.


6 vdc gear motor, 3 rpm (Aliexpress)

plastic rack, 4mm W x 7 mm H x 125 mm L (Aliexpress hobby pack of assorted gears)

10 mm OD pinion gear (salvaged from an old inkjet printer)

Rack guide (3D printed in ABS)

5 button assembly from old VCR

microswitch (parts drawer)

buttons (salvaged from the inkjet printer)

2 x 16 LCD with I2C serial backpack (Aliexpress)

Sparkfun MiniMoto I2C motor driver (Sparkfun)

4 AA battery holder for motor power supply (old Radio Shack)

battery clip connector (parts bin)

2 Bipolar Hall sensors Melexis US1881LUA, (Digikey)

Surface mount 470 ohm resistors mounted on sensors (Aliexpress)

Surface mount green LEDs mounted on sensors (Aliexpress)

Silicon wire, 24 AWG, various colors (Aliexpress)

Headers and connector pins (Aliexpress)

Hot Glue gun for insulating plugs and holding wires in place

Step 1: Code and Position Display

The Arduino code starts by initializing the rack's position by driving it until it hits a microswitch at one end of travel. From there, the rack can be moved via left and right buttons. Positions can be saved to flash memory by holding down a save button then pressing the left or right preset position buttons. To move to a predefined position, press either of the preset position buttons. The LCD displays the current position, as well as the preset positions.`

Thanks to


Sparkfun for their MiniMoto motor driver and code :

My Code (with above help)