SparkMax Example Code Help

So I am looking to use the setVoltage API calls to drive a 6 motor, tank drive, drivetrain.

I am aware of the setReference kCurrent API call and was wondering do I need to set both voltage and current individually to get the robot to move, or do I need just the setVoltage and the current will be auto-calculated based upon if the setVoltage is reached? Or how might I get this to work?

My goal is to take an input joystick Y val, and I can only assume to scale it between -12 and 12 using a math function, then set the voltage that way. I want constant speed and everything a PID could provide without it being a closed system. If someone can tell me if I need to do some math to also calculate the necessary current for such a system, give me the heads up.

Thank you!

Using setVoltage is enough to get your robot to move.

There is no “current calculation” that takes place on the roboRIO or the motor controller. The current that the motor draws is dependent on the voltage across the motor windings (which is determined by the parameter to your setVoltage call) and the speed of the motor.

For example, when 12V is applied to a NEO motor and the motor has zero velocity, it will draw 105A (the stall current). As the motor speeds up, the amount of current that the motor draws will decrease until the velocity remains constant. When this happens (also known as steady-state), the motor will draw 1.8A (free current).

You need a closed-loop system to accurately get your system to get to a desired velocity setpoint. You can run system identification and reasonably estimate the voltage input to the motor to achieve a certain velocity, but in the presence of external disturbances, you need a closed-loop controller like PID.

Once again, current is not an input that you can directly provide to a motor. The only input you can provide is voltage.


In the API it directly calls Set and does a sort of voltage calculation.

void SpeedController::SetVoltage(units::volt_t output) {

  Set(output / units::volt_t(RobotController::GetInputVoltage()));


I just wanted to know if this was adequate enough to get as close to the results I desire without a Closed Loop…

And will this work with negative voltages, ie going backwards…

In your original post, you stated that you wanted “constant speed”. You cannot achieve good speed (i.e. velocities in m/s) control without a closed loop system.

If all you want is for your robot to drive based on your scaled joystick inputs (from -12 to 12), this will work. In fact, this type of open-loop control is preferred by a lot of teams for regular teleop driving.

What it’s doing here is it’s calculating the percent voltage to apply. The battery has RobotController::GetInputVoltage() volts and Set() takes in a percent. So if, say the battery has 10V and you want 5V, you want to command 50% of the available voltage, which is 5/10. So it just guarantees you can set the voltage you want

Note that this is if you are calling Set() without using the SPARK MAX API. Our API overwrites this function and the voltage calculation is done directly on the controller. It is the same calculation, just faster.