← all lessons
Microcontrollers · #10 of 48

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

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).

— analog — quantized — averaged

Key takeaways

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

  1. Connect potentiometer: 3.3V → pot → GND, wiper to ADC pin
  2. Configure ADC: 12-bit, 11dB attenuation
  3. Read ADC value and convert to voltage
  4. Add averaging (8 samples) — observe reduced noise
  5. Rotate potentiometer — verify linear response

full glossary →