Setting Mechanism Position with Button

Hey guys, I’ve got a question about triggering some PID loops.

So I built a small VI with a PID control in it that reads the value of a potentiometer and attempts to change it by actuating a motor (the reference voltages for various positions are inputted). I want to trigger moving to a different position using a button.

My plan is to put the VI in periodic tasks inside a case structure, and control it using a boolean that is tied to a joystick button. But I don’t want to hold it down continuously while the loop executes. How could I program it to execute on the button press and continue executing (as true, so the code stays active in the loop) until it achieves the desired position (or a position very close to it; when it’s in range). I want it to run until its close and then stop.


I’m thinking about trying to put it together as a button start of a timed action, similar to the Team 358 example shown here. Maybe have the PID loop execute for 3 sec?

Any thoughts on that?

Can you provide more details on the mechanism that you are trying to control? Is it a requirement that the PID loop runs then quits?

An arm on a motor for example should probably keep the PID loop running. Position control on a drive train probably shouldn’t, or if you must change to ‘manual’ (open loop) control.

In the case you describe, how do you decide when your PID loop is ‘done’. Is a timer like in FRC358’s example sufficient?

You need 2 functions.

Function 1: Looks at the Button, and sets a Variable when it is pressed. Make sure you “debounce” the button (all presses within n milliseconds is considered the same press).

Function 2: Looks at the Variable, and does whatever (move to different position) when it sees the variable set. When it is done, it resets the variable.

It’s an arm moving from an angle of about 15 degrees to about 75 degrees. I suspect a timed termination would be mostly sufficient, unless there was a mechanical conflict that prevented the actuation happening in the normal amount of time. However, I’d prefer it to terminate when it has confirmation that it’s achieved the specified position, or something very near that, like with a deadband on a joystick control.

I know I could just leave the loops running constantly, and switch between them to get to different positions. The PID would 0 out, and presumably no movement would occur. But I just figured it’d be better to terminate after. The arm is worm gear, so it will not backdrive (so far it hasn’t), so I just don’t see a reason to keep it running.

Do I face any issues leaving it running? If not, I could have each loop in a separate case of a single case structure within periodic tasks, and switch between the cases to go to various positions, avoiding termination entirely.

Instead of switching between multiple loops in different cases, what I am suggesting is having a single loop with the PID controller in it.

You could implement this with a simple global variable as your set point. When you press the button to change the arm angle, just write your desired position to the global variable.

So in periodic tasks you have a single loop for the PID controller. The loop constantly reads from the global variable which is set to the target arm position. When the arm is near the target the PID output will be close to 0. This is also where you can implement a deadband to force the output to 0.

Now in auton/teleop all you need to do to set the arm angle is write to the global variable.

That sounds like a good plan! Thanks!

I think I know how to implement nearly all of that. I’ll post back if I have questions or run into issues.

Thank you,