Analog Input and Signal Processing

ADC resolution and reference, sampling, oversampling and filtering, calibration and scaling, with a thermistor worked through.

What the ADC does

An analog-to-digital converter (ADC) turns a voltage into an integer. An n-bit ADC divides its reference voltage into 2n steps; the size of one step is the LSB (least significant bit). Most microcontrollers use a successive-approximation ADC: a sample-and-hold capacitor captures the input, and a comparator and a digital-to-analog converter home in on the value one bit at a time, in a few microseconds. Others (sigma-delta) trade speed for resolution and noise rejection, and external ADC chips offer 16 to 24 bits for precision sensing.

LSB = Vref ÷ 2n    counts = floor(Vin ÷ LSB)    Vin ≈ counts × LSB

01234567output code0.000.250.500.751.00input voltage as a fraction of V_ref1 LSB8 codes = 2³LSB = V_ref ÷ 8Dashed: idealstraight lineRounded down:error is 0 to1 LSB
A 3-bit ADC for clarity. Each code covers a band of input voltage one LSB wide, so the output is the input rounded down to the nearest step.

Resolution, accuracy and noise

ResolutionReferenceStepsLSBIdeal signal-to-noise (6.02 n + 1.76)
8 bits3.3 V25612.891 mV49.9 dB
10 bits5.0 V1 0244.883 mV62.0 dB
10 bits3.3 V1 0243.223 mV62.0 dB
12 bits3.3 V4 0960.806 mV74.0 dB
16 bits3.3 V65 5360.050 mV98.1 dB

Resolution is not accuracy. Resolution is the number of steps; accuracy is how close each step is to the true value. The real errors are: offset (a reading that is the same amount off at every input), gain error (a slope that is slightly wrong), INL (integral non-linearity: a curve that bends from the straight line) and DNL (steps of unequal size, which can leave missing codes), and noise. Together they usually cost one to three bits: a “10-bit” ADC on a noisy board is good to about 8 or 9 bits. The number of bits that are actually meaningful is the effective number of bits (ENOB), found from the measured noise: ENOB = (SINAD − 1.76) ÷ 6.02.

The reference voltage

Counts are a ratio to the reference voltage, so the reading is only as good as the reference. The choices are the supply (simple, but it moves with the supply), an internal reference (typically 1.1 V, 2.048 V or 2.5 V, accurate to 1 to 2 %) or an external precision reference (0.05 % or better). Where the sensor is ratiometric (a potentiometer, a bridge or a thermistor divider powered from the same supply) use the supply as the reference: the supply error cancels. Where the sensor has its own fixed output (a temperature sensor with 10 mV/°C), use a stable reference.

Worked example: measuring the supply with the internal reference

If the ADC reference is VCC and you measure the internal 1.1 V band-gap reference, then counts = 1.1 ÷ VCC × 1 023, so VCC = 1.1 × 1 023 ÷ counts. A reading of 225 means VCC = 1.1 × 1 023 ÷ 225 = 5.00 V. This needs no extra pin and lets a battery device read its own battery voltage and correct all its other readings.

The source impedance and the sample capacitor

The ADC input charges a small sample-and-hold capacitor (typically 10 to 20 pF) through the sensor’s output impedance and the internal switch. If the source impedance is too high, the capacitor does not charge to the final value in the sample time, and the reading is wrong and depends on the previous channel.

Worked example: does the sample capacitor settle?

  • To settle to within half an LSB of a 10-bit conversion, the capacitor must charge for t = R C ln(2n+1) = R C ln(2 048) = 7.62 R C.
  • A source of 10 kΩ plus 1 kΩ of switch resistance with C = 14 pF needs 7.62 × 11 kΩ × 14 pF = 1.17 µs. With a 125 kHz ADC clock and a sample time of 1.5 clock cycles (12 µs) it settles with margin.
  • A 100 kΩ source needs 7.62 × 101 kΩ × 14 pF = 10.8 µs: barely enough, so either lengthen the sample time, slow the ADC clock, or put a buffer amplifier or a 100 nF capacitor on the pin (a capacitor much larger than the sample capacitor holds the voltage steady and supplies the charge).
  • Leakage: the pin leaks up to about ±1 µA. Through a 50 kΩ source that is an error of 50 mV, which on a 12-bit ADC with a 3.3 V reference (LSB 0.806 mV) is 62 counts. A low-impedance source (under 10 kΩ) avoids both problems.

Battery divider. To read a 4.2 V battery with a 3.3 V ADC, a divider of R1 = R2 = 100 kΩ halves the voltage to 2.10 V but draws 21 µA continuously from the battery (enough to flatten a small cell in a few months) and presents a 50 kΩ source to the ADC. Add a 100 nF capacitor at the ADC pin, or switch the divider on only while measuring.

Sampling rate and aliasing

A signal can be reconstructed only if you sample at more than twice its highest frequency (the Nyquist rate). Frequencies above half the sampling rate are not lost: they fold back (alias) into the band as false lower frequencies. The only cure is to remove them before the ADC with an analog anti-aliasing filter (an RC low-pass), because once sampled the aliases cannot be told from real signals.

Worked example: 50 Hz hum aliasing

A sensor picks up 50 Hz mains hum. Sampled at 60 Hz the hum aliases to |50 − 60| = 10 Hz, which looks like a slow real oscillation in the data. Sampling at 1 kHz keeps the hum at 50 Hz, where a low-pass filter or averaging over a whole number of mains cycles (20 ms at 50 Hz, 16.7 ms at 60 Hz) removes it. Averaging over exactly one mains period is a classic trick: for a slow signal, take 20 samples at 1 kHz (20 ms) and the hum cancels.

  • RC anti-alias filter: fc = 1 ÷ (2π R C): for a 100 Hz cut-off with 1.6 kΩ and 1 µF; set it below half the sample rate and above the signal you want.
  • Sample at a steady rate from a timer interrupt (see Timers, PWM and Timing), not a loop whose speed varies.
  • Take readings in a quiet moment: not while a motor, relay or radio switches.

Averaging, oversampling and filtering

Filtering a noisy ADC signal02040608010002505007501000sample numberADC countsraw samples8-sample moving averageexponential filter, α = 0.15The spike at sample 83 is spread into the averages; a median filter would remove it completely.
A noisy ADC signal with a step and a spike. Both filters reduce the noise and lag the step; the spike leaks into both.
FilterWhat it doesCostBest for
Moving average (N samples)Mean of the last N readings; noise falls as 1 ÷ √NN values of memory; lag of about N ÷ 2 samplesSteady signals with random noise
Exponential (first-order IIR)y += α (x − y)One variable; a few instructionsThe standard choice; tune α to the speed you need
Median (3 or 5 samples)Takes the middle valueA small sortRemoves spikes and outliers without blurring edges
Oversampling and decimationAdds resolution: 4k samples give k extra bitsTime and the right kind of noiseSqueezing 12 bits out of a 10-bit ADC
Median then averageReject the spikes, then average the restSlightly more codeNoisy industrial signals

Worked example: choosing and sizing a filter

  • Exponential filter. With α = 0.15, y += α (x − y): the time constant is τ = −1 ÷ ln(1 − α) = 6.2 samples, and the random noise standard deviation falls by √(α ÷ (2 − α)) = 0.285 (to 28 % of the raw noise). The output settles to 99 % in about 5 τ = 31 samples; at 1 kHz that is 31 ms.
  • Moving average of 8. Noise falls to 1 ÷ √8 = 0.354 (35 %), with a group delay of 3.5 samples. For a similar noise reduction the exponential filter responds more slowly to a step (τ = 6.2 samples), but needs one variable instead of 8.
  • Integer version. With α = 1 ÷ 23 = 0.125 the filter is one shift and one add: y += (x − y) >> 3;, with τ = 7.5 samples. Keep extra bits of fraction in y (for example y in 16.4 format) so that small differences are not lost to rounding.
  • Oversampling. Averaging N = 4k samples and shifting right by k bits gives k extra bits, provided the noise is at least about 1 LSB so that the readings dither between codes. With k = 2, N = 16 samples gives 2 extra bits (a 10-bit ADC reads as 12), at an output rate of 10 000 ÷ 16 = 625 per second from a 10 kS/s ADC.
  • A spike of one wild sample shifts a moving average by (spike ÷ N); a 5-point median ignores it. Use a median when the signal can have glitches.
// Exponential filter in integers: y keeps 4 extra fractional bits
static int32_t y16 = 0;                       // filtered value, scaled by 16
int16_t filter(int16_t x) {                   // x is a raw ADC count
  y16 += ((int32_t)x * 16 - y16) >> 3;        // alpha = 1/8
  return (int16_t)((y16 + 8) >> 4);           // round and drop the fraction
}

Calibration and scaling

The raw count is not yet a measurement. Convert it to engineering units with a straight line, ideally calibrated against two known points to remove the offset and gain errors of the ADC, the reference and the sensor together.

Worked example: two-point calibration

  • A 10-bit ADC with a 5 V reference should read 102.4 counts at 0.500 V and 921.6 counts at 4.500 V. Applying precisely those voltages, it reads 105 and 922.
  • The slope is m = (4.500 − 0.500) ÷ (922 − 105) = 0.004896 V/count (the nominal slope is 0.004883) and the intercept follows from V = 0.500 + m × (counts − 105), so V = 0.004896 × counts − 0.014 V.
  • A reading of 512 counts is then 2.493 V; the uncalibrated formula (512 × 5 ÷ 1 024) would give 2.500 V, an error of 7.3 mV.
  • Store the two constants in non-volatile memory with a checksum (see Memory, Number Formats and Reliability).

Integer scaling without floating point

Multiply first, then divide, in a wide enough type: millivolts = counts × 3 300 ÷ 4 095 needs counts × 3 300 up to 13 513 500, which overflows 16 bits but fits a 32-bit integer, so declare the product uint32_t (on an 8-bit chip, write 3300UL). Round by adding half the divisor first: (counts * 3300UL + 2047) / 4095.

Worked sensor examples

A thermistor with a 12-bit ADC

  • A 10 kΩ NTC (B = 3 950) is the upper resistor of a divider to Vref, with a 10 kΩ resistor to ground. A reading of 2 300 out of 4 095 means RNTC = 10 000 × (4 095 − 2 300) ÷ 2 300 = 7 804 Ω.
  • Beta equation: 1 ÷ T = 1 ÷ 298.15 + ln(7 804 ÷ 10 000) ÷ 3 950, so T = 303.84 K = 30.7 °C.
  • The thermistor is most sensitive near the middle of the ADC range, so choose the fixed resistor equal to the thermistor’s resistance at the middle of the range you need. The sensitivity is about 4 %/°C of resistance, so a 12-bit reading resolves a fraction of a degree. See Temperature Sensors.

A current shunt

A 0.1 Ω shunt in a supply line carrying up to 2 A gives a voltage of I R = 200 mV and dissipates P = I² R = 0.40 W. An amplifier of gain 10 brings full scale to 2.0 V for a 3.3 V ADC (the range ends at 3.3 A; lower the gain for more). The resolution of a 12-bit ADC is then 0.8 mA per count. A smaller shunt wastes less power but gives a smaller signal and more error from offset.

Getting a quiet ADC reading

  • Separate analog from digital: keep analog traces short and away from clocks, PWM and switching supplies; use a ground plane; join analog and digital grounds at one point.
  • Decouple the analog supply and reference with 100 nF and 10 µF capacitors close to the chip, and a ferrite bead or small resistor from the digital supply on chips with a separate AVCC pin.
  • Use ADC noise reduction modes where available: the CPU sleeps during the conversion, removing its digital noise.
  • Avoid changing digital outputs near an ADC pin during a conversion.
  • Shield and twist the wires of sensors that are more than a few centimeters away (see Sensor Outputs and Wiring) and filter at the input.
  • Use a differential input or an external ADC for small signals (bridges, thermocouples): an instrumentation amplifier or a 24-bit sigma-delta chip is the right tool.

Related

FAQ

Why is my 10-bit ADC not accurate to 10 bits?

Resolution is the number of steps; accuracy is how close each step is to the true value. Reference error, offset, gain error, non-linearity and noise typically cost the last one to three bits. Averaging helps noise but not a drifting reference.

Should I average or use a median filter?

Averaging reduces random noise; a median removes isolated spikes. For a signal with both, take a median of three or five samples, then average the results.

Can I get more bits by oversampling?

Yes, if there is enough noise to dither the readings (at least about 1 LSB): 4 times the samples gives 1 extra bit. It does not help if the ADC is quiet, because the readings are then the same code each time.

Why do my readings change when I switch to another channel?

The sample capacitor has not settled from the previous channel because the source impedance is too high. Lower it with a buffer or a capacitor, discard the first reading after a channel change, or lengthen the sample time.

References

  • Microcontroller datasheets and application notes on ADC accuracy, sample time and oversampling (for example Microchip AN-1152 / AVR121 “Enhancing ADC resolution by oversampling”).
  • Horowitz, P. and Hill, W., The Art of Electronics, Cambridge University Press (sampling, aliasing and filters).
  • Texas Instruments and Analog Devices ADC application notes (ENOB, INL and DNL).

Last reviewed: October 2026. Values use common parts and typical specifications: check your own datasheet.