ADC & Reading Sensors
One genuine ESP32 advantage over a Raspberry Pi is built-in analog input. A Raspberry Pi has no analog input pins at all - every GPIO pin is purely digital (on/off), so reading something like a potentiometer or an analog sensor normally requires an external ADC chip. The ESP32, by contrast, has real analog-to-digital conversion (ADC) built directly into the chip.
ADC1 vs ADC2
The ESP32 has two ADC blocks: ADC1 with 8 channels and ADC2 with 10 channels. Functionally they both convert an analog voltage into a digital reading, but there is an important practical difference between them.
| ADC Block | GPIO Pins |
|---|---|
| ADC1 (8 channels) - safe with Wi-Fi | GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, GPIO37, GPIO38, GPIO39 |
| ADC2 (10 channels) - not usable while Wi-Fi is active | GPIO0, GPIO2, GPIO4, GPIO12, GPIO13, GPIO14, GPIO15, GPIO25, GPIO26, GPIO27 |
Notice ADC1 lines up exactly with the four input-only pins from the GPIO Pinout & Restrictions lesson (GPIO34, 35, 36, 39) plus GPIO32/33/37/38 - a convenient overlap, since an analog sensor reading never needs to drive the pin as an output anyway. Also notice GPIO0, 2, and 15 appear in both the ADC2 list and the strapping-pin list - one more reason to prefer ADC1 for a sensor project.
Reading a Potentiometer with analogRead()
A potentiometer is a simple variable resistor, commonly wired with its two outer legs to 3.3V and GND and its middle wiper leg to an ADC-capable pin - turning the knob changes the voltage the wiper reports, anywhere between roughly 0V and 3.3V. The example below uses GPIO34, one of the eight confirmed ADC1 pins from the table above - safe to read alongside Wi-Fi, and since GPIO34 is also input-only, there's no risk of accidentally configuring it as an output elsewhere in your code.
const int SENSOR_PIN = 34; // ADC1, input-only - confirmed safe alongside Wi-Fi
void setup() {
Serial.begin(115200);
}
void loop() {
int reading = analogRead(SENSOR_PIN);
Serial.println(reading);
delay(200);
}
analogRead() on the ESP32 returns a value with 12-bit resolution, meaning
the raw reading ranges from 0 to 4095 - 0 representing roughly 0V and 4095 representing
roughly the ADC's reference voltage. You can scale that raw range to whatever real-world unit your
sensor measures (degrees, percentage, and so on) in your own code.
The Other Direction: DAC Output
ADC reads an analog voltage in. The ESP32 also has the reverse capability: 2 DAC (digital-to- analog converter) channels, on GPIO25 and GPIO26 specifically, with 8-bit resolution, which can output an actual analog voltage rather than just a fast on/off PWM approximation of one. This is a distinct concept from ADC input and is useful when a project genuinely needs a smooth analog output signal rather than a digital one.
analogRead()
returns a 12-bit value (0-4095). Readings are less accurate near the very top/bottom of the range. DAC
output (true analog voltage out) lives on GPIO25 and GPIO26.