ADC Reading
Quantization, Noise, Averaging, and Sensor Voltage
The robot hand has a small trim knob for grip force. Turn it left and the fingers
should relax. Turn it right and the firmware should command more current. The knob is
not digital. It does not send 42 or 73 over a wire. It makes a voltage.
The ADC is the translator at that boundary. It samples the pin, compares the voltage to a reference range, and returns an integer. That integer feels simple in firmware, but it has a physical past: source resistance, noise, sampling time, reference error, input range, quantization and sometimes a radio stealing the ADC peripheral.
An analog-to-digital converter is not a truth machine. It is a measurement instrument inside your microcontroller. If you treat the ADC number as the sensor, you will chase phantoms in code. If you treat it as a voltage measurement with error bars, the bugs become ordinary engineering.
By the end, you can
- Explain what voltage range, resolution and code mean for an ADC reading
- Compute LSB size, ADC code and reconstructed voltage for an ideal converter
- Explain quantization error without pretending extra decimals are real information
- Use averaging to reduce random noise while naming the response-time cost
- Recognize practical ESP32 ADC traps: ADC1 vs ADC2, attenuation, source impedance, calibration and input limits
- Design a sensor input from the voltage source backward: range, protection, filtering and sampling
The ADC reads a voltage, not a thing
A potentiometer is a good first ADC source because it is honest. The two outside pins connect across a voltage. The middle pin, called the wiper, slides along the resistive track and produces a fraction of that voltage. If the ends are at 3.3 V and ground, the wiper can move from near 0 V to near 3.3 V.
That distinction matters. The same ADC code could come from a knob, a light sensor divider, a battery divider, a pressure sensor output, a thermistor divider or a faulted wire held halfway by leakage. The ADC tells you what voltage was present at sample time. Your circuit and calibration tell you what that voltage means.
For an ESP32-class board, the first safety rule is simple: never drive an ADC pin below ground or above the allowed input range for the selected attenuation. The ADC input is not a power sink. A battery divider, sensor cable or external module needs series resistance, clamps or filtering when the real world can exceed the microcontroller's rails.
Codes are bins
An ideal N-bit ADC divides its full-scale range into integer codes. If the selected
full-scale voltage is Vfs, the largest code is:
For a 12-bit ADC, that top code is 4095. The least significant bit, usually called one LSB, is the voltage represented by one code step:
At 12 bits with a 3.3 V full-scale range:
That is about 0.806 mV per code in the ideal model. A measured voltage becomes a code:
The reconstructed voltage from that code is:
The ADC therefore returns a bin, not a perfect voltage. Every code represents a small range of input voltages. The ideal quantization error is about half an LSB. Printing six decimal places does not make the measurement six-decimal-place true.
A 12-bit ideal ADC uses a 3.3 V full-scale range. Approximately how large is one LSB?
-
Correct. In the ideal model, one code step is full-scale voltage divided by the largest code.
-
3.3 V is the full-scale range, not one step.
-
The number of bits controls the number of steps. It is not a voltage by itself.
-
4095 is a code value, not a voltage.
Quantization is only one error
Quantization gets attention because it is easy to calculate, but it is not always the largest error. Real ADC readings also move because of reference error, thermal noise, power rail noise, source impedance, switch charge injection, sensor noise, nearby radio bursts and board layout.
The input network matters because many ADCs sample onto a small internal capacitor. During the sampling window, the source must charge that capacitor close enough to the real input voltage. A high-value divider, long cable or weak sensor output may not settle fast enough unless you sample more slowly, buffer it, reduce impedance or add a small capacitor at the pin.
On ESP32 boards, the practical notes matter:
- Prefer ADC1 channels when Wi-Fi is active. ADC2 can be unavailable or contested while the radio is running.
- Attenuation changes the input range. It is not a magic precision boost.
- The usable range and linearity are not perfect, especially near the ends.
- Calibration improves voltage estimates, but it does not fix a bad input circuit.
- ADC pins are inputs. They are not GPIO outputs.
Use the widget like a bench instrument
The simulation below shows three traces:
- Gray: the underlying analog voltage.
- Orange: the quantized reading after noise.
- Green: a moving average of recent readings.
Try these moves:
- Drop resolution to 6 bits. The orange trace becomes visibly stair-stepped.
- Raise noise. The reading jumps even when the underlying gray signal is smooth.
- Increase averaging. The green trace steadies, but it lags behind changes.
- Change attenuation. The same physical voltage occupies a different fraction of full scale.
The point is not that averaging is good or bad. Averaging is a trade: it reduces uncorrelated random noise by spreading one answer across several samples, but it also slows the answer. If a robot finger needs to react quickly to a force spike, a huge average window can hide the event you care about.
What is the main cost of increasing a moving-average window from 4 samples to 64 samples?
-
Correct. Averaging smooths random sample-to-sample variation, but it adds lag.
-
Averaging does not change the hardware resolution setting.
-
Voltage range is set by the ADC front end and attenuation, not by the averaging window.
-
Averaging is a software operation after samples are read.
Noise can masquerade as signal
A scope trace makes the warning obvious. The thing moving on screen may be the sensor, but it may also be mains pickup, ground bounce, supply ripple or radio noise. An ADC will happily turn any of those into numbers.
Sampling adds another trap: aliasing. If a signal changes faster than your sample rate can represent, it can reappear as a slower false pattern in your data. That false pattern may look stable and meaningful, which makes it dangerous.
The usual defenses are ordinary:
- Keep sensor wiring short or twisted when it carries high impedance signals.
- Add an RC low-pass near the ADC pin when the signal is slow enough.
- Use a buffer amplifier when the source cannot charge the sample capacitor cleanly.
- Use a proper reference or ratiometric measurement when absolute accuracy matters.
- Sample at a deliberate rate, not just whenever the main loop happens to run.
Why ratiometric sensing can beat absolute voltage accuracy
Suppose a potentiometer is connected between the same 3.3 V rail that the ADC uses as its reference and ground. If the rail is actually 3.25 V today, both the potentiometer top and ADC reference move together. A half-scale wiper still produces about half-scale ADC code. The code tracks ratio, not absolute volts.
This is called a ratiometric measurement. It is useful for potentiometers, bridge sensors and some resistive sensors because the supply error cancels. It does not help when the sensor output is an absolute voltage from a different reference, such as a precision temperature sensor or battery divider.
Design the ADC input backward
A reliable ADC channel starts from the signal you need, not from the line of firmware that reads it.
- What physical quantity matters? Position, light, force, battery voltage, current, temperature or something else.
- What voltage range will arrive at the pin? Include tolerances, faults and startup.
- What source impedance drives the ADC? Check divider values, sensor output impedance and sampling time.
- What noise is plausible? Motors, switchers, Wi-Fi bursts, mains pickup, long cables and shared grounds.
- How fast must the answer change? That sets sample rate, filtering and averaging.
- What accuracy is actually needed? Do not spend bits and calibration effort where the product only needs a rough threshold.
A 12-bit ADC uses a 3.3 V full-scale range. What code should an ideal ADC return for a 1.65 V input?
Show worked solution
The largest code is 4095. Half of 3.3 V is 1.65 V, so the ideal code is half-scale:
A 10-bit ADC uses a 2.2 V full-scale range. What is one LSB, and about how large is the ideal quantization error?
Show worked solution
The largest 10-bit code is 1023.
That is about 2.15 mV per code. Ideal quantization error is about half an LSB, so about 1.08 mV.
You need to measure a 2-cell battery that can reach 8.4 V, but the ADC input must stay within 3.3 V. Propose the first two design checks before choosing exact resistor values.
Show worked solution
First choose a divider ratio that keeps the worst-case battery voltage below the allowed ADC input range, including tolerance and margin. For example, the ratio must be less than about 3.3 / 8.4 before margin.
Second check whether the divider impedance is compatible with the ADC sampling input. Very large resistors save battery current, but the ADC sample capacitor may not settle well and the node becomes easier to disturb. You may need lower resistor values, a small capacitor at the ADC pin, slower sampling or a buffer.
Key takeaways
- An ADC reads voltage at a pin. The circuit around the sensor decides what that voltage means.
- For an ideal -bit ADC, .
- ADC codes are bins. Extra printed decimals are not extra measurement truth.
- Averaging reduces random noise but adds lag; it cannot fix aliasing, bad grounding or a source that cannot drive the sample capacitor.
- On ESP32-class boards, prefer ADC1 with Wi-Fi, choose attenuation deliberately, calibrate when accuracy matters and protect the pin from out-of-range voltage.
ADC work gets easier when you stop asking, "What number did the chip give me?" and start asking, "What voltage did my circuit present, during what sampling window, with what error sources?" That question turns ADC debugging from superstition into measurement.