ADC Reading
Quantization, Noise, Averaging
Why it matters
Sensors are analog. The ADC is how your ESP32 reads knobs, light, temperature, battery voltage, and more.
The idea
The core idea
An ADC converts a voltage into an integer code. More bits → smaller steps, but noise can still dominate.
flowchart LR
V[AnalogVoltage] --> Sample[Sample]
Sample --> Q[Quantize]
Q --> Code[DigitalCode]
Code --> Avg[Average]
ESP‑WROOM‑32 notes
- ADC1 works alongside Wi‑Fi. ADC2 is often blocked when Wi‑Fi is active.
- Input range depends on attenuation (0dB..11dB).
- ADC pins are input-only — great for sensing, not for outputs.
Mini-lab
Add noise, then increase averaging. You should see a more stable reading — but with more lag.
Demo
Gray is the underlying analog signal. Orange is the quantized ADC result. Green is a moving-average filter.
Reduce bits to see bigger steps. Increase noise to see jitter. Increase averaging to smooth jitter. Change attenuation to change full-scale range (Vfs).
Key takeaways
- Quantization turns continuous voltage into discrete codes
- Noise can dominate; averaging reduces noise at the cost of responsiveness
- On ESP32: prefer ADC1 when using Wi‑Fi
- Attenuation changes measurable voltage range (Vfs)
Going deeper
Real ESP32 ADC readings can be non-linear, especially at high attenuation. For better results: use calibration (if available), limit input impedance, and average multiple samples. For battery sensing, use a divider and keep max voltage below 3.3V (and within chosen attenuation range).
Math details
Let Vfs be full-scale voltage and N be bits:
levels = 2^N - 1
code = round( (V / Vfs) * levels )
V_quantized = (code / levels) * Vfs
Quantization error (ideal) is about ±0.5 LSB.
Implementation
LLM Prompt: ADC Reading
Write Rust code for ESP32 ADC reading using esp-hal.
Configure: ADC1 channel, attenuation (11dB for 0-3.3V), sample averaging (8 samples).
Include function to read voltage (convert ADC code to volts).
Handle ADC2 limitation (blocked when Wi‑Fi active).
Lab Exercise
- Connect potentiometer: 3.3V → pot → GND, wiper to ADC pin
- Configure ADC: 12-bit, 11dB attenuation
- Read ADC value and convert to voltage
- Add averaging (8 samples) — observe reduced noise
- Rotate potentiometer — verify linear response