Lesson: Exercise: Using Encoders

Explore the use of encoders to create feedback control of motors.

Understand how to use encoders to better control motors by measuring their operation.


So far we have been controlling the distance the robot travels with elapsed time. A more accurate way to control movement is with encoders. Encoders attach to or are integrated into the drive motors and count the revolutions of the motor shaft either optically or magnetically. The DcMotor object has support for using encoder counts to control how long the motor will run when turned on. In the example code we will run forward for 5000 encoder counts and stop. Then we will run backwards to zero encoder counts to the starting point. You will need to add encoders to both of the drive motors. Note that encoders don't count revolutions directly but count partial rotations to allow you to process small movements. A US Digital E4P encoder (in the Tetrix kit) will report 1440 counts for one revolution of the motor shaft. Each type of encoder will have a different counts per revolution value so you need to consult the specs for each encoder you use to determine the number of counts per revolution (if needed for your application).

We set the target position of 5000 encoder counts. Nothing happens until we set the power level on the motors, then they start running and will run until the encoder count reaches 5000 and then stop on thier own. Note we still need to set power to zero when the movement is done.

Our code needs to wait while the motors are running to the target position. The example shows two ways to do that, one watching the DcMotor.isBusy() function (true while motor has not reached the target) and the other compares the current motor position to the target position. You could also determine the amount of time needed to complete the movement and wait for that time to pass. In either case, since we selected the motor run mode as RUN_TO_POSITION, the motor will stop on it's own with brakes on.

Run mode RUN_WITH_ENCODER does not stop on it's own. You have to manage that yourself. RUN_WITH_ENCODER tries to run the motor at a constant speed, which is a percentage of the max speed of the motor. You set the percentage just as you do with percentage of power using the setPower() function. When you set a power level, the speed of the motor will be influenced by the battery power level and will slow down as power fades. When you set a speed level, the motor will adjust it's power to maintain a constant speed, to the extent there is battery power available to accomplish that.

If your program calls for you to run your motors without using encoders after you use encoders, you must set the motors to run without encoders using the enum DcMotor.RunMode.RUN_WITHOUT_ENCODER. Running without encoders just means the motor will take no automatic action, but the encoder is still counting. As shown in the example, you can monitor encoder counts yourself and decide when stop instead of having the motor do it automatically. Having the motor stop automatically is more accurate.

Create a new class called DriveWithEncoder and copy/paste the example code. Demonstrate your program using encoder counts.

In practice, you can determine the number of encoder counts needed to complete a movement experimentally by displaying the counts reported by the motors and manually moving/driving the robot through the movement. You can also measure the number of encoder counts that translate to actual distance in inches or feet and then set your movement in those units, converting to counts. The number of counts to a unit of distance will be a function of wheel size and the gears used between the motor shaft and wheel shaft. Modify the example to move a selected distance in feet. Make the code that converts distance into counts into a function that can be reused.

Here is more information about encoders on the Modern Robotics website.

Here is a quiz on using encoders.