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.

The CIM motor is a classic FRC workhorse — a brushed DC motor that has powered countless drivetrains over the years. When connected to a SPARK MAX motor controller operating in PWM mode (jumper installed), you can control it using WPILib’s built-in PWMSparkMax class. No vendor library installation is required. This makes the CIM with PWMSparkMax the simplest motor setup in FRC and an ideal starting point for students new to robot programming.

Hardware Requirements

Before writing code, make sure your hardware is configured correctly:
  • CIM motor wired to the SPARK MAX motor output leads
  • SPARK MAX motor controller with the PWM jumper installed (this enables PWM mode — without the jumper, SPARK MAX expects CAN communication)
  • PWM cable connected from the SPARK MAX signal port to a PWM header on the roboRIO
No additional vendor library is needed — PWMSparkMax is included with every WPILib installation.

Required Imports

Add this single import at the top of your Robot.java file:
import edu.wpi.first.wpilibj.motorcontrol.PWMSparkMax;
PWMSparkMax is part of WPILib — no additional vendor library installation is required. If you can see edu.wpi.first.wpilibj in your project, you already have everything you need.

Defining a CIM Motor

Declare and instantiate a PWMSparkMax object inline as a private final field inside your Robot class. The constructor takes one argument: the PWM port number on the roboRIO.
  • PWM port 0 is the default used in all FRC Academy lessons. PWM ports are numbered 0 through 9 on the roboRIO.
private final PWMSparkMax m_motor = new PWMSparkMax(0);

Inverting a Motor

PWMSparkMax implements WPILib’s MotorController interface, which includes the setInverted() method. You can call it directly — no configuration object needed:
m_rightMotor.setInverted(true);
Call this inside robotInit() for any motor that needs to spin in the opposite direction. In a standard tank drivetrain, inverting the right motor ensures both sides push the robot forward when given the same positive speed value.

Setting Motor Speed

Use the .set(double speed) method to command motor output. The value must be between -1.0 and 1.0:
  • 1.0 = full speed forward
  • 0.0 = stop
  • -1.0 = full speed reverse
m_motor.set(0.5);   // 50% forward
m_motor.set(0.0);   // stop
m_motor.set(-0.5);  // 50% reverse
PWMSparkMax is a great starting motor for beginners because it uses WPILib’s built-in MotorController interface with no extra setup. The .set(), .setInverted(), and .stopMotor() methods work identically across all WPILib motor controller classes.

PWM vs CAN

Understanding the difference between PWM and CAN mode will help you choose the right approach for your robot:
FeaturePWM ModeCAN Mode
WiringSimple — one PWM cable to roboRIORequires CAN bus wiring
Vendor libraryNot required (WPILib built-in)Required (REV or CTRE)
TelemetryNoneFull — current, temperature, velocity
Current limitingNot availableConfigurable in code
Encoder accessNot availableFull encoder feedback
Best forBeginners, simple mechanismsDrivetrains, advanced control
For learning the basics of robot programming, CIM / PWMSparkMax is the easiest starting point — you get a working motor with zero vendor library setup. Once you’re comfortable, consider upgrading to CAN-based motors (NEO or Kraken) to unlock the full feature set.

Available Lessons

FRC Academy includes four hands-on coding lessons for the CIM motor with PWMSparkMax. Each lesson builds on the previous one, from a single motor declaration to a full four-motor arcade drivetrain.

1. Define a Motor

Declare and instantiate a PWMSparkMax object on PWM port 0.

2. Activate a Single Motor

Bind .set(0.5) to the operator controller’s B button using whileTrue and onFalse command bindings.

3. 2 Motor Tank Drive

Declare left (port 0) and right (port 1) motors, invert the right side with setInverted(true), and implement arcade drive in teleopPeriodic().

4. 4 Motor Tank Drive

Extend to four motors using .addFollower(), configure right-side inversion, and drive with a DifferentialDrive object calling arcadeDrive().

Build docs developers (and LLMs) love