Showing results for 
Search instead for 
Did you mean: 

STM32 ADC DMA low raw/Voltage readings

Associate III

I am experiencing the following problem. When I setup an ADC with DMA for 5 channels, occasionally I get lower readings than the expected ones. It also happens in some of our hardware of our production, but others perform ok. We have inspected the components and everything seems identical. We have measured the reference voltage and all the expected voltages on ADC input pins (some are fixed and known) and all looking good too. On the other hand, when I sample only one ADC channel in polling mode, I do not get this problem, the voltages read as expected.
Here is the ADC configuration with DMA (source code attached too):






Accepted Solutions

> ADCrefINT== 379

Assuming that was taken as 10-bit measurement, after calibration (i.e. the ADC is already "true"). That then can be used to calculate the real VREF+ voltage:

3.0V * (1668 / 4096) / (379 / 1024) = 3.301V


View solution in original post


> occasionally I get lower readings than the expected ones

Try to elaborate.

How is VREF+ connected?


Associate III

The Vref+

Regarding the readings a healthy ADC reading at 10-bit resolution should read something like 914 raw value which will correspond to 3652mV for the battery voltage, as opposed to the lower reading which will be something like 837 raw value which corresponds to 3346mV for the battery voltage.

And what does "occasionally" here mean, exactly?

a) that on a particular board, most of the readings are 914 raw, and once in a time there's a 837 reading? If so, can you quantify "once in a time"? More precisely, you should try to relate it to some other event (e.g. activating a high-current peripheral).

b) that on most boards all readings are 914 raw, but on a few boards all readings are 837? If so, you should try to find what is common to "failing" boards and different to "non-failing" boards; try to think out of the box, e.g. cable arrangement.


It is a little bit hard to quantify. We run some tests and we noticed that we get failures due to voltage and current measurements were lower than the pre set thresholds in the firmware. Those failures are happening occasionally.

We have PCBs of the same batch in 3 countries, but only the ones tested in China are failing. At all times the ADC readings read lower than the expected values for all the ADC channels (I think this is were we need to focus, since it is a constant behaviour), but the PCBs at the other countries return the expected reading in all channels. All those PCBs are identical and they are driving small motors, have a keypad, have some LEDs UI, and a UART debugging port were we connect a USB to TTL UART cable. Maybe we can test this last connection if any power from the PC USB port is messing up anything?

Besides those issues which make sense to point to a hardware difference, is the software used correctly in terms of reading the ADC?

Why the polling method doesn't cause this issue? I tried to sample only one channel to see what am I getting but it makes the firmware crashing. I tried to use the same channel in all those 5 scannings, but same the firmware is crashing. Why running a single channel in DMA makes the firmware crashing?

This is hard to judge without knowing the intimate details.


I have posted the source code, the cube mx configuration, the schematic, the test results. Am I missing something?

The rest of code (including Cube, the compiler, particular settings of it), the rest of schematics, the hardware to which it is connected, PCB layout...

I have had a glance at the code and can't see anything obvious. I also don't use Cube.

Sometimes it happens that a problem can be discovered by having a short look at some snippet of code, but more often than not, it's ultimately up to the user to find the problem, we can perhaps give better of worse clues.

Common denominator of many ADC-related problems is too high signal impedance/too short sampling period, crosstalk/interference (often related to improper grounding/return arrangement), unstable reference.


1) I have tested the sampling rate by instead of having continues DMA requests, introducing a timer with parameters to set it to the maximum interval (prescaler 65535, clock division 4) as follows, without any difference in readings:
a)Trigger the ADC with DMA from init() function
b)On conversion complete callback start the timer with interrupt
c)On timer callback restart the ADC with DMA
2) We have measured the 3V3 reference voltage and check for noise in the oscilloscope
3) Not sure what we can check with the ground apart from continuity and noise in the oscilloscope
4) Regarding the impendence, again I am not very familiar on how to measure or adjust this, but I suppose in the circuit I posted with fixed resistor values it should be straight forward to work it out right? Are other parts of the circuit affecting this impedance value?



You've said that the problem is with battery voltage measurement, yet you're showing schematics for measurement on a divider not related to battery.

Read AN2834.