Skip to main content
Visitor II
September 10, 2024
Solved

STM32G0 ADC issue on Zephyr

  • September 10, 2024
  • 3 replies
  • 2810 views

Problem: ADC reading a battery voltage jump by twice as much when the battery voltage goes from just under 3.55V to anything above (jump is about 1000 in raw adc reading at 12 bits).

Background:

We have a custom board with STM32G0B1CB on which we are trying to measure the battery voltage.

VREF+ pin is tied to VDD which is fed by a DCDC at 3.5V

The battery can go from 2.75 to 4.5V and is fed to channel 1 (PA1) through a 100K : 100K resistor divider giving a max voltage on PA1 of 2.25V.

 

The battery voltage is currently fed from voltage supply that is changed from 2.75V to 4.5V. As mentioned earlier, at around 3.55V the adc reading has a big jump of close to a 1000 raw value at 12 bit which is just baffling. I am trying to get a curve of adc raw value vs. battery voltage and this jump just breaks the pattern.

 

Stratosphere_0-1726003554032.png

 

Here is the zephyr overlay file:

&adc1 {
    #address-cells = <1>;
    #size-cells = <0>;
    vref-mv = <3450>;
    channel@1 {
        reg = <1>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
        // zephyr,oversampling = <4>; gave weird result
    };
};

zephyr currently only supports ADC_GAIN_1 and ADC_REF_INTERNAL.

 

What change (hardware or firmware) do i need to make to get a reliable continuous output from the adc?

    This topic has been closed for replies.
    Best answer by waclawek.jan

    >100K : 100K resistor divider 

    That's too high signal impedance and yes, that can result in such surprising behaviour exactly around VREF+/2.

    See ADC characteristics section in datasheet for maximum allowed input impedance for any  given sampling time.

    JW

    3 replies

    Visitor II
    September 11, 2024

    please also verify what will be the Vref voltage in that case because Zephyr STM32 ADC only allows ADC_REF_INTERNAL, what is the that voltage actually since I need to know that to properly convert the adc raw readings into voltage.

    Stratosphere_0-1726017822065.png

     

    Super User
    September 11, 2024

    >100K : 100K resistor divider 

    That's too high signal impedance and yes, that can result in such surprising behaviour exactly around VREF+/2.

    See ADC characteristics section in datasheet for maximum allowed input impedance for any  given sampling time.

    JW

    Visitor II
    September 11, 2024

    Thank you JW.

    I went through the datasheet as well as the ADC link you posted and indeed need to change the resistor divider value.

    will a 40K: 40K divider be ok or there is a lower recommended divider suggested? trying to prevent leakage current through the divider to get maximum battery life and it is too late to change the circuit at this point.

     

    Stratosphere_0-1726022867538.png

     

    Super User
    September 11, 2024

    What is "VREF_INTERNAL"? Do you refer to something from RM/DS?

    The ADC *always* uses as its reference the voltage on the VREF+ pin (against VREF-, but that in most packages is internally bonded to VSS).

    JW

    Visitor II
    September 13, 2024

    sorry,

    the define in Zephyr is "ADC_REF_INTERNAL".

     

    running calculations as per VREF+ voltage (tied externally to VDD) or 3.5v worked!

     

    Thank you for all the support and help.

     

    The votlage readings make sense now but still fluctuate by 100 mV.

    Also found that 1 second time gap between readings with 100K:100K is still not enough. 2 seconds or more provides more stable readings.