Our crew is replaceable. Your package isn't.

Dead Reckoning and Encoders

Sun 11 June 2017

There are many types of encoders, above is a US Digital encoder designed to be mounted on a motor shaft.

The optical encoder, shines a series of lights through an encoder disk and the light is detected or not detected on the other side of the encoder disk by some photoreceptors. A quadrature encoder has 2 signals, A and B, which are phased such that they are never high or low at the same time. Depending on the phase of the signals, the direction can be determined.

The animation shows the signals produced from the movement of the motor shaft, with the encoder disk attached to it.

Again, the wave form from A and B tells us if the wheel (motor shaft and disk) are moving in the forward or reverse direction. Note that forward/reverse are arbitrary and the engineer needs to determine if CW or CCW is forward or reverse depending on how the sensor was mounted to the robot.

The resolution of the encoder is determine by how the 2 signals are read.

Now, obviously, the last option gives you the greatest resolution and the best performance ... so why wouldn't you do it? If the speed of your microcontroller is too slow and/or the speed of your wheel is too fast, you could get stuck answering interrupts all the time and never doing anything else. You have to balance your system constraints properly.

Python Pseudo Code

import time
from serial import Serial

count = 0
COUNTS_TO_METERS = 0.001  # this depends on the encoder system

def main_loop():
  ser = Serial('/dev/tty.usbserial0', 115200)

  while True:
    time.sleep(1)  # time depends on speed of robot
    position += count * COUNTS_TO_METERS
    count = 0

    # a super simple serial response to report position
    if ser.read() == 'p':

# an interrupt that gets called every time A or B changes
# you can do this with RPi.GPIO on the raspberry pi
def interrupt_AB():
  A, B = readEncoderPins()
  if A ^ B == 1:
    count += 1
    count -= 1

back to the top