Unit 4

Moving a Motor with motor.set()

This is the moment code becomes a robot. You'll create a motor in software and spin it at a speed you choose. It is the single most important method you will use all season.

25 min Beginner Needs: Java basics, Project Anatomy

Your goal

Create a SparkMax motor object, spin it with motor.set(), and explain what “percent output” means, including how to do it without frying the motor.

1 Why this matters

Whole robots have been driven with nothing but this one method. The cardboard “kitbot” that many rookies build? Programmed entirely with motor.set(). Once you can spin a motor on command, you can run an intake, a feeder, a shooter wheel, or a climber. Any mechanism whose job is to turn on until something happens.

The two-day voltage bug

The team once set a motor's power far too high. The motor “spazzed out” and quit running. They spent two full days hunting for a code bug before realizing the value was simply too large. The rule that came out of it: start low, raise slowly. And when something will not move, run the motor from the REV Hardware Client to test it directly. That instantly tells you whether the problem is your code, the wiring, or the build.

2 The signal path

Before code, picture where your command actually goes. When you call motor.set(0.7), the instruction travels a physical path through the robot:

RoboRIOCAN busSparkMaxNeo motorspin (your (twisted (motor (the (the code) pair wire) controller) actual mechanism addressed spinning moves) by CAN ID) part)

The SparkMax is a motor controller. It takes your software command and delivers the right power to the Neo motor plugged into it. Every controller on the CAN bus has a unique CAN ID you set in the REV Hardware Client, so your code can say “motor number 2, specifically.”

Where do CAN IDs start?

By the team's convention, ID 0 is the RoboRIO/system and ID 1 is the PDH, so motor IDs usually start at 2. Treat this as a practical convention and always confirm the reserved IDs for your own setup.

3 Creating a motor object

Remember from Phase 1 that creating an object means instantiating a class. A motor is no different. A SparkMax object needs two things: the CAN ID you assigned it, and the motor type, which is brushless for a Neo.

Verified syntax · REVLib 2025
IntakeSubsystem.javaJava
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkLowLevel.MotorType;

// id = the CAN ID you set in the REV Hardware Client
// kBrushless = a Neo (brushless) motor
SparkMax motor1 = new SparkMax(2, MotorType.kBrushless);

Heads up: in the onboarding video the narrator wrote new SparkMax(ID, brushless). The real motor type is MotorType.kBrushless. Older code may use the class CANSparkMax instead of SparkMax, which is the previous REVLib naming.

Verify for current season

WPILib and vendor libraries change every year. SparkMax and CANSparkMax, import paths, and class names can shift between REVLib versions. Always confirm against the current season's REV docs and the version your project's vendordeps pull in.

4 motor.set() and percent output

Now the star of the show. motor.set(x) takes a percent output from -1.0 to 1.0:

  • 1.0 = 100% power in one direction
  • -1.0 = 100% power in the other direction
  • 0.0 = stop

Which physical direction counts as positive? You will not know until you test, so run it slowly first and watch which way the mechanism moves.

IntakeSubsystem.javaJava
motor1.set(0.7);    // run at 70% power, one direction
motor1.set(0.0);    // stop
motor1.set(-0.5);   // run at 50% power, the other direction
percent output
A fraction of full power from -1.0 to 1.0. It is not a speed in RPM. It is how hard to push.
SparkMax
The REV motor controller. You create one object per controller, addressed by its CAN ID.
brushless / kBrushless
The motor type for a Neo. You pass MotorType.kBrushless when constructing the SparkMax.
CAN ID
The unique address of a device on the CAN bus, set in the REV Hardware Client, so code can target one motor.

5 Staying under 80%

The fried motor

Pushing a motor at about 90% power once fried it so badly it wouldn't run for more than ~5 seconds. The team's rule of thumb ever since:

Keep output under about 80%. If you need more, add another motor rather than pushing one harder.

So set(0.7) is a healthy go value for many mechanisms. set(0.95) is asking for smoke. When a mechanism needs more force, teams add a second motor rather than redline one.

6 Practice challenges

This is robot code and it needs a real robot and WPILib to run, so these challenges test your understanding instead of a live compiler.

Predict the behaviorWhat does this do?

A roller motor is at rest. You call:

motor1.set(-0.5);

In a few words, how fast and which way does it run? Think about the percent and the sign.

Fill in the blanksBuild & run an intake motor

Create a brushless motor on CAN ID 2 and run it at a safe 70%.

SparkMax intake = new SparkMax(, MotorType.);
intake.set();
Hint

The first argument is the CAN ID, a whole number. The motor type for a Neo is kBrushless. A safe percent output is 0.7, which stays under 0.8.

Multiple choiceStop the motor

Which call stops the motor?

7 Common mistakes

Watch out for these
  • Wrong CAN ID. If the ID in your code doesn't match the one set in the REV client, the motor does nothing and the console may print CAN ID 16 timed out. Check the ID first.
  • Going too hard. Values above ~0.8 risk overheating or frying a motor. Start low, raise slowly.
  • Assuming a direction. Positive is not always forward. Test at low power and watch before trusting the sign.
  • Out of range values. set(2.0) does not give double power. The valid range is only -1.0 to 1.0.
  • Wrong class or import. Mixing up SparkMax and the older CANSparkMax, or forgetting MotorType.kBrushless, will not compile.
Build it · real mechanism

Program the Intake

An intake is a motor driving a pulley that spins roller wheels. set(0.7) pulls a game piece in and set(0) stops it. Fill in the class below so it controls a real intake.

Intake.java · your turn
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkLowLevel.MotorType;

public class Intake {
    // 1) create the motor on CAN ID 2, brushless
    private final SparkMax roller = /* TODO */;

    // 2) pull a game piece IN at a safe 70%
    public void intake() {
        // TODO
    }

    // 3) stop the roller
    public void stop() {
        // TODO
    }
}
  1. Create the motor with new SparkMax(2, MotorType.kBrushless).
  2. intake() should call roller.set(0.7).
  3. stop() should call roller.set(0).
  4. Bonus. Add an outtake() method that spits the piece back out at -0.5.
Reveal the solution
Intake.java · solution
import com.revrobotics.spark.SparkMax;
import com.revrobotics.spark.SparkLowLevel.MotorType;

public class Intake {
    private final SparkMax roller = new SparkMax(2, MotorType.kBrushless);

    public void intake() {
        roller.set(0.7);   // pull the game piece in
    }

    public void stop() {
        roller.set(0);     // stop the roller
    }

    // Bonus: reverse to spit the piece out
    public void outtake() {
        roller.set(-0.5);
    }
}

That is your first real mechanism controller. In Unit 7 you turn it into a proper Subsystem, and in Unit 8 you bind intake() to a controller button.

Checkpoint

0 / 4
Q1. What does the argument to motor.set() represent?
Q2. Two values needed to construct a SparkMax are…
Q3. Roughly what's the team's safe upper limit for percent output?
Q4. The console prints CAN ID 16 timed out. Most likely cause?
You made a robot move (in code).Next up: reading sensors, so the robot knows what its mechanisms are doing.