Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Holden9607/FRC-Academy/llms.txt

Use this file to discover all available pages before exploring further.

Building on the motor definition from Lesson 1, this lesson wires your motor to an Xbox controller button so it runs while the button is held and automatically stops the moment it is released. This pattern is foundational in FRC robot programming — almost every operator-controlled mechanism uses the same whileTrue / onFalse binding structure.

What You’ll Learn

  • How to create a CommandXboxController and which port number the operator controller uses
  • How to retrieve a Trigger from a specific button (button B in this lesson)
  • The difference between .whileTrue() and .onFalse() and why you need both
  • How to write an inline RunCommand lambda to set motor speed on the fly
  • The motor speed range: -1.0 (full reverse) → 0.0 (stopped) → 1.0 (full forward)

Solutions by Motor Type

The motor runs at 50% forward while B is held and stops when B is released. Button binding lives inside robotInit().
import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj2.command.CommandXboxController;
import edu.wpi.first.wpilibj2.command.RunCommand;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkLowLevel.MotorType;

public class Robot extends TimedRobot {
    private final SparkMax m_motor = new SparkMax(1, MotorType.kBrushless);
    private final CommandXboxController driverController = new CommandXboxController(0);
    private final CommandXboxController operatorController = new CommandXboxController(1);

    @Override
    public void robotInit() {
        operatorController.b()
            .whileTrue(new RunCommand(() -> {
                m_motor.set(0.5);
            }))
            .onFalse(new InstantCommand(() -> {
                m_motor.set(0.0);
            }));
    }
}

Key Concepts

operatorController.b() Calling .b() on a CommandXboxController returns a Trigger object that is active (true) whenever the B button is physically pressed. You chain .whileTrue() and .onFalse() directly onto this trigger. .whileTrue(command) Schedules the given command every scheduler cycle while the trigger condition is true (i.e., while the button stays held). When the button is released the command is interrupted. .onFalse(command) Schedules the given command on the falling edge — the instant the trigger transitions from true to false (button released). Using InstantCommand here ensures the motor is commanded to stop exactly once rather than continuously. new RunCommand(() -> { m_motor.set(0.5); }) RunCommand is a lightweight WPILib command that runs a single lambda (anonymous function) repeatedly while active. The lambda sets the motor output to 50% forward every scheduler tick. new InstantCommand(() -> { m_motor.set(0.0); }) InstantCommand runs its lambda exactly once and immediately finishes. It is the right choice for .onFalse() because stopping a motor is a one-time action, not a continuous one. Speed range Motor set() accepts a double from -1.0 to 1.0:
ValueBehavior
1.0Full speed forward
0.550% speed forward
0.0Stopped
-0.550% speed reverse
-1.0Full speed reverse

In FRC Academy

To reach this lesson in the app:
1

Open the Main Menu

Launch FRC Academy and click Motors from the main menu.
2

Select a motor type

Choose NEO, Kraken, or CIM.
3

Open Lesson 2

Select 2. Activate a Single Motor from the lesson list.
4

Choose a mode

Pick Guided Mode or Unguided Mode and start writing.
The operator controller is always port 1 in FRC Academy motor lessons. The driver controller is port 0 and is used in the drivetrain lessons (Tank Drive). Make sure you pass the correct port when constructing each CommandXboxController.

← Define a Motor

Lesson 1 — Declare the motor hardware object with the correct import and constructor arguments.

2-Motor Tank Drive →

Lesson 3 — Control two motors with joystick axes to drive a differential drivetrain.

Build docs developers (and LLMs) love