ESP32 UNO - Potentiometer

Want to read a knob position with the ESP32 Uno? Connect a potentiometer to the ESP32 Uno form board and turn the knob into a live 0-4095 number in the Serial Monitor. A potentiometer (also called a rotary angle sensor or variable resistor) is the simplest way to add a manual control to any Arduino IDE project.

By the end, you can:

  1. Connect a potentiometer to the board in three wires
  2. Read the analog value with analogRead()
  3. Convert the value into a voltage, an angle or a PWM level
  4. Understand why the ESP32 Uno needs 3.3V and a 12-bit range
ESP32 Uno potentiometer

Hardware Preparation

1×ESP32 Uno-form Board
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×Potentiometer
1×Alternatively, 10k Ohm Trimmer Potentiometer
1×Alternatively, Potentiometer Kit
1×Alternatively, Potentiometer Module with Knob
1×Breadboard
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of Potentiometer

By the end of this part, you know what the three pins do and how the knob makes a voltage.

You use a potentiometer to change a setting by hand. Typical jobs are the volume of a stereo, the brightness of a lamp or the zoom of an oscilloscope.

Potentiometer Pinout

Pinout

A potentiometer has three pins.

Pin Connect To
GND GND (0V)
VCC The power rail of your board (use 3.3V on the ESP32 Uno)
Output (middle) An analog input pin of the ESP32 Uno
Potentiometer Pinout

※ NOTE THAT:

You may swap the GND and VCC wires. The knob then works in the other direction.

How It Works

By the end of this part, you can predict the output voltage for any knob angle.

Inside the part, a sliding contact moves along a resistor track when you turn the shaft. The shaft starts at 0° (closest to the GND pin) and ends at a maximum angle named ANGLE_MAX (closest to the VCC pin). The output voltage follows the angle in a straight line.

Shaft Angle Output Voltage
0° 0V
Between 0° and ANGLE_MAX angle × VCC / ANGLE_MAX
ANGLE_MAX Same as VCC

※ NOTE THAT:

Each maker picks its own ANGLE_MAX. You only need this number when you want to calculate the real rotation angle.

How Potentiometer Works

ESP32 Uno and the Analog Input

By the end of this part, you know what number the board gives you.

The ADC of the ESP32 Uno has 12 bits. It changes a voltage between 0V and about 3.3V into a whole number between 0 and 4095. This number is the ADC value. It is not an angle and not a voltage, so your code must convert it.

Good to know: the ESP32 Uno pins work at 3.3V and are NOT 5V tolerant. Power the potentiometer from 3.3V, so the output never goes higher.

Use Cases

  • Convert the ADC value to the shaft angle
  • Convert the ADC value to a voltage
  • Convert the ADC value to a control value such as stereo volume, LED brightness or motor speed (the most common use)

Rescale Range

FROM TO
Angleturned by you 0° → ANGLE_MAX
Voltageat the potentiometer output 0V → 3.3V
ADC valueread by the ESP32 Uno 0 → 4095
Other valuecalculated in code VALUE_MIN → VALUE_MAX

ESP32 Uno Pinout

Every Uno header pin of the ESP32 Uno form board has its own GPIO number, and your code uses that number. Match the labels in the diagram before you connect a wire.

ESP32 Uno pinout diagram

Wiring Diagram

By the end of this part, the potentiometer is connected and ready for the sketch.

The wiring diagram between ESP32 Uno Potentiometer

This image is created using Fritzing. Click to enlarge image

Potentiometer Pin ESP32 Uno Pin
VCC 3.3V
GND GND
Output A0 (GPIO2)

Good to know: the code reads this pin with the number 2, because A0 is GPIO2 on the ESP32 Uno.

WARNING

A0 (GPIO2) is a boot strapping pin. The chip checks it at start-up, so a module that pulls it the wrong way can stop the board from booting or uploading. A potentiometer is fine because its output sits between 0V and 3.3V, but unplug the output wire if an upload ever fails.

WARNING

Do not connect the potentiometer VCC to 5V. The output could reach 5V and damage the GPIO2 pin.

How To Program For Potentiometer

By the end of this part, you know the five lines that handle every potentiometer project.

Step 1 — Read the pin

Use analogRead() on the pin that holds the output wire. A0 is GPIO2.

adc_value = analogRead(2);

Step 2 — Convert to an angle

The map() function rescales the number.

angle = map(adc_value, 0, 4095, 0, ANGLE_MAX);

Step 3 — Convert to a voltage

voltage = map(adc_value, 0, 4095, 0, VCC);

Step 4 — Convert to a control value

Use any range you like, for example volume, brightness or motor speed.

value = map(adc_value, 0, 4095, VALUE_MIN, VALUE_MAX);

Step 5 — Example with LED brightness

PWM brightness runs from 0 (off) to 255 (full). Map the knob onto this range:

brightness = map(adc_value, 0, 4095, 0, 255);

※ NOTE THAT:

map() only gives whole numbers (int or long). When you need decimals, for example a voltage, use the floatMap() function below.

The floatMap() function:

float floatMap(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }

ESP32 Uno Code

This sketch reads the knob once per second and prints the raw value and the voltage (0 to 3.3V).

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-potentiometer */ float floatMap(float x, float in_min, float in_max, float out_min, float out_max) { // rescale a decimal number from one range to another range return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } void setup() { // start the Serial Monitor link at 9600 baud Serial.begin(9600); // set the ADC attenuation to 11 dB (up to ~3.3V input) analogSetAttenuation(ADC_11db); } void loop() { // A0 (GPIO2) carries the potentiometer output, read it as a 12-bit number int adc_value = analogRead(2); // change the 0-4095 number into a 0-3.3V voltage float voltage = floatMap(adc_value, 0, 4095, 0, 3.3); // print both numbers on one line Serial.print("Analog: "); Serial.print(adc_value); Serial.print(", Voltage: "); Serial.println(voltage); // pause one second, then measure again delay(1000); }
Code Part What It Does
floatMap() Rescales a decimal number from one range to another
analogSetAttenuation(ADC_11db) Opens the ADC input range up to about 3.3V
analogRead(2) Reads GPIO2 (A0) as a number from 0 to 4095
floatMap(adc_value, 0, 4095, 0, 3.3) Turns the number into a voltage
delay(1000) Gives one reading per second

The Serial Monitor now shows a new line every second.

Good to know: analogSetAttenuation(ADC_11db) lets the ESP32 Uno analog pin read the full range, from 0V up to about 3.3V. Without a wide range, the readings hit 4095 too early and the values look wrong.

Upload and Test

By the end of this part, the knob values appear on your screen.

  1. First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
  2. Build the circuit by following the wiring table above.
  3. Plug in the USB Type-C cable between the ESP32 Uno and your computer.
  4. Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
  5. Copy the code above and open it in Arduino IDE.
  6. Click the Upload button to send the code to the board.
  7. Open the Serial Monitor and set 9600 baud.
  8. Turn the knob slowly from one end to the other.
  9. Read the result in the Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
Analog: 0, Voltage: 0.00 Analog: 311, Voltage: 0.25 Analog: 905, Voltage: 0.73 Analog: 1873, Voltage: 1.51 Analog: 2640, Voltage: 2.13 Analog: 3402, Voltage: 2.74 Analog: 4095, Voltage: 3.30
Ln 11, Col 1
ESP32 Dev Module on COM15
2
  1. Pro tip: the last digits can flicker a little even when the knob is still. Print the average of 8 reads if you need a calm number.

Video Tutorial

See the ESP32 Uno build in action in the video below.

ESP32 Uno vs UNO R4 for This Project

By the end of this part, you know what to change when you move this project from the UNO R4 to the ESP32 Uno.

Item Arduino UNO R4 ESP32 Uno
Logic voltage 5V 3.3V
Potentiometer VCC 5V or 3.3V 3.3V only
Analog pin used A0 A0 (GPIO2), written as 2 in code
ADC range 0 to 1023 0 to 4095
Extra code line none analogSetAttenuation(ADC_11db)
Voltage math 0 to 5V 0 to 3.3V
Arduino IDE board Arduino UNO R4 WiFi ESP32 Dev Module

The wiring stays on the same A0 header position. Only the power wire moves to 3.3V, and the numbers in your math change.

Go Wireless: Show the Knob Value on Your Phone

By the end of this part, you have an idea to read the potentiometer without a cable.

The ESP32 Uno has WiFi and Bluetooth, so the knob value does not have to stay in the Serial Monitor. Send the number to a web page or to a phone app and watch a gauge or a graph move while you turn the knob. Remember that A0 (GPIO2) is an ADC2 pin, which cannot be read while WiFi is on. For a WiFi version, use A2 (GPIO35) for the output wire and change the code to analogRead(35).

Try These Next

  • Dim an LED with the knob: map the ADC value to 0-255 and use PWM
  • Print the shaft angle in degrees with map()
  • Control a servo with the knob, see the ESP32 Uno - Potentiometer Servo Motor tutorial
  • Average 8 readings to get a very stable value

Function References

Troubleshooting

Problem Possible Cause Solution
No COM port in Arduino IDE CH340 driver missing or a charge-only cable Install the CH340 driver and use a USB cable that carries data
Upload fails with Failed to connect or Waiting for download Board is not in download mode Hold the BOOT button while the upload starts
Board does not boot or upload with the knob connected A0 (GPIO2) is a boot strapping pin and was pulled the wrong way Unplug the output wire while uploading, or move to A2 (GPIO35) and change the code
Value stays at 0 VCC wire missing or the output wire is on the wrong pin Check the 3.3V, GND and A0 wires
Value reaches 4095 before the knob ends ADC range not widened Keep analogSetAttenuation(ADC_11db) in setup()
Value jumps around Loose breadboard contact or ADC noise Press the wires in firmly and average several reads
Value goes down when you turn up VCC and GND wires are swapped Swap the two outer wires
Voltage shows above 3.3V Code still uses 1023 or 5V from older 10-bit 5V sketches Use 4095 and 3.3 in map() and floatMap()
Nothing in the Serial Monitor Wrong baud rate Set the Serial Monitor to 9600
analogRead stuck while WiFi is on A0 (GPIO2) is an ADC2 pin Use A2 (GPIO35) or GPIO32 or GPIO33

FAQ

How does a potentiometer make a changing voltage?

It is a resistor track with a sliding contact. When you turn the shaft, the contact moves, and the middle pin gives a share of the supply voltage that depends on the angle.

Can I power the potentiometer from 5V on the ESP32 Uno?

No. The output could reach 5V, and the ESP32 Uno pins are not 5V tolerant. Use the 3.3V pin.

What value range does analogRead() give on the ESP32 Uno?

It gives 0 to 4095, because the ADC has 12 bits. The UNO R4 sketch uses 0 to 1023 by default, so change the numbers in map() when you copy old code.

Why does the code call analogSetAttenuation(ADC_11db)?

It sets the ESP32 Uno ADC input range to about 0-3.3V, so the full sensor signal maps to 0-4095. With a smaller range, readings saturate early. The UNO R4 does not need this line, it is ESP32-only. Keep the sensor output at 3.3V or less.

Which resistance value should I buy?

A 10kΩ linear potentiometer is a good choice. Smaller values waste a little more current, and larger values pick up more noise.

How do I get an angle instead of a voltage?

Use map(adc_value, 0, 4095, 0, ANGLE_MAX). Take ANGLE_MAX from the datasheet of your part, often around 270°.

Can I use A1 to A5 for the knob?

Yes. All six analog header pins can read it. A2 to A5 (GPIO35, 34, 36, 39) are input only, which is perfect for a sensor. A0 and A1 (GPIO2, GPIO4) are ADC2 pins that fail while WiFi is on.

Can I read two potentiometers at once?

Yes. Wire the second output to another analog pin, call analogRead() with its GPIO number, and keep one analogSetAttenuation(ADC_11db) line in setup().

Can I show the knob value on a web page with the ESP32 Uno?

Yes, the ESP32 Uno has WiFi and Bluetooth. See the Go Wireless section for ready tutorials. Use an ADC1 pin such as A2 (GPIO35) for WiFi projects.

What if my project needs more pins than the Uno headers give?

The ESP32 Uno has a few extra holes near the power header: GPIO32 and GPIO33 (I/O, PWM, analog on ADC1, so they also work while WiFi is on) and GPIO15 (I/O, PWM, analog on ADC2). Solder pin headers to use them and write the GPIO number in code. For more potentiometers in a WiFi project, GPIO32 and GPIO33 fit best. Two warnings: (1) GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC position) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code, so use GPIO32 and GPIO33 first. (2) Never use the six holes under the digital header (SD0-SD3, CMD, CLK = GPIO6-GPIO11), because they are wired to the flash chip and using them crashes the board.

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!