Notice: This website has undergone a refactor to allow for more pages in the future.
Specifically, the limit-switch, gyro, and potentiometer pages were moved under the Sensors header and then dashboard or roboRIO based on where the edited code would run.
The old locations were set with permanent redirects, but please update bookmarks/favorites.

FRC LabVIEW Tutorials - Potentiometer

Table of Contents


Over the years, several of the mentors and students involved in writing the content of this website have found themselves designing a manipulator and trying to decide between an encoder and a potentiometer for the feedback in the system.

Several reasons that have been considered for the encoder are:

Several reasons that have been considered for the potentiometer are:

The purpose of this tutorial is to show how to have the software on the robot allow for a potentiometer to account for this.

Because potentiometers "know" where they are at startup, it doesn't matter where the actuator is, the set points (min, max, and others) are still correct.


First, we must setup a potentiometer.

Soldering the potentiometer

We attached a knob to our potentiometer for testing purposes, but it would likely be attached to a motor or gear shaft in mechanics of the manipulator to be controlled.

Soldering the potentiometer

We also need to open the potentiometer in

Soldering the potentiometer

Basic Read

We start by putting the logic in to decide what the target setpoint of a PID is and reading the potentiometer for the process variable.

Soldering the potentiometer

We can improve this by moving the potentiometer code into a sub-vi.

create sub-VI

We will use a while loop to remember whether or not the values have been initialized

add a while loop

Add a case structure to the loop and a shift register

add a shift register to it

Wire from the inside of the selector terminal to the right shift register (in the True case)

wire the selector to the shift register

Create a True constant in the False case and connect it to the tunnel. This will cause the input of the shift register to default to False, but to remember the True after that. We can use this to decide when to initialize the values.

We now want to move the GetDevRef VI into the false case.

move the get devRef

We now need to wire the DevRef to the while loop.

Connect it to the While Loop

And create a shift register for it.

Replace the tunnel with a Shift Register

Move the Potentiometer Get VI after the case structure the True case and connect it's DevRef terminals to the shift registers and the output to the indicator.

Connect the get to the shift registers

Create a constant on the while loop's control terminal and set it to True (to make it run only once).

Create a constant on the control terminal

On the output wire, insert a subtract node.

Insert Subtract node

And create a constant. This can be used as the expected offset - so that when the manipulator is in a known state (i.e. against a hard stop) the VI can read 0 (if the known state is with the arm at the top of the potentiometer range, make it an add so that the sensor reads 1 at that point). If the potentiometer is adjusted, only this constant needs to be changed to keep all the set points the same.

Create constant for offset.

Reading offset from a file on load

To move the offset value to being stored in a file (this will enable use to later update it programmatically, but have it remembered across reboots), open a PuTTY session and enter a host name of RoboRIO-XXYY-FRC.local -- where XXYY is your team number, as configured on the RoboRIO -- (if using ethernet, you could also enter the RoboRIO's IP address. Tools like Advanced IP Scanner can help you find this if you don't know it.)

Open PuTTY

PuTTY will prompt you for a username and password. This is the same as you use on the web interface (default to admin, blank).

Enter username (admin)

Nothing will be displayed (echoed) as you enter the password. To enter a blank password (the default), just press enter.

Enter password (hit enter for blank)

If login is successful, a prompt will be displayed (most likely admin@{the host name you used}:~#). The first two values tell us what machine we are logged into (logged in as admin on roboRIO-3937-FRC in this case). After the colon, the current file path is displayed (~ means home, similar to the user's directory on Windows). Finally, a pound sine indicates the end of the prompt. (because the prompt is configurable in Linux, this can be changed).
We can find the absolute path by entering the command pwd.

Enter pwd to find absolute path

Create a folder to hold any and all settings files.

Create a directory with mkdir settings

To see the permissions (who can read or write to files in this directory), enter the command ls -l (ListSubdirectory -Longformat)

List subdirectory in long format (ls -l)

The total 0 in the output means that there are no files in the current directory.

The second lines gives us information about the settings directory.

Directory bit
Owner perm.
Group perm.
World perm.
Owning user
Owning group
I/O block size
Time stamp
Feb 20 09:35

We gather from this that the directory (by default) can be [R]ead from, [W]ritten to, and e[X]ecuted (or rather, the programs in side it can be) by the owner (who is admin).
Only read and executed by other members of the group, and the world.

So that we don't have to care what user our LabVIEW program is executing as, we will change the permissions so that anyone can read or write to the this directory by running the command chmod 777 settings (this will also make it executable, to remove that access for the group and world, use 766).

use the chmod command to change the access permissions

If you run ls -l now, you will see that the dashes have been replaced with w's - signifying that the write permission is now granted.

You can use a text editor like vi to create the file, but we will show how to have LabVIEW create it with a default value (this allows for less setup when moving between controllers).

First, move the offset constant into the False case of the Case Structure and reconnect it to the subtraction node. Then, also connect it to the while loop and create a shift register.

move the constant inside the False case.

Connect the left shift register to the tunnel in the True case to make this value remembered after the initialization.

Connect the shift register in the True case.

In the False case, you can press the Control key while clicking and moving the mouse to create some more space.

Click and control drag to expand the diagram.

Get an Open/Create/... VI from the File I/O palette.

Get an Open File VI.

Right click on the "file path" terminal

Right click on path terminal

and create a constant.

Create a constant

Also create a constant for the operation terminal and set it to open.

Create an Open constant for the operation

Finally, set the access terminal to read only

Create a Read-only constant for the access

If we highlight the VI and it's constants, we can use the diagram cleanup button to cleanup just the selection.

Cleanup the selection

We'll need to create some more space to handle if the file does not exist yet.

Click and control drag to expand the diagram.

We then add a Case Structure and connect the File Open's error out terminal to it.

Click and control drag to expand the diagram.

In the No Error case, we add a Read Text File VI (we set it to read 1 character, but later changed our minds on that.)

Create a read Text File in the No Error Case.

From the String Palette -> Number/String Conversion, we get the Frac/Exp String to Number VI (this allows for decimal values).

Get a Frc/Exp String to Number VI

We place this after the case structure and wire the output from the read to it.

Use it to convert the file

And use the number it returns as the default value.

Number becomes the default

In the Error case (this will be triggered if the file does not exist yet), we use another File Open VI, but set this one to Create Mode and Write-Only access.

Create the file in the error case

We add a Write Text File VI and connect it to the Open VI. We then create a constant for the text to write that we will set to the desired default value.

Create the file in the error case

Now close the file.

Create the file in the error case

We then re-open the file with read access.

Re-open the file with read access.

At this point, we realized we wanted to read the file in either case, so we move it to being after the Case Structure and rewire the error and refnum values through the No Error case.

Move the read after the case structure

We then wire the refnum from re-opening the file in the error case to the read VI via the tunnel.

Move the read after the case structure

We also connect the error wire to the read, and the output of the read to the convert VI and cleanup the diagram.

Move the read after the case structure

Programmatically updating configuration file

To allow us to programmatically update the file (and zero point) we insert a Compound Arithmetic into the wire control the main case structure.

Insert compound arithmetic

First, we invert the input that is not used

Invert unused input

Then, we change the mode to And

Invert unused input

Finally, we create a control on the inverted input. And name it Set.

Create a control on the inverted input

We now add a case structure inside the false case, around the logic to read the file.

Add another case structure

Move the convert inside the new structure and reconnect it.

Move the convert inside

Connect the Set control to the new case structures control terminal.

Connect the set control

Swap the case structure's False case.

Change the case structure to being the false case.

Move the path constant outside the case structures and reconnect it.

Move the path constant.

In the outer False Case, inner True case, add an Open File VI set to replace or create and write only

Add a Write Text File VI.

From the String Palette, get a Number to Fractional String VI

Connect it to the write and create a control for the zero point.

Wire the path constant to the Open VI

Create control for zero point.

Wire the zero point to the tunnel so that it can start being used.

Connect the zero point to the tunel.

At this point, we we add some comments, and do a diagram cleanup.

Finished VI.

Click here to download finished VI.


This method allows a potentiometer's read to be quickly adjusted - removing the disadvantage of having to get the shaft just right when making adjustments, but keeping the advantage of a known position at startup (without always starting in the same spot).

Always make sure the manipulator is not going to move based on an old config! If this is in Periodic tasks, the code will run and can have the set point update without enabling the robot; however, if this is implemented in Teleop, pull the breakers to the actuator before enabling to call the set

Possible Improvements

If this tutorial inadvertently leaves some details out, please tell us about it and we will update it.

Google Form to request details