SparkMax API: Set Current / Set Voltage Calls

Just a question regarding Rev Robotics SparkMax Controllers.

There’s API for CTRE TalonSRX’s and VictorSPX’s on setting Current and Voltages directly to the controllers instead of the default output of percent value [-1…1]. I was just looking through the SparkMax API and I can’t seem to find this same feature anywhere in there. I am aware setting voltages and currents directly to brush-less DC motors is not as straightforward as it may seem, yet I cant help to wonder that at least there should be some sort of feature like this. Otherwise, all i can discover is if i want it to go 10 amps directly to the motor, before every Set call I set the current limiting feature, then set the output all the way to 1 or -1 depending if forwards or backwards… This seems like a lousy solution but if it turns out i’m just missing the C++ API calls, I would appreciate some help finding them.

First thing, constantly setting current limiting in your main loop is a bad idea, it definitely causes stuttering I think it’s because it has to stop receiving instructions from the roborio when it’s setting new configs, although that’s just a guess. Those calls are supposed to be infrequent.

They have the setVoltage method of the speed controller interface, all it does is divide by the battery voltage to compensate, then sets a [-1,1] value.

You may be talking about voltage compensation which is also available.

As for setting the current, I think it is done with the CANPIDController. You do controller.setRefrence(ControlType.kCurrent, value).

Here are all the control types, you’ll notice there is also voltage there, never really tried that or the current. I would assume the it sets voltage directly without dividing by battery voltage first. Sadly there is very little documentation on what the different control types do exactly.

1 Like

So setReference can be used as a periodic function in lieu of the set function that is just between [-1…1]?
If so thank you very much. Though you did link Java API references, I think I was able to find the same reference for C++ here.

Idk about C++, but in java CANSparkMax.set(double p) calls CANPIDController.setReference(kDutyCycle, p), so it makes no difference which one you call ( if you are setting duty cycle value).

Thank you. But the goal is to set 12 volts constant and then instead of sending in a value from -1…1 send in amps between -30 and 30 or whatever I might desire as my MIN and MAX amps. Controlling the amperage means no matter the battery voltage the motors will spin at the exact same speed every time its run (or at least closet than a dudyCycle value of .5 that varies in amps over the battery’s active time.

This is not true.

What you are probably looking for is voltage compensation, where the [-1, 1] is a fraction of a set voltage value instead of a fraction of the battery voltage.

At steady-state, voltage is directly proportional to the speed output of a motor. Current (in amps) is directly proportional to the torque output of the motor.

The best way to ensure that your motor reaches the same velocity setpoint each time is to use closed-loop control on velocity, which is a feature that is available on the Spark MAX.


To expand on this a little bit, voltage is always open loop meaning that you can set the voltage directly, and our API gives you the ability to do this. Both setReference(ControlType.kVoltage, 12) and setVoltage(12) are the same with our API.

The WPILib default implementation of setVoltage measures the battery voltage and divides to give a duty cycle, but the overridden version in our API sets the voltage directly (technically the same way, but at the same rate as the controller switching frequency).

In contrast, current control is always closed loop just like velocity and position. In most cases you want velocity or position control.