REV Spark Max sending error 4 & 5

our team has been experiencing an issue with implementing the spark max code, the code will compile but sends error 4 & 5 to the Roborio. The code however will enable but will also send the error message error 4. Here’s our code

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package frc.robot;

import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.CommandScheduler;

//import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;

import com.revrobotics.RelativeEncoder;
import com.revrobotics.SparkMaxAlternateEncoder;
import com.revrobotics.SparkMaxPIDController;
import com.revrobotics.CANSparkMax;
import com.revrobotics.CANSparkMaxLowLevel.MotorType;


  • The VM is configured to automatically run this class, and to call the functions corresponding to
  • each mode, as described in the TimedRobot documentation. If you change the name of this class or
  • the package after creating this project, you must also update the build.gradle file in the
  • project.
    public class Robot extends TimedRobot {
    private Command m_autonomousCommand;

private RobotContainer m_robotContainer;

  • Change these parameters to match your setup
    static final int kCanID = 2;
    private static final MotorType kMotorType = MotorType.kBrushless;
    private static final SparkMaxAlternateEncoder.Type kAltEncType = SparkMaxAlternateEncoder.Type.kQuadrature;
    private static final int kCPR = 8192;

private CANSparkMax m_motor;
private SparkMaxPIDController m_pidController;
public double kP, kI, kD, kIz, kFF, kMaxOutput, kMinOutput;


  • An alternate encoder object is constructed using the GetAlternateEncoder()
  • method on an existing CANSparkMax object. If using a REV Through Bore
  • Encoder, the type should be set to quadrature and the counts per
  • revolution set to 8192
    private RelativeEncoder m_alternateEncoder;


  • This function is run when the robot is first started up and should be used for any
  • initialization code.
    public void robotInit() {
    // Instantiate our RobotContainer. This will perform all our button bindings, and put our
    // autonomous chooser on the dashboard.
// initialize SPARK MAX with CAN ID
m_motor = new CANSparkMax(kCanID, kMotorType);

m_alternateEncoder = m_motor.getAlternateEncoder(kAltEncType, kCPR);

 * In order to use PID functionality for a controller, a SparkMaxPIDController object
 * is constructed by calling the getPIDController() method on an existing
 * CANSparkMax object
m_pidController = m_motor.getPIDController();

 * By default, the PID controller will use the Hall sensor from a NEO for its
 * feedback device. Instead, we can set the feedback device to the alternate
 * encoder object

 * From here on out, code looks exactly like running PID control with the 
 * built-in NEO encoder, but feedback will come from the alternate encoder

// PID coefficients
kP = 0.1; 
kI = 1e-4;
kD = 1; 
kIz = 0; 
kFF = 0; 
kMaxOutput = 1; 
kMinOutput = -1;

// set PID coefficients
m_pidController.setOutputRange(kMinOutput, kMaxOutput);

// display PID coefficients on SmartDashboard
SmartDashboard.putNumber("P Gain", kP);
SmartDashboard.putNumber("I Gain", kI);
SmartDashboard.putNumber("D Gain", kD);
SmartDashboard.putNumber("I Zone", kIz);
SmartDashboard.putNumber("Feed Forward", kFF);
SmartDashboard.putNumber("Max Output", kMaxOutput);
SmartDashboard.putNumber("Min Output", kMinOutput);
SmartDashboard.putNumber("Set Rotations", 0);

m_robotContainer = new RobotContainer();



  • This function is called every 20 ms, no matter the mode. Use this for items like diagnostics
  • that you want ran during disabled, autonomous, teleoperated and test.
  • This runs after the mode specific periodic functions, but before LiveWindow and

  • SmartDashboard integrated updating.
    public void robotPeriodic() {
    // Runs the Scheduler. This is responsible for polling buttons, adding newly-scheduled
    // commands, running already-scheduled commands, removing finished or interrupted commands,
    // and running subsystem periodic() methods. This must be called from the robot’s periodic
    // block in order for anything in the Command-based framework to work.


/** This function is called once each time the robot enters Disabled mode. */
public void disabledInit() {}

public void disabledPeriodic() {}

/** This autonomous runs the autonomous command selected by your {@link RobotContainer} class. */
public void autonomousInit() {
m_autonomousCommand = m_robotContainer.getAutonomousCommand();

// schedule the autonomous command (example)
if (m_autonomousCommand != null) {


/** This function is called periodically during autonomous. */
public void autonomousPeriodic() {}

public void teleopInit() {
// This makes sure that the autonomous stops running when
// teleop starts running. If you want the autonomous to
// continue until interrupted by another command, remove
// this line or comment it out.
if (m_autonomousCommand != null) {

/** This function is called periodically during operator control. */
public void teleopPeriodic() {
// read PID coefficients from SmartDashboard
double p = SmartDashboard.getNumber(“P Gain”, 0);
double i = SmartDashboard.getNumber(“I Gain”, 0);
double d = SmartDashboard.getNumber(“D Gain”, 0);
double iz = SmartDashboard.getNumber(“I Zone”, 0);
double ff = SmartDashboard.getNumber(“Feed Forward”, 0);
double max = SmartDashboard.getNumber(“Max Output”, 0);
double min = SmartDashboard.getNumber(“Min Output”, 0);
double rotations = SmartDashboard.getNumber(“Set Rotations”, 0);

    // if PID coefficients on SmartDashboard have changed, write new values to controller
    if((p != kP)) { m_pidController.setP(p); kP = p; }
    if((i != kI)) { m_pidController.setI(i); kI = i; }
    if((d != kD)) { m_pidController.setD(d); kD = d; }
    if((iz != kIz)) { m_pidController.setIZone(iz); kIz = iz; }
    if((ff != kFF)) { m_pidController.setFF(ff); kFF = ff; }
    if((max != kMaxOutput) || (min != kMinOutput)) { 
      m_pidController.setOutputRange(min, max); 
      kMinOutput = min; kMaxOutput = max; 

     * PIDController objects are commanded to a set point using the 
     * SetReference() method.
     * The first parameter is the value of the set point, whose units vary
     * depending on the control type set in the second parameter.
     * The second parameter is the control type can be set to one of four 
     * parameters:
     *  com.revrobotics.CANSparkMax.ControlType.kDutyCycle
     *  com.revrobotics.CANSparkMax.ControlType.kPosition
     *  com.revrobotics.CANSparkMax.ControlType.kVelocity
     *  com.revrobotics.CANSparkMax.ControlType.kVoltage
    m_pidController.setReference(rotations, CANSparkMax.ControlType.kPosition);
    SmartDashboard.putNumber("SetPoint", rotations);
    SmartDashboard.putNumber("ProcessVariable", m_alternateEncoder.getPosition());

public void testInit() {
// Cancels all running commands at the start of test mode.

/** This function is called periodically during test mode. */
public void testPeriodic() {}

/** This function is called once when the robot is first started up. */
public void simulationInit() {}

/** This function is called periodically whilst in simulation. */
public void simulationPeriodic() {}

Any help would be appreciated

FWIW, while something like a GitHub link to your code is best, you can get much better formatting by putting a line with just “```java” before your code, and a line with just “```” after it. These have three of the “backtick” characters (on the same key with “~” on most US keyboards).

I’m not sure exactly what you mean by these errors – a screenshot, cut-and-paste, or even a picture could be helpful. Also, was is the robot doing (or not doing) that you want it to do?

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.