ESP32 S3 UNO - Potentiometer

This ESP32 S3 Uno potentiometer tutorial shows you how to wire a potentiometer to the ESP32 S3 Uno form board and read its value with Arduino code. As you turn the knob of this variable resistor (also called a rotary angle sensor), the Serial Monitor shows the analog value and the matching voltage.

In this tutorial, you will:

  1. Learn how a potentiometer works and what its three pins do
  2. Wire a potentiometer to an analog pin of the ESP32 S3 Uno
  3. Read the analog value (0 to 4095) with analogRead()
  4. Convert the value into a voltage, an angle, or any range you need
ESP32 S3 Uno potentiometer

Hardware Preparation

1×ESP32 S3 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

A potentiometer is one of the easiest ways to give your project a manual control. Once you know how it turns a knob position into a voltage, you can use it for almost any setting.

A rotary potentiometer is also called a rotary angle sensor. You find it in everyday devices, where it sets things like the volume of a stereo, the brightness of a lamp, or the zoom level of an oscilloscope.

Potentiometer Pinout

Pinout

Most potentiometers have three pins. Two of them are for power, and the middle one gives the signal you read.

GND pin

Connect it to GND (0V).

VCC pin

Connect it to the power supply. With the ESP32 S3 Uno, use the 3.3V pin, so the output never goes above 3.3V.

Output pin

This pin sends a voltage to an analog input pin of the ESP32 S3 Uno.

Potentiometer Pinout

※ NOTE THAT:

You can swap the GND pin and the VCC pin. The only change is the direction: turning the knob the same way will now make the value go down instead of up.

How It Works

Inside the potentiometer, a sliding contact moves along a resistor as you turn the shaft. This simple idea turns a position into a voltage that your board can measure.

The shaft turns from 0° (the end closest to the GND pin) up to a maximum angle (the end closest to the VCC pin). We call this maximum angle ANGLE_MAX.

The voltage on the output pin goes from the GND voltage to the VCC voltage, and it changes in a straight line with the angle. At 0°, the output is 0V. At ANGLE_MAX, the output equals VCC. For any angle in between, output_voltage = angle × VCC / ANGLE_MAX.

※ NOTE THAT:

ANGLE_MAX is different from one manufacturer to another. You usually do not need it, unless you want to calculate the rotation angle (see the use cases below).

How Potentiometer Works

ESP32 S3 Uno - Rotary Potentiometer

The ESP32 S3 Uno has analog input pins on the A0 to A5 headers. These pins measure a voltage and turn it into a number, so this is where the potentiometer's output goes.

The ESP32 S3 Uno has a 12-bit ADC. It turns a voltage from 0V to about 3.3V into a whole number from 0 to 4095. This number is called the ADC value or the analog value. Keep in mind that the board does not give you an angle or a voltage directly. It only gives you this number.

When you wire the potentiometer's output pin to an analog pin, your code can read the ADC value and convert it into something useful.

Use Cases

There are three common ways to use the ADC value. You can convert it into the angle of the shaft, or into the voltage on the output pin. Most often, you convert it into a value you want to control, such as the volume of a stereo, the brightness of an LED, or the speed of a motor.

Rescale Range

The table below shows how each range lines up with the others. The idea is always the same: one end of the knob gives the minimum, the other end gives the maximum.

FROM TO
Anglerotated by user 0° → ANGLE_MAX
Voltagefrom potentiometer's pin 0V → VCC (3.3V)
ADC valueread by ESP32 S3 Uno 0 → 4095
Other valueconverted by ESP32 S3 Uno VALUE_MIN → VALUE_MAX

ESP32 S3 Uno Pinout

The image below shows the pinout diagram of the ESP32 S3 Uno form board. Use it to find the Uno header pins (D2, A0, SDA…) and their GPIO numbers when you wire the circuit.

ESP32 S3 Uno pinout diagram

Wiring Diagram

Connect the potentiometer's output pin to the A0 header of the ESP32 S3 Uno, and power the potentiometer from the 3.3V pin.

The wiring diagram between ESP32 S3 Uno Potentiometer

This image is created using Fritzing. Click to enlarge image

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

WARNING

The ESP32 S3 Uno GPIO pins are NOT 5V tolerant. If you connect the potentiometer's VCC pin to 5V, the output pin can reach 5V and damage GPIO2. Always power the potentiometer from 3.3V.

How To Program For Potentiometer

Reading a potentiometer takes one function, and converting the result takes one more. The snippets below show each step on its own.

  1. Read the output pin with analogRead(). The A0 header is GPIO2, so you pass the number 2.
adc_value = analogRead(2);
  1. Convert the ADC value into the angle of the shaft with the map() function.
angle = map(adc_value, 0, 4095, 0, ANGLE_MAX);
  1. Convert the ADC value into a voltage.
voltage = map(adc_value, 0, 4095, 0, VCC);
  1. Convert the ADC value into a value you want to control, such as the volume of a stereo, the brightness of an LED, or the speed of a DC motor.
value = map(adc_value, 0, 4095, VALUE_MIN, VALUE_MAX);
  1. For example, to set the brightness of an LED, you use a PWM value from 0 (always OFF) to 255 (always ON). Map the ADC value onto this range, and the knob moves the LED from off to fully bright.
brightness = map(adc_value, 0, 4095, 0, 255);

※ NOTE THAT:

The map() function only works with whole numbers, so it returns an int or long value. When you need a float result, such as a voltage with decimals, use the floatMap() function instead.

Here is 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 S3 Uno Code

This sketch reads the potentiometer on GPIO2 once every second. It converts the raw value into a voltage between 0V and 3.3V with floatMap(), then prints both numbers on the Serial Monitor.

/* * This ESP32 S3 Uno code was developed by newbiely.com * * This ESP32 S3 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3-uno/esp32-s3-uno-potentiometer */ float floatMap(float x, float in_min, float in_max, float out_min, float out_max) { // Map a float value from one range to another. return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } void setup() { // Begin serial communication with a baud rate of 9600: Serial.begin(9600); // set the ADC attenuation to 11 dB (up to ~3.3V input) analogSetAttenuation(ADC_11db); } void loop() { // Retrieve analog value from pin GPIO2 (A0): int adc_value = analogRead(2); // Convert the analog value to a voltage (0-3.3V range): float voltage = floatMap(adc_value, 0, 4095, 0, 3.3); // Output the analog value and corresponding voltage to the serial monitor: Serial.print("Analog: "); Serial.print(adc_value); Serial.print(", Voltage: "); Serial.println(voltage); // Wait for a second before repeating the loop: delay(1000); }

The line analogSetAttenuation(ADC_11db); in setup() is important on the ESP32 S3 Uno. By default, its ADC can only measure a small voltage. With 11 dB attenuation, the analog pin reads the full range from 0V up to about 3.3V. Without it, the reading hits 4095 too early, and the values look wrong as you turn the knob.

Detailed Instructions

Follow these steps in order:

  1. New to the ESP32 S3 Uno? Follow ESP32 S3 Uno - Getting Started first.
  2. Wire it up as shown in the diagram.
  3. Connect the board to your computer with a USB Type-C cable.
  4. Open Arduino IDE, choose the ESP32S3 Dev Module board and the correct COM port.
  5. Copy the code above and paste it into Arduino IDE.
  6. Upload the code by clicking the Upload button.
  7. Open the Serial Monitor and set the baud rate to 9600.
  8. Turn the potentiometer slowly from one end to the other.
  9. Check the result on the Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
Analog: 0, Voltage: 0.00 Analog: 0, Voltage: 0.00 Analog: 512, Voltage: 0.41 Analog: 1130, Voltage: 0.91 Analog: 2071, Voltage: 1.67 Analog: 3018, Voltage: 2.43 Analog: 3627, Voltage: 2.92 Analog: 4095, Voltage: 3.30 Analog: 4095, Voltage: 3.30
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2
  1. Tip: The ESP32 S3 Uno ADC is a bit noisy, so the value may jump by a few steps even when you do not touch the knob. This is normal. If you need a steadier number, read the pin several times and use the average.

Video Tutorial

Watch the video below to see this ESP32 S3 Uno project step by step.

Function References

FAQ

Why does my potentiometer read 0 to 4095 instead of 0 to 1023?

The ESP32 S3 Uno has a 12-bit ADC, so analogRead() returns a number from 0 to 4095. Many Arduino boards, like the UNO R4 by default, use a 10-bit range of 0 to 1023. If you copy code from those boards, change every 1023 in your map() calls to 4095.

Why does the code call analogSetAttenuation(ADC_11db)?

It sets the input range of the ESP32 S3 Uno ADC to about 0V to 3.3V, so the full turn of the potentiometer maps to 0 to 4095. Without it, the range is smaller and the reading reaches 4095 long before the knob reaches the end. The UNO R4 does not need this line, because it is only needed on ESP32 boards like the ESP32 S3 Uno. Keep the potentiometer powered from 3.3V so the signal never goes above 3.3V.

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

No. With 5V on the VCC pin, the output pin can reach 5V, and the ESP32 S3 Uno pins are not 5V tolerant. This can damage the pin. Use the 3.3V pin instead.

Which ESP32 S3 Uno pins can read a potentiometer?

The A0 to A5 headers all work as analog inputs (GPIO2, GPIO1, GPIO7, GPIO6, GPIO5 and GPIO4). Many digital headers, such as D2 to D7 and D10 to D13, also support analog input. In your code, always write the GPIO number, for example analogRead(2) for A0. Note that D8 (GPIO21) and D9 (GPIO46) have no analog function.

Why do the readings near 0V and 3.3V look less accurate?

The ESP32 S3 Uno ADC is not perfectly linear at the very ends of its range. Values close to 0V and close to 3.3V can be a little off. For a knob control this does not matter, but for exact voltage measurement, take the middle of the range or calibrate your readings.

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

The ESP32 S3 Uno has two extra rows of holes with more GPIOs. GPIO15 and GPIO16 support I/O, PWM and analog. GPIO45 and GPIO35 to GPIO42 support I/O and PWM. GPIO47 and GPIO48 are output only, with PWM. Solder pin headers to use them and write the GPIO number in your code. For extra potentiometers, use GPIO15 or GPIO16, because they are the only extra pins that can read analog values. Keep two warnings in mind. First, GPIO47 and GPIO48 may run at 1.8V instead of 3.3V on some modules (especially ones with "V" in the name, like R8V or R16V), so 3.3V devices can be damaged or act strangely. Second, GPIO0, GPIO3 (D6), GPIO45 and GPIO46 (D9) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code. Use the other extra pins first.

Troubleshooting

Problem Possible Cause Solution
No COM port shows up in Arduino IDE USB driver missing or board not in upload mode Install the CP210x or CH340 driver, use a data USB cable, or hold BOOT while pressing RESET
Nothing prints on the Serial Monitor Wrong baud rate Set the Serial Monitor to 9600 baud
Value stays at 0 when you turn the knob VCC wire missing or output wire on the wrong pin Check the 3.3V and GND wires and make sure the middle pin goes to A0 (GPIO2)
Value reaches 4095 when the knob is only half turned ADC attenuation not set Add analogSetAttenuation(ADC_11db) in setup()
Value jumps around without touching the knob ADC noise or a loose breadboard contact Press the wires in firmly and average several readings
Value goes down when you turn the knob up VCC and GND pins are swapped Swap the two outer wires or change the map() range
Voltage shows more than 3.3V in your math Code still uses 5V or 1023 from old Arduino code Use 3.3 and 4095 in floatMap() and map()

※ 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!