Using the PWM Output with Spark Max

The Canandmag easily integrates with the REV Spark Max motor controller, offering closed loop control feedback. The Canandmag’s PWM output can be read by the Spark Max without the need of any intermediate adapter boards.


When using the Helium Canandmag over PWM with a Spark Max, ReduxLib and Alchemist will not be able to configure the device. Use the REV Hardware Client to configure the device via the Spark Max instead!


The Canandmag, by default, ships in Spark MAX compatibility mode. As a result, the 10 pin IDC connector may be directly connected to the Spark MAX data port using the included IDC cable. This will transmit both power and signal with no need for soldering.

If the encoder has had its Spark MAX trace cut (for example, to configure the device in Using the PWM Output with Talon SRX mode), you may bridge the MAX solderpad to re-enable Spark MAX compatibility mode. Make sure not to bridge both the Spark MAX and Talon SRX pads at the same time, as this could damage your motor controller.


The Canandmag acts as a PWM absolute encoder. It can be configured in the Absolute Encoder tab of the REV Hardware Client.

As the output of the Canandmag is similar to that of a REV Through Bore, it may be used in areas where the REV encoder is used (for example, when used in a swerve module, it can be configured and used with similar code to a MaxSwerve module).

Pressing the zero button on the Canandmag will set the currently read position as the new zero point. This can be used to quickly rezero a mechanism such as a swerve module without the use of a computer. If the encoder is connected over CAN, manipulating the absolute position via setAbsPosition() or inverting the direction through either the ReduxLib API or Alchemist will also change the PWM output accordingly, overriding the offset saved by the button press.

Code Example - Java

// Instantiate a Spark MAX and get a handle to a PWM absolute encoder
CANSparkMax sparkmax = new CANSparkMax(0, MotorType.kBrushed);
var sparkencoder = sparkmax.getAbsoluteEncoder(SparkMaxAbsoluteEncoder.Type.kDutyCycle);

// Change this as needed, 8 points to average for velocity measurement is a
// decent starting point

// Reads the PWM Canandmag position in rotations

// configure the Spark Max to use the PWM-connected Canandmag for
// closed-loop control

// Additionally, SparkMaxPIDController.setPositionPIDWrappingEnabled() and
// similar functions may be useful for swerve pivot applications.

// By default, the Spark Max only transmits position and velocity data
// for duty cycle encoders every 200 ms (5 Hz).
// To increase frequency (e.g. to 20 ms/50 Hz) adjust periodic frames 5 and 6:

// increase position update frequency to once every 20 ms
sparkmax.setPeriodicFrameRate(PeriodicFrame.kStatus5, 20);

// increase velocity update frequency to once every 20 ms
sparkmax.setPeriodicFrameRate(PeriodicFrame.kStatus6, 20);

Refer to REV’s documentation for more information on using absolute encoders with the Spark Max. The Java API reference for SparkMaxAbsoluteEncoder and SparkMaxPIDController may also be helpful.