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.
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 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:
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.”
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.
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.
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 direction0.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.
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
-1.0 to 1.0. It is not a speed in RPM. It is how hard to push.MotorType.kBrushless when constructing the SparkMax.5 Staying under 80%
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.
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.
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.
Which call stops the motor?
7 Common mistakes
- 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.0to1.0. - Wrong class or import. Mixing up
SparkMaxand the olderCANSparkMax, or forgettingMotorType.kBrushless, will not compile.
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.
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
}
}
- Create the motor with
new SparkMax(2, MotorType.kBrushless). - intake() should call
roller.set(0.7). - stop() should call
roller.set(0). - Bonus. Add an
outtake()method that spits the piece back out at-0.5.
Reveal the 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 / 4motor.set() represent?SparkMax are…CAN ID 16 timed out. Most likely cause?