PROJECT 2 · ANALOG INPUT

Analog Inputs: Reading a Potentiometer

Measure a range of voltage (0–3.3 V) as a number 0–4095 with the ESP32's ADC.

⬇ Download the sketch Save Project_2_ESP32_Analog_Inputs.ino, then open it in the Arduino IDE (setup: Foundation 3).

🎯 Objective

By the end of this project, you will:

1 · Analog vs. Digital: How It Works

The ESP32 ADC is 12‑bit, so readings run 0 … 4095:

0–3.3 V maps to 0–4095
0 V → 0 · 3.3 V → 4095 · in between → proportional.

The ADC pin here

We use GPIO 4 ANALOG (ADC2, channel 0): the same physical pin that was a digital input in Project 1, now used with analogRead().

For later: GPIO 4 is on ADC2, which can't be read while Wi‑Fi is on. Fine here (no Wi‑Fi). In Wi‑Fi projects use an ADC1 pin (GPIO 32, 33, 34, 35, 36, 39).

Which pins can do analog input?

Grab your ESP32 board and locate the pins highlighted with a red border in the figure below: these are your analog-capable pins:

ESP32 DEVKIT V1 pinout with ADC pins highlighted in red
ESP32 DEVKIT V1 (30‑pin version): ADC pins are outlined in red. The board has 15 ADC pins, each with 12‑bit resolution (values from 0 to 4095).

Notice that not every pin can read an analog signal. The red‑outlined pins are the ones connected to the internal ADC hardware. In this project we use GPIO 4, but you could use any of the other ADC pins just as well.

3 · Parts Required

QtyPartNotes
1ESP32 DEVKIT V1 · breadboard · jumper wires-
1Potentiometer (10 kΩ)3 legs: two ends + a middle wiper

4 · Wiring the Circuit

Potentiometer: outer legs to 3.3 V and GND, wiper to GPIO 4
Outer legs → 3.3 V and GND · middle leg (wiper) → GPIO 4.
  1. One outer leg → 3.3 V
  2. Other outer leg → GND
  3. Middle leg (wiper) → GPIO 4

Turning the knob taps off 0 V → 3.3 V, and the ADC reports the matching 0–4095 value.

5 · Code Walkthrough: Understanding the Sketch

Let's walk through the key parts of the sketch so you understand what each line does and why.

Step 1: Pin definition & variables

// The potentiometer's middle leg (wiper) connects to GPIO 4
const int potPin = 4;    // ADC2, channel 0, an analog-capable pin

int potValue = 0;           // Variable to store the ADC reading (0–4095)

const int potPin = 4; gives the pin a human-readable name. Using a constant (const) prevents accidentally changing the pin number later. The variable potValue will hold whichever value analogRead() returns.

Step 2: one-time preparation in setup()

void setup() {
  Serial.begin(115200);     // Open the serial connection at 115200 baud
}

Serial.begin(115200) opens a USB link between the ESP32 and your computer. Without this, the Serial Monitor would stay blank. Think of it as turning on the communication channel.

Step 3: loop() reads → converts → prints → repeats

void loop() {
  // 1️⃣ READ the analog voltage on GPIO 4
  potValue = analogRead(potPin);          // returns 0 .. 4095

  // 2️⃣ CONVERT the raw number to actual voltage (0–3.3 V)
  float voltage = potValue * 3.3 / 4095.0;

  // 3️⃣ PRINT both values to the Serial Monitor
  Serial.printf("Pot: %4d / 4095   (~%.2f V)\n", potValue, voltage);

  // 4️⃣ WAIT 500 ms before the next reading
  delay(500);
}

Key concepts: what each line really does

CodeWhat it does
analogRead(potPin)Measures the voltage on GPIO 4 and returns an integer 0–4095. The ESP32's built-in ADC hardware compares the input voltage to the 3.3 V reference and produces a proportional digital number.
potValue * 3.3 / 4095.0A proportion: if 4095 = 3.3 V, then any reading × (3.3 ÷ 4095) gives the matching voltage. Example: 2048 × 3.3 ÷ 4095 ≈ 1.65 V (exactly half of 3.3 V).
Serial.printf()Prints formatted text to the monitor. %4d = integer, right-aligned in 4 columns; %.2f = decimal number with 2 digits after the dot.
delay(500)Pauses 500 ms (half a second). Without it, the ESP32 would read and print thousands of times per second: too fast to read.

Expected output on the Serial Monitor

==============================================
 Project 2: ESP32 Analog Inputs (ADC)
==============================================
Potentiometer -> GPIO 4
12-bit ADC: 0 = 0 V ... 4095 = 3.3 V
Turn the knob and watch the value change.
----------------------------------------------
Pot:    0 / 4095   (~0.00 V)
Pot: 2047 / 4095   (~1.65 V)
Pot: 4095 / 4095   (~3.30 V)
Try the Serial Plotter (Tools → Serial Plotter, 115200 baud): turning the knob draws a live graph, a great way to see the analog signal change smoothly as you turn.

6 · Understanding the ADC (Non-Linearity)

ESP32 ADC voltage vs reading, non-linear at the ends
Readings flatten near 0 V and 3.3 V: you can't tell ~3.2 V from ~3.3 V.

This matters for precise measurements; for a knob or light sensor it's fine.

7 · Demonstration

Potentiometer on a breadboard with the ESP32
Fully one way → 0 · fully the other → 4095.

8 · Wrapping Up: What You've Learned

In this project you've learned how to read analog inputs using the ESP32 with the Arduino IDE. Here's a summary of the key takeaways:

9 · Troubleshooting

SymptomLikely causeFix
Stuck at 0 or 4095An outer leg not on 3.3 V / GNDRecheck both outer legs
Value jumps randomlyWiper not on GPIO 4Confirm middle leg → GPIO 4
Monitor blank / garbageWrong baudSet it to 115200
Never reaches 4095Normal ADC non‑linearityExpected near the top
← Project 1 · Inputs & Outputs Project 3 · PWM (Analog Output) →