ESP32 UNO - Potentiometer fade LED
Want to dim an LED with a knob? With a potentiometer and the ESP32 Uno form board, a small sketch turns the knob position into LED brightness. You wire a variable resistor and an LED, read the voltage with Arduino IDE code, and watch the light fade up and down.
By the end, you can:
- Connect a potentiometer and an LED to the ESP32 Uno
- Read the knob with analogRead() on a 12-bit ADC
- Turn the reading into PWM brightness with map() and analogWrite()

Hardware Preparation
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Additionally, some of these links are for products from our own brand, DIYables .
Buy Note: Use the LED Module for easier wiring. It includes an integrated resistor.
Overview of the LED and the Potentiometer
After this part, you know where to read about each part alone. The potentiometer is the input, and the LED is the output.
Learn the pinout, the working principle and the basic code of each part here:
| Part | Role | Signal |
|---|---|---|
| Potentiometer | Input | Voltage from 0V to 3.3V on the wiper |
| LED | Output | PWM duty from 0 to 255 |
ESP32 Uno Pinout
Every Uno header label on the ESP32 Uno form board has a GPIO number behind it, and the sketch uses that number. Look at the picture to match labels and GPIOs before you place a wire.

Wiring Diagram
Goal: the knob feeds an analog pin, and the LED sits on a PWM pin behind a resistor.

This image is created using Fritzing. Click to enlarge image
| Component Pin | ESP32 Uno Pin |
|---|---|
| Potentiometer VCC | 3.3V |
| Potentiometer GND | GND |
| Potentiometer Output (middle pin) | A0 (GPIO2) |
| LED Anode (+) via 220 ohm resistor | D3 (GPIO25) |
| LED Cathode (-) | GND |
Good to know: Power the potentiometer from 3.3V. ESP32 Uno pins are not 5V tolerant.
WARNING
A0 (GPIO2) is a boot strapping pin. If the board does not start or upload with the circuit connected, unplug the potentiometer wire from A0 while you upload, then plug it in again. A0 is also an ADC2 pin, so analogRead() on it stops working when WiFi is on. This sketch does not use WiFi, so it works fine here.
How To Program
Goal: understand the three jobs the loop does, in order.
Step 1 — Read the knob
The ADC measures the voltage on A0 (GPIO2). On the ESP32 Uno the result runs from 0 to 4095.
Step 2 — Scale it to a duty value
PWM duty uses 0 to 255, so map() shrinks the big range into the small one.
Step 3 — Drive the LED
Send the duty value to the LED on D3 (GPIO25).
ESP32 Uno Code
Goal: one sketch that reads the knob, sets the LED and prints both numbers every 100 ms.
| Code Part | What It Does |
|---|---|
| #define LED_PIN 25 | Names the LED pin, D3 (GPIO25) |
| #define POTENTIOMETER_PIN 2 | Names the knob pin, A0 (GPIO2) |
| analogSetAttenuation(ADC_11db) | Opens the ADC range to about 3.3V |
| analogRead() | Gets a number from 0 to 4095 |
| map() | Converts 0-4095 into 0-255 |
| analogWrite() | Sets the LED brightness with PWM |
The result: the LED goes from dark to full light as you turn the knob from one end to the other.
Good to know: The analogSetAttenuation(ADC_11db) line lets the ESP32 Uno analog pin read the full range, from 0V up to about 3.3V. With a narrower range, the reading hits 4095 too early, and the LED is fully on before the knob ends.
Detailed Instructions
Do these in order:
- First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
- Build the circuit by following the wiring table above.
- Plug in the USB Type-C cable between the ESP32 Uno and your computer.
- Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
- Copy the code and paste it into a new sketch.
- Click Upload (Upload button) to send the sketch to the board.
- Open the Serial Monitor at 9600 baud.
- Turn the knob slowly and watch the LED.
- Compare the numbers with this sample:
- Pro tip: Add a second LED on another PWM pin and send it 255 - brightness. One LED fades up while the other fades down.
Video Tutorial
See the ESP32 Uno build in action in the video below.
ESP32 Uno vs UNO R4 for This Project
Goal: 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 supply | 5V | 3.3V |
| Knob pin | A0 | A0 (GPIO2), written as 2 in code |
| LED pin | D3 | D3 (GPIO25), written as 25 in code |
| ADC range | 0 to 1023 | 0 to 4095 |
| map() input range | 0, 1023 | 0, 4095 |
| Extra code line | none | analogSetAttenuation(ADC_11db) |
| Arduino IDE board | Arduino UNO R4 WiFi | ESP32 Dev Module |
The wiring positions stay the same, so the same breadboard layout works. Only change the supply of the potentiometer to 3.3V, and the numbers in the code.
Go Wireless: Dim the LED from Your Phone
Goal: see the knob value on a screen, or move the dimming to your phone.
The ESP32 Uno has WiFi and Bluetooth. You can send the adc_value and brightness numbers to a web page and watch them as a live graph, or use a phone slider in place of the knob. Note that A0 (GPIO2) is an ADC2 pin and cannot be read while WiFi is on, so for a WiFi version, move the knob to A2 (GPIO35) and change POTENTIOMETER_PIN in the code.
Try These Next
- Make the LED fade the other way, so a higher knob value gives a darker light.
- Light three LEDs one after another as the knob turns.
- Use constrain() to ignore the first and last 100 steps of the knob.
- Average 8 readings before map() to remove flicker.
Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| No COM port shows in Arduino IDE | CH340 driver missing or a charge-only cable | Install the CH340 driver and use a USB data cable |
| Failed to connect or Waiting for download | Board is not in upload mode | Hold the BOOT button when the upload starts |
| Board will not boot or upload with the circuit on | A0 (GPIO2) is a boot strapping pin pulled the wrong way | Unplug the potentiometer wire from A0 while you upload |
| LED never lights | LED is reversed or the resistor is loose | Put the long leg toward D3 (GPIO25) and check the 220 ohm resistor |
| LED is full on for half of the knob turn | map() still uses 1023 or the attenuation line is missing | Use map(adc_value, 0, 4095, 0, 255) and keep analogSetAttenuation(ADC_11db) |
| Reading is stuck at 0 or 4095 | Middle pin is not on A0 or the outer pins are loose | Connect the wiper to A0 (GPIO2), the outer pins to 3.3V and GND |
| Brightness flickers | ADC noise or a loose breadboard wire | Press wires in firmly and average a few readings |
| Reading jumps to 4095 and the pin gets hot | 5V is wired to the potentiometer VCC | Use the 3.3V pin, 5V can damage the pin |
| Strange characters in Serial Monitor | Wrong baud rate | Set the Serial Monitor to 9600 |
FAQ
How does a potentiometer dim an LED?
The potentiometer works as a voltage divider. Its middle pin gives a voltage between 0V and 3.3V. The board turns that into a number, and PWM turns the number into an average LED power.
What 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 map() call to use 4095.
Why does the code call analogSetAttenuation(ADC_11db)?
It sets the ESP32 Uno ADC input range to about 0-3.3V, so the full knob turn 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.
Is it safe to give the knob 5V?
No. The ESP32 Uno pins are not 5V tolerant, so 5V on the wiper can damage the pin. Use the 3.3V pin.
Is a resistor needed for the LED?
Yes. Use a 220 ohm resistor in series with the LED. It limits the current to a safe level for the GPIO pin.
Where can I connect the LED for PWM dimming?
Most Uno header pins support PWM, so D2 to D13 all work. The input-only pins A2 to A5 (GPIO35, 34, 36, 39) cannot drive an LED. This tutorial uses D3 (GPIO25).
Can I use the potentiometer on A0 while WiFi is on?
Not with analogRead(). A0 (GPIO2) is an ADC2 pin, and ADC2 cannot be read while WiFi is on. Move the wiper to A2 (GPIO35) or GPIO32/33 and change the pin in the code.
Do I have to write A0 in the code?
No, write the GPIO number. On the ESP32 core, A0 means GPIO36, not the A0 label on the board. This sketch uses 2 for A0 (GPIO2).
Why does the brightness jump a little when I do not touch the knob?
The ADC has some noise, so the value can move by a few steps. Average several readings, or add a 0.1 µF capacitor from the wiper to GND.
Can I show the knob value on a web page with the ESP32 Uno?
Yes. The ESP32 Uno has WiFi and Bluetooth, so a web page or phone app can show the value. See the Go Wireless section for links.
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 a second knob in a WiFi project, GPIO32 or GPIO33 is a good fit. 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/33 first. (2) Never use the six holes under the digital header (SD0-SD3, CMD, CLK = GPIO6-GPIO11). They are wired to the flash chip, and using them crashes the board.