STM32 gotchas
18. ADC readings not as expected

The ADC input, from external circuit's point of view, can be modeled as a cca 6-8pF capacitor, charged to an unpredictible voltage1, switched to the input pin at the moment when software (or ADC hardware in case of some of the "automatic" modes) starts the sampling process. While this capacitor is sometimes labeled as a Sample-and-Hold circuit, it's in fact part of the ADC structure itself; but that's just a matter of terminology, not influencing its outward effect.

This capacitor together with the signal's source impedance and the the switch's ON resistance2 represents an RC circuit with its associated exponential charging process. Whatever is the charge state by the end of sampling period (as specified by software in ADC_SMPRx) will result in the value converted by the ADC. In other words, if the RC circuit is not settled by the end of the sampling period, the read out value will be different from the expected one. This process can be easily seen by observing the ADC input pin using oscilloscope, see e.g. this page (with exahustive explanation, albeit in Russian).

The net effect may be sometimes surprising, for example a signal slowly crossing the mid-range may appear to be "stuck" at a certain level - see "flat" sections inside the circles on this picture from this thread.

Another surprising effect occurs, when the same input signal source is sampled by several ADC channels. For example, ADC1 measures several inputs through its input multiplexer in succession, including one particular signal in question, with settings adjusted to determine their precise value; while ADC2 runs continuously conversions only on that one particular shared input signal, set as an ADC watchdog, in order to react quickly to sudden changes of its value. If ADC2 starts to sample at the moment when ADC1 finishes its sampling phase on that shared signal, the "dip" caused by switching of the ADC2's capacitor severely disturbs the value converted by ADC1; and vice versa. In this case, both ADCs have to be carefully synchronized to avoid this effect.

The most straighforward way to mitigate this effect is to avoid high impedance input source (e.g. voltage dividers with high ohmic value resistors). Amplifiers can be employed to decrease impedance, although they may introduce errors (offsets, drifts) on their own. Another method is to simply increase the sampling time

An often mentioned solution is to add a relatively large capacitor in parallel to the ADC input (large compared to the sampling capacitor, i.e. at around a few nF or higher). While this decreases indeed the source signal impedance at the cost of decreased bandwidth, if the RC constant of this setup is shorter than the sampling period, the capacitor may not be recharged from the primary signal source fast enough and the measured value may be off again; so here the sampling period has to be chosen carefully3

Internal structure and working of STM32 ADC, together with concise guidelines to its usage (including discussion of the effect described here) are detailed in AN2834.


1. Probably VREF+/2. However, the exact working of ADC is unpublished, so proper design has to assume the worst case, i.e. that the initial voltage of capacitor may be at either end of 0-VREF+ range.
2. Value given by datasheet, a few kΩ. This switch is part of the ADC's input multiplexer.
3. Note that there is a difference between sampling time and sampling period. The former is given by setting in ADC_SMPRx register and represents the time while the sampling switch connects the sampling capacitor to input pin. The latter is given by the method how the ADC is triggered, and may be significantly longer, especially if the ADC samples many inputs within its input multiplexer in succession, or if the sampling is sparsely triggered by timer or software.