Skip to main content
Graduate
April 23, 2025
Question

STM32H743 ADC values fluctuating after voltage divider

  • April 23, 2025
  • 4 replies
  • 2167 views

I have a +30V -30V input to be fed to STM32H7 ADC 16-bit

I tried using a 2 resistor potential divider using 33K 3.3K ; 1K 100E, 1M 100K, resistor combinations but the output is not correctly read by the ADC. (For 3V input, ADC reads from 2.2V to 3.2V randomly fluctuating) Not constant

But if I bypass the divider circuit and feed an input less than 3.3V to the ADC pin directly, it reads perfectly (For 3V input, it reads 2.9999).

Should sampling time affect the resistor values? 

    This topic has been closed for replies.

    4 replies

    Graduate II
    April 23, 2025

    Random fluctuations should not happen. Check if the power supply of the MCU and the ADC (VDDA) and the reference voltage are stable. What did you measure?
    What happens if you supply a stable voltage from a low impedance source? Such as a 1.2V battery or a bench power supply? Same fluctuations?
    Did you read the datasheet of the MCU? The ADC is not designed for high impedance sources since its sample and hold circuit loads the signal. At least decouple the output of the voltage divider with a capacitor. But preferably use a buffer.
    Did you calibrate the ADC?

    Jonah9VehAuthor
    Graduate
    April 23, 2025

    I tried with an input from GPIO pin of a Nucleo board. Direct input to ADC pin works fine but if checked after the divider it starts getting erratic.

    Made an opamp buffer after divider circuit using general purpose LM358, but still fluctuating. Will try with a precision opamp. 

    How about this divider circuit? Will also try a buffer after this.

    JCAeron_0-1745395568231.png

     

     

    Graduate II
    April 23, 2025

    The divider circuit is not the problem. If the voltage is stable its equivalent circuit is an ideal voltage source with a series resistance. It will be loaded by the ADC so the reading won't be correct, but it should not fluctuate. You already tried a buffer with a unity gain stable OPAMP and that didn't change the result.

    Could you please answer my other questions?

    Super User
    April 23, 2025

    The ADC will never read a constant value, you will always have some noise, at 16 bits at least. But 1 V of noise is excessive.

    You can see general tips on improving accuracy here:

    How to optimize the ADC accuracy in the STM32 MCUs - Application note

     

    > Direct input to ADC pin works fine but if checked after the divider it starts getting erratic.

    Suggests something else at play here.

    How is this set up? On a breadboard with questionable connections? Pictures would help.

    Jonah9VehAuthor
    Graduate
    April 24, 2025

    @TDK @unsigned_char_array 

    • VCC and VDDA are from the same source and is stable as observed. Couldn't check it with any different source.
    • No calibration done. Can it be done before the ADC reads something stable? How to calibrate it? Please help with that.

    An existing PCB is used with wires taken out from those ADC pins and connected to the circuit on a stripboard.

    TI_opa_query.PNG

    VIN_A = 10V from a calibrator source.

    • Multimeter reads a constant 2.172V output after the divider and buffer. Input to ADC is 2.172V.

    This is the read ADC output count with voltage. This trend remains almost the same with or without the buffer.

    CountVoltage
    431722.1739161
    431722.1739161
    429672.16359329
    429672.16359329
    431942.17502403
    431942.17502403
    430532.16792393
    430532.16792393
    428812.1592629
    428812.1592629
    431952.17507434
    431952.17507434
    430822.16938424
    430822.16938424
    431012.17034101
    431012.17034101
    432012.17537642
    432012.17537642
    431182.17119694
    431182.17119694
    430772.16913247
    430772.16913247
    431102.17079425
    431102.17079425
    431122.17089486
    431122.17089486
    431992.1752758
    431992.1752758
    432142.17603111
    432142.17603111
    430832.16943455
    430832.16943455
    430332.16691685
    430332.16691685
    430462.16757154
    430462.16757154
    430382.16716862
    430382.16716862
    431882.17472172
    431882.17472172
    431452.17255664
    431452.17255664
    431722.1739161
    431722.1739161
    430852.1695354
    430852.1695354
    430082.165658
    430082.165658
    431672.17366433
    431672.17366433
    429692.16369414
    429692.16369414
    431292.17175102
    431292.17175102
    429782.16414738
    429782.16414738
    429712.16379476
    429712.16379476
    431452.17255664
    431452.17255664
    432312.17688704
    432312.17688704
    430072.16560769
    430072.16560769
    430972.17013955
    430972.17013955
    430972.17013955
    430972.17013955
    431232.17144871
    431232.17144871
    432002.17532611
    432002.17532611
    431192.17124748
    431192.17124748
    431422.17240548
    431422.17240548
    430342.16696739
    430342.16696739
    430142.16596031
    430142.16596031
    431212.17134809
    431212.17134809
    430262.16656446
    430262.16656446
    431612.17336226
    431612.17336226
    431232.17144871
    431232.17144871
    431232.17144871
    431232.17144871
    429752.16399622
    429752.16399622
    431092.17074394
    431092.17074394
    430702.16878009
    430702.16878009
    431662.17361403
    431662.17361403
    430852.1695354
    Graduate II
    April 24, 2025

    I noticed a few things.
    First off all I see a lot of duplicate values. Are you sure each data point is one sample or are you saving the values faster then they are sampled?

     

    plot of countsplot of counts

     

    The histogram (bin size 16 counts) doesn't look particularly like Gaussian (noise).

    histogram of counts (bin size 16 counts)histogram of counts (bin size 16 counts)

    Perhaps there aren't enough samples to conclude this. But in my experience you should see noise levels of 1 or maybe 2 counts. This spread of 350 counts is way too large!

    FFT doesn't show any particular frequency stand out, but there are not enough samples to be sure of this.

     


    @Jonah9Veh wrote:

    @TDK @unsigned_char_array 

    • No calibration done. Can it be done before the ADC reads something stable? How to calibrate it? Please help with that.

    If you use LL you need to call LL_ADC_StartCalibration().

    Example:

    	LL_ADC_Disable(ADC1);
    	LL_ADC_SetChannelPreSelection(ADC1, LL_ADC_CHANNEL_16);
    	LL_ADC_StartCalibration(ADC1, LL_ADC_CALIB_OFFSET_LINEARITY, LL_ADC_SINGLE_ENDED);
    
    	/* Wait for calibration completion */
    	while (LL_ADC_IsCalibrationOnGoing(ADC1) != 0UL)
    	{
    		;
    	}
    	LL_ADC_Enable(ADC1);
    
    	while ((ADC1->ISR & ADC_ISR_ADRDY) != ADC_ISR_ADRDY);// On this STM32 series, after ADC enable, a delay for ADC internal analog stabilization is required before performing a ADC conversion start.
    	LL_ADC_REG_StartConversion(ADC1);

     

    For HAL you need to call HAL_ADCEx_Calibration_Start().

     

    @Jonah9Veh wrote:

    @TDK @unsigned_char_array 

    An existing PCB is used with wires taken out from those ADC pins and connected to the circuit on a stripboard.


    How long are the wires?

     


    @Jonah9Veh wrote:

    @TDK @unsigned_char_array 

    • Multimeter reads a constant 2.172V output after the divider and buffer. Input to ADC is 2.172V.

    A multimeter on voltage mode reads a DC voltage. It doesn't measure noise or ripple. You need an oscilloscope for that.

     

    Explorer
    April 24, 2025

    @Jonah9Veh wrote:

    But if I bypass the divider circuit and feed an input less than 3.3V to the ADC pin directly, it reads perfectly (For 3V input, it reads 2.9999).

    ADC can output stable results only if its saturated...

    Internal ADC are always noisy, especially when Reference voltage has no Vref- differential part.

    Just do oversampling & averaging

    Graduate II
    April 24, 2025

    @MasterT wrote:

    @Jonah9Veh wrote:

    But if I bypass the divider circuit and feed an input less than 3.3V to the ADC pin directly, it reads perfectly (For 3V input, it reads 2.9999).

    ADC can output stable results only if its saturated...


    Exactly.

     


    @MasterT wrote:

    Internal ADC are always noisy, especially when Reference voltage has no Vref- differential part.

    Just do oversampling & averaging


    Not that noisy! 350 counts between max and min. That's a lot.
    I disagree with averaging something that noisy. The source of the noise needs to be fixed first. Then the remaining noise (1-2 counts) can be averaged to reduce noise and optionally increase resolution.

    Explorer
    April 24, 2025


    @MasterT wrote:

    Internal ADC are always noisy, especially when Reference voltage has no Vref- differential part.

    Just do oversampling & averaging


    Not that noisy! 350 counts between max and min. That's a lot.
    I disagree with averaging something that noisy. The source of the noise needs to be fixed first. Then the remaining noise (1-2 counts) can be averaged to reduce noise and optionally increase resolution.


    1-2 count? Sure you never tested internal stm32 adc. 7 LSB (+-128 "counts") is a Normal for 16-bits H7. Depends on  uCPU package, I played with nucleo boards, 144 pins, but ST says BGA IC have better ADC performance.

    Explorer
    April 24, 2025

    > Should sampling time affect the resistor values? 

    Yes, sampling is affected by input resistance.

    I don't know what method your MCU uses is based upon, presumably successive approximation.
    For this type, the input voltage charges the S&H capacitor for the selected sampling time, then the capacitor is switched to the internal conversion circuitry.
    If the input voltage can't charge it fully up - either because the sampling time is too short, the input impedance is too high, or both - you get incorrect voltage. And, if you convert multiple channels, you get "bleed over", i.e. interference with subsequent channels.

    Check the datasheet carefully, if the proper conditions are met.
    A buffer amplifier is recommended for such instances.