Basics of Potentiometers with Arduino

Learn the fundamentals of how a potentiometers works, about the forms they come in, and how to use them in your projects.

A potentiometer is a simple mechanical device that comes in many different forms. It provides a variable amount of resistance that changes as you manipulate it. The examples in this article uses a potentiometer with a twisting shaft, one of the more common versions of a potentiometer you will find.

By passing voltage through a potentiometer into an analog input on your Arduino, it is possible to measure the amount of resistance of the potentiometer as an analog value. This article will showcase use cases of potentiometers, as well as teach you how to connect and read data from them. One shows how you can use a potentiometer as an input for a color mixer, and the other shows how to accurately choose colors and how to smoothly fade between them.

The typical potentiometer will have 3 pins, two power supply pins (+5V and GND), and one pin that connects to an analog input pin on your Arduino to read the value output.

To learn how to read data from a potentiometer, and display it in the Serial Monitor, visit the Analog Read Serial example.

Hardware Required

  • Arduino board
  • Potentiometer
  • 1x Red, 1x Green, 1x Blue LED
  • 3x 220 Ohm Resistors

Circuit

  • Potentiometer + Pin to 5V
  • Potentiometer - Pin to GND
  • Potentiometer Data Pin to A3
  • A Red LED connected to pin 9 with a 220 Ohm Resistor
  • A Green LED connected to pin 10 with a 220 Ohm Resistor
  • A Blue LED connected to pin 11 with a 220 Ohm Resistor

Complete Circuit
Complete Circuit

Color Mixer Example

This example will show you how a potentiometer can be used as an analog input to mix colors with great granularity.

1/*
2* Code for making one potentiometer control 3 LEDs, red, grn and blu, or one tri-color LED
3* The program cross-fades from red to grn, grn to blu, and blu to red
4* Clay Shirky <clay.shirky@nyu.edu>
5*/
6
7// INPUT: Potentiometer should be connected to 5V and GND
8int potPin = A3; // Potentiometer output connected to analog pin 3
9int potVal = 0; // Variable to store the input from the potentiometer
10
11// OUTPUT: Use digital pins 9-11, the Pulse-width Modulation (PWM) pins
12// LED's cathodes should be connected to digital GND
13int redPin = 9; // Red LED, connected to digital pin 9
14int grnPin = 10; // Green LED, connected to digital pin 10
15int bluPin = 11; // Blue LED, connected to digital pin 11
16
17// Program variables
18int redVal = 0; // Variables to store the values to send to the pins
19int grnVal = 0;
20int bluVal = 0;
21
22void setup()
23{
24 pinMode(redPin, OUTPUT); // sets the pins as output
25 pinMode(grnPin, OUTPUT);
26 pinMode(bluPin, OUTPUT);
27}
28
29// Main program
30void loop()
31{
32 potVal = analogRead(potPin); // read the potentiometer value at the input pin
33
34 if (potVal < 341) // Lowest third of the potentiometer's range (0-340)
35 {
36 potVal = (potVal * 3) / 4; // Normalize to 0-255
37
38 redVal = 256 - potVal; // Red from full to off
39 grnVal = potVal; // Green from off to full
40 bluVal = 1; // Blue off
41 }
42 else if (potVal < 682) // Middle third of potentiometer's range (341-681)
43 {
44 potVal = ( (potVal-341) * 3) / 4; // Normalize to 0-255
45
46 redVal = 1; // Red off
47 grnVal = 256 - potVal; // Green from full to off
48 bluVal = potVal; // Blue from off to full
49 }
50 else // Upper third of potentiometer"s range (682-1023)
51 {
52 potVal = ( (potVal-683) * 3) / 4; // Normalize to 0-255
53
54 redVal = potVal; // Red from off to full
55 grnVal = 1; // Green off
56 bluVal = 256 - potVal; // Blue from full to off
57 }
58 analogWrite(redPin, redVal); // Write values to LED pins
59 analogWrite(grnPin, grnVal);
60 analogWrite(bluPin, bluVal);
61}

Color Crossfading Example

1/*
2* Code for cross-fading 3 LEDs, red, green and blue (RGB)
3* To create fades, you need to do two things:
4* 1. Describe the colors you want to be displayed
5* 2. List the order you want them to fade in
6*
7* DESCRIBING A COLOR:
8* A color is just an array of three percentages, 0-100,
9* controlling the red, green and blue LEDs
10*
11* Red is the red LED at full, blue and green off
12* int red = { 100, 0, 0 }
13* Dim white is all three LEDs at 30%
14* int dimWhite = {30, 30, 30}
15* etc.
16*
17* Some common colors are provided below, or make your own
18*
19* LISTING THE ORDER:
20* In the main part of the program, you need to list the order
21* you want to colors to appear in, e.g.
22* crossFade(red);
23* crossFade(green);
24* crossFade(blue);
25*
26* Those colors will appear in that order, fading out of
27* one color and into the next
28*
29* In addition, there are 5 optional settings you can adjust:
30* 1. The initial color is set to black (so the first color fades in), but
31* you can set the initial color to be any other color
32* 2. The internal loop runs for 1020 iterations; the 'wait' variable
33* sets the approximate duration of a single crossfade. In theory,
34* a 'wait' of 10 ms should make a crossFade of ~10 seconds. In
35* practice, the other functions the code is performing slow this
36* down to ~11 seconds on my board. YMMV.
37* 3. If 'repeat' is set to 0, the program will loop indefinitely.
38* if it is set to a number, it will loop that number of times,
39* then stop on the last color in the sequence. (Set 'return' to 1,
40* and make the last color black if you want it to fade out at the end.)
41* 4. There is an optional 'hold' variable, which pasues the
42* program for 'hold' milliseconds when a color is complete,
43* but before the next color starts.
44* 5. Set the DEBUG flag to 1 if you want debugging output to be
45* sent to the serial monitor.
46*
47* The internals of the program aren't complicated, but they
48* are a little fussy -- the inner workings are explained
49* below the main loop.
50*
51* April 2007, Clay Shirky <clay.shirky@nyu.edu>
52*/
53
54// Output
55int redPin = 9; // Red LED, connected to digital pin 9
56int grnPin = 10; // Green LED, connected to digital pin 10
57int bluPin = 11; // Blue LED, connected to digital pin 11
58
59// Color arrays
60int black[3] = { 0, 0, 0 };
61int white[3] = { 100, 100, 100 };
62int red[3] = { 100, 0, 0 };
63int green[3] = { 0, 100, 0 };
64int blue[3] = { 0, 0, 100 };
65int yellow[3] = { 40, 95, 0 };
66int dimWhite[3] = { 30, 30, 30 };
67// etc.
68
69// Set initial color
70int redVal = black[0];
71int grnVal = black[1];
72int bluVal = black[2];
73
74int wait = 10; // 10ms internal crossFade delay; increase for slower fades
75int hold = 0; // Optional hold when a color is complete, before the next crossFade
76int DEBUG = 1; // DEBUG counter; if set to 1, will write values back via serial
77int loopCount = 60; // How often should DEBUG report?
78int repeat = 3; // How many times should we loop before stopping? (0 for no stop)
79int j = 0; // Loop counter for repeat
80
81// Initialize color variables
82int prevR = redVal;
83int prevG = grnVal;
84int prevB = bluVal;
85
86// Set up the LED outputs
87void setup()
88{
89 pinMode(redPin, OUTPUT); // sets the pins as output
90 pinMode(grnPin, OUTPUT);
91 pinMode(bluPin, OUTPUT);
92
93 if (DEBUG) { // If we want to see values for debugging...
94 Serial.begin(9600); // ...set up the serial output
95 }
96}
97
98// Main program: list the order of crossfades
99void loop()
100{
101 crossFade(red);
102 crossFade(green);
103 crossFade(blue);
104 crossFade(yellow);
105
106 if (repeat) { // Do we loop a finite number of times?
107 j += 1;
108 if (j >= repeat) { // Are we there yet?
109 exit(j); // If so, stop.
110 }
111 }
112}
113
114/* BELOW THIS LINE IS THE MATH -- YOU SHOULDN'T NEED TO CHANGE THIS FOR THE BASICS
115*
116* The program works like this:
117* Imagine a crossfade that moves the red LED from 0-10,
118* the green from 0-5, and the blue from 10 to 7, in
119* ten steps.
120* We'd want to count the 10 steps and increase or
121* decrease color values in evenly stepped increments.
122* Imagine a + indicates raising a value by 1, and a -
123* equals lowering it. Our 10 step fade would look like:
124*
125* 1 2 3 4 5 6 7 8 9 10
126* R + + + + + + + + + +
127* G + + + + +
128* B - - -
129*
130* The red rises from 0 to 10 in ten steps, the green from
131* 0-5 in 5 steps, and the blue falls from 10 to 7 in three steps.
132*
133* In the real program, the color percentages are converted to
134* 0-255 values, and there are 1020 steps (255*4).
135*
136* To figure out how big a step there should be between one up- or
137* down-tick of one of the LED values, we call calculateStep(),
138* which calculates the absolute gap between the start and end values,
139* and then divides that gap by 1020 to determine the size of the step
140* between adjustments in the value.
141*/
142
143int calculateStep(int prevValue, int endValue) {
144 int step = endValue - prevValue; // What's the overall gap?
145 if (step) { // If its non-zero,
146 step = 1020/step; // divide by 1020
147 }
148 return step;
149}
150
151/* The next function is calculateVal. When the loop value, i,
152* reaches the step size appropriate for one of the
153* colors, it increases or decreases the value of that color by 1.
154* (R, G, and B are each calculated separately.)
155*/
156
157int calculateVal(int step, int val, int i) {
158
159 if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
160 if (step > 0) { // increment the value if step is positive...
161 val += 1;
162 }
163 else if (step < 0) { // ...or decrement it if step is negative
164 val -= 1;
165 }
166 }
167 // Defensive driving: make sure val stays in the range 0-255
168 if (val > 255) {
169 val = 255;
170 }
171 else if (val < 0) {
172 val = 0;
173 }
174 return val;
175}
176
177/* crossFade() converts the percentage colors to a
178* 0-255 range, then loops 1020 times, checking to see if
179* the value needs to be updated each time, then writing
180* the color values to the correct pins.
181*/
182
183void crossFade(int color[3]) {
184 // Convert to 0-255
185 int R = (color[0] * 255) / 100;
186 int G = (color[1] * 255) / 100;
187 int B = (color[2] * 255) / 100;
188
189 int stepR = calculateStep(prevR, R);
190 int stepG = calculateStep(prevG, G);
191 int stepB = calculateStep(prevB, B);
192
193 for (int i = 0; i <= 1020; i++) {
194 redVal = calculateVal(stepR, redVal, i);
195 grnVal = calculateVal(stepG, grnVal, i);
196 bluVal = calculateVal(stepB, bluVal, i);
197
198 analogWrite(redPin, redVal); // Write current values to LED pins
199 analogWrite(grnPin, grnVal);
200 analogWrite(bluPin, bluVal);
201
202 delay(wait); // Pause for 'wait' milliseconds before resuming the loop
203
204 if (DEBUG) { // If we want serial output, print it at the
205 if (i == 0 or i % loopCount == 0) { // beginning, and every loopCount times
206 Serial.print("Loop/RGB: #");
207 Serial.print(i);
208 Serial.print(" | ");
209 Serial.print(redVal);
210 Serial.print(" / ");
211 Serial.print(grnVal);
212 Serial.print(" / ");
213 Serial.println(bluVal);
214 }
215 DEBUG += 1;
216 }
217 }
218 // Update current values for next loop
219 prevR = redVal;
220 prevG = grnVal;
221 prevB = bluVal;
222 delay(hold); // Pause for optional 'wait' milliseconds before resuming the loop
223}

Contribute to Arduino

Join the community and suggest improvements to this article via GitHub. Make sure to read out contribution policy before making your pull request.

Missing something?

Check out our store and get what you need to follow this tutorial.