Using SPARK MAX & NEO position control in LabVIEW


Our team is trying to use the REV Robotics Spark MAX controller with the NEO brushless motor. We want to use it in position control mode. I should point out we’ve tried using PID in previous seasons with no success. We’ve always given up and found another way (higher ratio gearboxes to reduce speed and limit switches to stop the motion)
We’ve looked at the code examples and can get the motor to run in velocity mode using an axis on a joystick. Now, we want the motor to run in position mode.
I should also mention we have the motor bolted to a 32:1 gearboox. To start, we want the robot to power-up and reset the internal encoder to zero (in Begin). Then in Teleop, we would like a button on the joystick to rotate the motor shaft 45 rotations.
We cannot find a method of setting the initial (power-up) position to zero. Also, our code causes the motor to rotate continuously; not 45 rotations (we’ve tried 3 rotations in testing too. Attached are screen shots of Begin and Teleop. (It should be noted we believe the majority of the PID code should be placed in Periodic Tasks, but putting it there did not work either)


This is a good start to be able to control position, and I would recommend using our new Smart Motion mode in our resent beta release. The Smart Motion uses the velocity control, and two additional parameters, to control position, and will work better than a direct position PID loop. The Beta release includes an example for using this mode. The steps are roughly:

  1. Get closed loop PID velocity control working
  2. Set a max acceleration and max velocity
  3. Run in Smart Motion mode which takes position as an input (i.e. tell it to drive for the number of rotations).

The beta release also has a method called ‘Set Position’ which can be used to reset the encoder position.


Will- I am also a mentor with team 3658. Jim has been pulling his hair out on this one. I’ve stepped-in to help too. After taking your advice, we have been able to get the motor to “behave” in a somewhat controlled manner when lowering our ramp (we found through calculations and throug testing that our ramp “Down” position is -10.7. In the graph, you’ll see the output to the motor is still chock-full of what I would call jitter. That jitter is twisting our mechanism back and forth more than just the affect gravity has on pulling the ramp down. I am attaching a photo of the graph we captured while lowering the ramp. I’m also attaching a screenshot of the code we’ve placed in Begin to configure the SparkMAX as well as our revised code to operate the motor. You will see where we have added code to move the ramp to the “UP” or Zero position too. We tried all sorts of P,I,D and Feedforward values to get the ramp moving “UP” in a controlled manner. I suspect we are running the motor at too low of an RPM to tune properly. Either that or there are values we need to change but do not have the experience (filtering, deadband, etc.!



Thank you for the advice! We were able to tune the motor to run well in closed-loop as a velocity control! We then switched to position mode and adjusted the values to get our ramp to work. We found that the motor only needs to rotate about 10 revolutions to lower / raise the ramp. We realize, we probably should have a several-hundred-to-one ratio gearbox; but this is what we had on the shelf to work with this year. Use of a higher ratio would definitely allow that motor to spin higher into the RPM band and would probably be much easier to tune; thus control.
Here are screenshots of the Begin and Periodic Tasks code MikeG is talking about.
If it is helpful, we shot a video of the ramp in action during the time the data was captured. Let me know if seeing that would be helpful.


For the velocity control our example and some values that we’ve used as a starting point are:

P Gain: 5e-5
F Gain: 0.000156

Based on the position graph it looks like its actually getting to a position and holding, so I think with some more tuning it will be possible to get it to that position smoothly as well.

An additional thing that may be helpful for tuning is to keep the controls from the example as controls. That way you can tune the values while the robot is running and get very quick feedback to how well the gains work.

A video may help, you can attach here or you can send it in an email to (also link this thread in the email).



Thank you for the quick feedback! The ramp holds its’ position so well in the down position because it is resting on the floor! :slight_smile: We tried adding some F in addition to P as well as with a bit of D but things always seemed to get out of control when we played with F.
We had been using the slider for tuning but the students really wanted to use the joystick buttons because it was easier to flip from 0 to -10.7 than clicking the slider. We did have the PIDF and velocity controls on the front panel while tuning. What you see in the example code posted in the screenshots was what we had placed in the competition robot code. We have removed the ramp mechanism, NEO and Spark from the robot prior to bagging. We will continue tuning; using those values you mentioned as a starting point. We will also work on tuning it to raising the ramp. We ran out of time to shoot video of the ramp raising, capturing graphical data, etc. We will capture data and shoot a video after attempting a bit more tuning. Thank you again. We’ll keep you posted on our progress!


Video that goes with the data captured yesterday 2/19/19. Note, our programmer presses the “Ramp Down” button about 5sec into this clip.:


Ok, so we have the Ramp Down working pretty well. I’ll attach a graph of the ramp down. We have messed with the ramp up for hours. I’m attaching the best we’ve come up with so far. The motion is still jerky and not smooth; but it isn’t quite as violent as it has been…


I still think the PID values for the velocity loop are too high. Have you tried the exact gains mentioned before?

I know I recommended the Smart Motion, but since this mechanism only has two states and does not need exact control to deploy (since you can just use the floor) it may be easier to simplify it. If you need to also be able to retract you can use the Position PID. (Again the gains will be different, take a look at the LabVIEW Position PID example for a good starting point).

I would still recommend plotting all of the same signals as above if you do change the control mode.


We used the exact gains listed in, but the mechanism would never lift. It just shuddered violently. We’ve tried dozens and dozens of settings. I left p at 5e-5 and increased F until it finally lifted. Even with small numbers for velocity and acceleration, it was never very pretty. You mentioned lowering the velocity/acceleration before. We have. What kinds of numbers do you think we need for velocity and acceleration? I tried 50/50, 50/100, 10/10, 50/75, 100/125, 125/125. I feel like we’ve been all over the map with it. We will go back to position mode as you recommend. Is the behavior caused by our setpoint going instantly from -10.7 to 0? Should we implement some kind of function to provide a linear ramp? I know LabVIEW has linear functions, but we’ve never used one. We’re praying for a breakthrough this week! Our competition is on Friday. What we have works but it is still pretty violent and we aren’t sure it will hold-up. Thanks for your advice up to this point. It is definitely appreciated!


This may sound like a step back, but have you tried controlling this motor manually using a joystick? The reason I ask is if it is not controllable that way then it is likely also not able to be controlled closed loop.

If it is controllable, how accurate does it need to be? Maybe a much much simpler controller will work here (e.g. add a simple ramp, then just drive until it is near the place you want, then stop)