LogoLogo
  • Introduction
  • Getting Started with Control Hub
    • Connect to the Robot Controller Console
    • Updating Wi-Fi Settings
    • Connecting Driver Station to Control Hub
    • Wiring Diagram
    • Next Steps
  • Getting Started with Driver Hub
  • Adding More Motors
    • SPARKmini Motor Controller
    • Adding an Expansion Hub
  • Troubleshooting the Control System
    • General Troubleshooting
    • Control Hub Troubleshooting
    • Driver Hub Troubleshooting
      • Driver Hub Battery Troubleshooting
    • Expansion Hub Troubleshooting
    • Status LED Blink Codes
  • System Overview
    • Control Hub Specifications
    • Expansion Hub Specifications
    • Driver Hub Specifications
    • Port Pinouts
    • Protection Features
    • Cables and Connectors
      • XT-30 - Power Cable
      • JST VH - Motor Power
      • JST PH - Sensors and RS485
    • Integrated Sensors
    • Dimensions and Important Component Locations
  • Updating and Managing
    • Managing Wi-Fi on the Control Hub
    • REV Hardware Client
    • Updating Firmware
      • Firmware Changelog
    • Updating Operating System
      • Control Hub Operating System Changelog
    • Updating Robot Controller Application
      • Updating Robot Controller Application via Android Studio
    • Updating the Driver Hub
      • Driver Hub OS - Change Log
    • Accessing Log Files
    • Android Studio - Deploying Code Wirelessly
  • Hello Robot - Intro to Blocks Programming
    • Welcome to Hello Robot!
    • Where to Program - Client vs. Browser
      • What is an OpMode?
    • Setting up a Configuration
      • Common Errors in Configuration
    • Using a Gamepad
    • Part 1: Tackling the Basics
      • Tackling the Basics Directory - Blocks
      • Creating an OpMode - Blocks
      • Programming Essentials
      • Programming Servos
        • Programming Servo Basics
        • Using a Gamepad with a Servo
        • Programming Servo Telemetry
      • Programming Motors
        • Programming Motors Basics
        • Programming a Motor with a Gamepad
        • Programming Motor Telemetry
      • Programming Touch Sensors
      • Programming Color Sensors
        • Color Sensor Telemetry
        • Detecting Color
    • Part 2: Robot Control
      • Robot Control Blocks Directory
      • Programming Drivetrain Motors
      • Arcade Style TeleOp - Blocks
        • Establishing Variables in Blocks
        • Motor Power vs. Robot Movement
        • Programming Arcade Drive
      • Arm Control - Blocks
        • Adding a Limit Switch
      • Robot Control Full Program
    • Part 3: Autonomous and Encoders
      • ElapsedTime - Blocks
        • ElapsedTime Setup
        • ElapsedTime Logic
        • ElapsedTime - Multiple Movements
      • Encoder Basics
      • Drivetrain Encoders - Blocks
        • Converting Encoder Ticks to a Distance
        • Moving to a Target Distance
        • Setting Velocity
        • Turning the Drivetrain Using RUN_TO_POSITION
      • Arm Control with Encoders - Blocks
        • Estimating the Position of the Arm
        • Calculating Target Position
        • Using Limits to Control Range of Motion
    • Part 4: Going Beyond!
      • Exploring Functions
      • Programming Mecanum - Simplified
      • Programming Mecanum - Refined
  • Hello Robot - Intro to OnBot Java Programming
    • Welcome to Hello Robot!
    • Where to Program - Client vs. Browser
      • What is an OpMode?
    • Setting up a Configuration
      • Common Errors in Configuration
    • Using a Gamepad
    • Part 1: Tackling the Basics
      • Tackling the Basics Directory - OnBot
      • Creating an OpMode - OnBot
      • Programming Essentials
      • Programming Servos
        • Programming Servo Basics
        • Using a Gamepad with a Servo
        • Programming Servo Telemetry
      • Programming Motors
        • Programming Motor Basics
        • Programming a Motor with a Gamepad
        • Programming Motor Telemetry
      • Programming Touch Sensors
    • Part 2: Robot Control
      • Robot Control OnBot Java Directory
      • Programming Drivetrain Motors
      • Arcade Style TeleOp - OnBot Java
        • Establishing Variables in OnBot Java
        • Motor Power vs. Robot Movement
        • Programming Arcade Drive
      • Arm Control - OnBot Java
        • Adding a Limit Switch
      • Robot Control Full Program
    • Part 3: Autonomous and Encoders
      • ElapsedTime - OnBot Java
        • ElapsedTime Setup
        • ElapsedTime Logic
        • ElapsedTime - Multiple Movements
      • Encoder Basics
      • Drivetrain Encoders - OnBot Java
        • Converting Encoder Ticks to a Distance
        • Moving to a Target Distance
        • Setting Velocity
        • Turning the Drivetrain Using RUN_TO_POSITION
      • Arm Control with Encoders - OnBot Java
        • Estimating the Position of the Arm
        • Calculating Target Position
        • Using Limits to Control Range of Motion
  • Sensors
    • Introduction to Sensors
    • Digital
    • Analog
    • I2C
      • IMU
        • Orientating the IMU
      • Adding an External IMU to your Hub
    • Encoders
      • REV Motor Encoders
      • Through Bore Encoder
    • Using 3rd Party Sensors
      • Sensor Compatibility Chart
  • Useful Links
    • REV DUO Build System
  • Legacy Documentation
    • Configuring Your Android Devices
    • Expansion Hub with Android Device Robot Controller
      • Driver Station and Robot Controller Pairing
      • Wiring Diagram
      • Configuration
    • REV Hub Interface Software
Powered by GitBook
On this page
  • What is an Encoder?
  • Exploring Motor Modes
  • Using STOP_AND_RESET_ENCODER
  • Using RUN_WITHOUT_ENCODER
  • Using RUN_USING_ENCODER
  • Using RUN_TO_POSITION

Was this helpful?

Export as PDF
  1. Hello Robot - Intro to OnBot Java Programming
  2. Part 3: Autonomous and Encoders

Encoder Basics

PreviousElapsedTime - Multiple MovementsNextDrivetrain Encoders - OnBot Java

Last updated 5 months ago

Was this helpful?

What is an Encoder?

Encoders are a form of sensor built into some motors that help provide feedback to our robot. There are different kinds of encoders, but we're going to be focus on what's called a quadrature encoder for this tutorial. These encoders are able to count the number of revolutions of the motor also sometimes called "ticks".

While quadrature encoders aren't able to tell exact positions, they can still be used to help the motor move to a specified point. We'll go over how to do so later in this tutorial, but this works by specifying first an origin point in our code then a point the motor should move away.

Quadrature vs. Absolute Encoders

You may see the term absolute encoder when referring to something like REV's . Absolute encoders have a set origin allowing exact movements of the motor in comparison.

Here's a hint for how to remember the difference:

  • Quadrature Encoders are like a stopwatch continuously adding up time!

  • Absolute Encoders are more like a clock telling an exact time!

Exploring Motor Modes

Let's take a closer look at the different modes we can set our encoder to with our motor. The mode is often established during the initialization process of our code, meaning the motors are ready to go throughout our program, but it is possible to change this for specific use cases as it executes.

Which mode we need to use largely depends on the intended function of the motor and any attached mechanism. For example, we may not need our encoders active on the drivetrain motors when they're being controlled by a joystick's input. On the other hand, we may have a flywheel design that requires a specific speed our encoders can help us achieve.

Using STOP_AND_RESET_ENCODER

When using encoders, it is strongly recommended to first use STOP_AND_RESET_ENCODER during initialization. This will allow you to know what position the motor is starting in, however you will want to plan for a repeatable start up configuration each time!

A motor can be switched to "STOP_AND_RESET_ENCODER" while a code is executing as well. This is often set up using a button on the gamepad to allow the driver to reset the encoder in the event of a motor misbehaving, such as after the robot's been caught on an obstacle.

Below is a snippet of code that demonstrates how to reset the encoder in OnBot Java. You can skip the first line if you already have retrieved the motor object from hardwareMap:

DcMotorEx motor = hardwareMap.get(DcMotorEx.class, "Motor");
motor.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);

Using RUN_WITHOUT_ENCODER

Use this mode when you don’t want the Control Hub to attempt to use the encoders to maintain a constant speed. You can still access the encoder values, but your actual motor speed will vary more based on external factors such as battery life and friction. In this mode, you provide a power level in the -1 to 1 range, where -1 is full speed backwards, 0 is stopped, and 1 is full speed forwards. Reducing the power reduces both torque and speed.

The RUN_WITHOUT_ENCODER motor mode is very straightforward, you simply set a power throughout the program using the "Power" block or, such as for a drivetrain, to be set by the joysticks.

The power level is set in Java by calling setPower() on a DcMotor or DcMotorEx object, as shown in this snippet. You can skip the first line if you already have retrieved the motor object from hardwareMap.

DcMotorEx motor = hardwareMap.get(DcMotorEx.class, "Motor");
motor.setMode(DcMotor.RunMode.RUN_WITHOUT_ENCODER);
// This will run the motor forward at half-power
double motorPower = 0.5;
motor.setPower(motorPower);

Using RUN_USING_ENCODER

In this mode, the Control Hub will use the encoder to take an active role in managing the motor’s speed. Rather than directly applying a percentage of the available power, RUN_USING_ENCODER mode targets a specific velocity (speed). This allows the motor to account for friction, battery voltage, and other factors. You can still provide a power level in RUN_USING_ENCODER mode, but this is not recommended, as it will limit your target speed significantly.

Setting a velocity from RUN_WITHOUT_ENCODER mode will automatically switch the motor to RUN_USING_ENCODER mode. You should pick a velocity that the motor will be capable of reaching even with a full load and a low battery.

The velocity is set in Java by calling setVelocity() on a DcMotorEx object, as is shown in this snippet. You can skip the first line if you have already retrieved the motor object as a DcMotorEx from hardwareMap.

DcMotorEx motor = hardwareMap.get(DcMotorEx.class, "Motor");
motor.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
// This will turn the motor at 200 ticks per second
double motorVelocity = 200;
motor.setVelocity(motorVelocity);

Using RUN_TO_POSITION

In this mode, the Control Hub will target a specific position, rather than a specific velocity. You can still choose to set a velocity, but it is only used as the maximum velocity. The motor will continue to hold its position even after it has reached its target.

If the motor is unable to reach the determined position the motor will continue to run attempting to reach or maintain that position, which can lead to the motor stalling and overheating.

To use RUN_TO_POSITION mode, you need to do the following things in this order:

  1. Set a target position (measured in ticks)

  2. Switch to RUN_TO_POSITION mode

  3. Set the maximum velocity (if not determined by a gamepad input)

Remember it is recommended to always reset the encoder during initialization, however you will need to make sure your robot has been reset physically to the initialization position. For example, an arm may need to be brought back to the start up configuration like for the beginning of a FTC match.

The motor will continue to hold its position even after it has reached its target, unless you set the velocity or power to zero, or switch to a different motor mode.

package org.firstinspires.ftc.teamcode;
// import lines were omitted. OnBotJava will add them automatically.

@TeleOp
public class JavaRunToPositionExample extends LinearOpMode {
    DcMotorEx motor;
    
    @Override
    public void runOpMode() {
        motor = hardwareMap.get(DcMotorEx.class, "Motor");
        
        // Reset the encoder during initialization
        motor.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
 
        waitForStart();
        
        // Set the motor's target position to 300 ticks
        motor.setTargetPosition(300);
        
        // Switch to RUN_TO_POSITION mode
        motor.setMode(DcMotor.RunMode.RUN_TO_POSITION);
        
        // Start the motor moving by setting the max velocity to 200 ticks per second
        motor.setVelocity(200);
 
        // While the Op Mode is running, show the motor's status via telemetry
        while (opModeIsActive()) {
            telemetry.addData("velocity", motor.getVelocity());
            telemetry.addData("position", motor.getCurrentPosition());
            telemetry.addData("is at target", !motor.isBusy());
            telemetry.update();
        }
    }
}
Through Bore Encoder