cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G0 ADC issue on Zephyr

Stratosphere
Associate II

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?

1 ACCEPTED SOLUTION

Accepted Solutions

>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

View solution in original post

7 REPLIES 7
Stratosphere
Associate II

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

 

>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

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

 

You can use high value of resistors, 100k - 1M just put a capacitor in parallel with lower leg, 0.1uF.  And make sampling not very often , to allow RC time to settle down 0.1%, once in 1 sec should be fine.

great, thank you for the help!

I will test today.

 

btw, just to confirm, what would the VREF_INTERNAL voltage be in this case since VREF+ is tied to VDD ?

 

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

Stratosphere
Associate II

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.