Voltage divider on Nucleo STM32L452RE bad accuracy

What are you developing?
Post Reply
brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

Voltage divider on Nucleo STM32L452RE bad accuracy

Post by brixton »

Hello all,

I have an STM32L452RE Nucleo 64 board with voltage divider. See schematic.
voltage divider schematic
voltage divider schematic
Gallery_1692892464589 (2).jpg (32.23 KiB) Viewed 4504 times
The output should be 3.3 Volts, but instead it is steadily 3.25 V. Does anyone have an idea where I might be going wrong?
Page 154 of the datasheet mentions that the "Internal sample and hold capacitor" for the capacitor has a capacitance of 5 pF. Thought that might be relevant.
N.B. the rather large values for the resistors is for low power application, and the capacitor is to make up for the low current that results from this.

Code: Select all

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200); 
  
}

void loop() {
  // Calculate the voltage of the voltage divider
  Serial.print(analogRead(PC4)*(3.3/1023.0)*(4.7+2.2)/2.2); 
  Serial.print(" V, "); 
  Serial.println(analogRead(PC4)); 
  
  delay(100); 

}

output:

Code: Select all

17:59:10.945 -> 3.25 V, 321
17:59:11.038 -> 3.25 V, 321
17:59:11.163 -> 3.25 V, 321
17:59:11.255 -> 3.25 V, 321
17:59:11.333 -> 3.25 V, 321
17:59:11.457 -> 3.25 V, 321
17:59:11.550 -> 3.25 V, 321
17:59:11.645 -> 3.25 V, 321
17:59:11.738 -> 3.25 V, 321
17:59:11.862 -> 3.25 V, 321
17:59:11.954 -> 3.25 V, 321
17:59:12.065 -> 3.25 V, 321
17:59:12.155 -> 3.25 V, 321
17:59:12.248 -> 3.25 V, 321
17:59:12.340 -> 3.25 V, 321
17:59:12.466 -> 3.25 V, 321
17:59:12.560 -> 3.25 V, 321
17:59:12.654 -> 3.25 V, 321
17:59:12.748 -> 3.25 V, 321
17:59:12.841 -> 3.25 V, 321
17:59:12.965 -> 3.25 V, 321
17:59:13.058 -> 3.25 V, 321
17:59:13.152 -> 3.25 V, 321
17:59:13.246 -> 3.25 V, 321
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: Voltage divider on Nucleo STM32L452RE bad accuracy

Post by ag123 »

if it is 3.3v, you can try to measure it directly,

you may like to check your resistors.
there can also be rounding errors in the calculations, there may be other possible sources of errors etc.
and that the voltage supplied may be lower than 3.3v after all, there would be voltage drops even with low resistance mosfets quite common in LDOs, and if it uses regular transistors the dropout voltages would be even larger to the extent of 1v dropout and beyond.
and that normally, for 12 bits the top of the range is 4096, sometimes measurements won't reach there, due to various electrical limits, voltage drops etc.
and that we normally assume the range is linear, there can be variances.
https://www.st.com/resource/en/applicat ... ronics.pdf
this may not be for stm32, but may be interesting reading
https://www.st.com/resource/en/applicat ... ronics.pdf

oh and radio waves that the stm32 adc can detect on the wire, can easily exceed 10 mV
viewtopic.php?p=8524#p8524
stm32's adc is very sensitive and if you place a long enough wire (e.g. even a resistor lead) it becomes an antenna and stm32 adc can read that as like a SDR (software defined radio)
GonzoG
Posts: 403
Joined: Wed Jan 15, 2020 11:30 am
Answers: 27
Location: Prudnik, Poland

Re: Voltage divider on Nucleo STM32L452RE bad accuracy

Post by GonzoG »

1. Are you sure, the input voltage is exactly 3.3V ??
2. Are you sure that those resistors are exactly 4.7M and 2.2M ?
ozcar
Posts: 143
Joined: Wed Apr 29, 2020 9:07 pm
Answers: 5

Re: Voltage divider on Nucleo STM32L452RE bad accuracy

Post by ozcar »

With less than 500nA through the resistors, have you checked the input leakage current specifications?
brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

Re: Voltage divider on Nucleo STM32L452RE bad accuracy

Post by brixton »

Thanks for all the suggestions!
ag123 wrote: Thu Aug 24, 2023 4:36 pm if it is 3.3v, you can try to measure it directly,
I'm using 3.3 V only as a testing voltage. The intention is to measure higher voltages. But that aside, if I try that then I get a solid analog output of 1023 which is perfect. Converting that to voltage will obviously yield 3.3 V.

GonzoG wrote: Thu Aug 24, 2023 8:35 pm 1. Are you sure, the input voltage is exactly 3.3V ??
2. Are you sure that those resistors are exactly 4.7M and 2.2M ?
No I'm not.. just measured it. We have:
The 4.7 MOhm is actually 4.74, the 2.2 MOhm is actually 2.18, and the voltage that I'm measuring (the 3.3 V output from Nucleo) is actually 3.32 V.

When I replace the resistance values, we get
Vin = 321*(3.3/1023.0)*(4.74+2.18)/2.18 = 3.29 V, which is already a whole lot better but not spot on.
Now I'm not sure whether I should then also update the 3.3 V reference voltage with 3.32 V since that will then be the actual reference point for the ADC output..? If so then we get
Vin = 321*(3.32/1023.0)*(4.74+2.18)/2.18 = 3.31 V, which is better again but still does not match the 3.32 V.

So that brings me to two new questions:
1. if using such a voltage divider circuit for multiple PCB's, how do you ensure consistency? Measure the actual resistance values prior to uploading code, and then hardcode the individual resistor values into the Arduino program for each PCB? I.e. calibration. Seems a bit cumbersome.. Or find super low error resistors?
2. Same question for the 3.3 V reference voltage of the nucleo. Is there a way for the nucleo to determine that? Or should I use a multimeter (like I did now)? And my guess is that this 3.3V reference voltage will also change over time, making the situation even harder..

ozcar wrote: Thu Aug 24, 2023 10:33 pm have you checked the input leakage current specifications?
I have not.. I'm not very familiar with that concept so will have to look into it.
ag123 wrote: Thu Aug 24, 2023 4:36 pm oh and radio waves that the stm32 adc can detect on the wire, can easily exceed 10 mV
So far my measurements are very constant (precise), no fluctuations as shown on the serial monitor output. With radio waves I would expect more fluctuating/intermittent deviations, correct?
hobbya
Posts: 49
Joined: Thu Dec 19, 2019 3:27 pm
Answers: 1

Re: Voltage divider on Nucleo STM32L452RE bad accuracy

Post by hobbya »

The internal resistance of common multi-meter is around 10M and can affect voltage measurement if you choose high values for the potential divider.
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: Voltage divider on Nucleo STM32L452RE bad accuracy

Post by ag123 »

among the things, you may like to try using lower resistances e.g. between 10k to 100k ohms,
with those 'meagohm' resistances, note that there are 'invisible' scattered capacitances (even for that matter a finger touch would have capacitance), and that alone can significantly increase the time to reach the stable sampling voltages at the adc input, it is simple RC circuit
https://en.wikipedia.org/wiki/RC_circuit
in fact, I think the ADC practically needs pretty high currents like in the milliamp ranges for 'normal' sample rates up to the maximum possible in configuration. And if you insist on those megaohm resistances, you may want to try to increase sample time to the maximum possible like 300 clock cycles on the adc clock for those high resistances and in fact, you may need to add an op amp as a buffer so that it can deliver milliamps level impedances to the adc if you desire those accurate readings.

I've in cases use an opamp before the ADC, and that alone tend to improve the accuracy, because the op amp tend to be able to drive loads in the 10s of milliamps, that practically ensure that the ADC will read an accurate voltage instead of waiting for the RC levels to reach the plateau.

and if you are measuring 3.3v, you may like to measure it directly if that is your voltage reference, i.e. direct, no resistance etc.
that would give you a feel of how 'accurate' the adc is, and 3.3v being the upper limit (do not go above that).
what i tend to think is that there are also some other circuits such as the channel multiplexer, and gpio circuits etc, there may be some electrical limits to read votages near VDD, probably deemed a 'common mode' voltage.

if you played with op amps, many 'generic' op amps have a CMRR that is no more than about 0.7 VCC, and if both inputs are above 0.7 VCC, there would be no way for the op amp to effectively remove common mode voltages, that is just physical limits. I'd think quite similarly, there would be physical limits to measure close to VDD. measuring VDD 3.3v at the adc is also the upper range of the limit, hence, that would give you the top of range reading from the ADC. if you prefer, you can consider that number you read say 1022 instead of 1023 as the value of what you read say 3.3v.

And we normally assume that adc ranges are linear, but I think i've read some app notes somewhere that due to practical real world fabrication limits, it is unlikely you get that perfectly linear readouts and if you do get that, it is likely you got lucky (got a good piece) or that the processors are literally binned so as to select the 'top notch' ones to sell at a premium, intel, amd etc does that to sell 'overclockable' chips for a high premium.
GonzoG
Posts: 403
Joined: Wed Jan 15, 2020 11:30 am
Answers: 27
Location: Prudnik, Poland

Re: Voltage divider on Nucleo STM32L452RE bad accuracy

Post by GonzoG »

brixton wrote: Fri Aug 25, 2023 8:01 am
So that brings me to two new questions:
1. if using such a voltage divider circuit for multiple PCB's, how do you ensure consistency? Measure the actual resistance values prior to uploading code, and then hardcode the individual resistor values into the Arduino program for each PCB? I.e. calibration. Seems a bit cumbersome.. Or find super low error resistors?
2. Same question for the 3.3 V reference voltage of the nucleo. Is there a way for the nucleo to determine that? Or should I use a multimeter (like I did now)? And my guess is that this 3.3V reference voltage will also change over time, making the situation even harder..
0.01V isn't a big error.

1. Using ultra precise resistors and lower resistances.
1a. not using basic voltage dividers but ultra precise voltage dividers. Those are ICs that are very, very precise.
1b. calibration - write a code so you can use calibration data, then store it in eeprom or flash. Once board is finished and firmware uploaded you can calibrate it and you'll have precise measurments.

2. Calibration once more.
2a. Using external (or internal, which is less precise) precise voltage reference. By measuring it (a known, precise value) you can calculate STM32's ADC reference.
eg. you have 1V reference and you got 312 reading -> ADC Vref = Vref_ex * 1023 / Vread = 1 * 1023 / 312 = 3.2788 V.
There is an internal voltage reference in most (if not all) STM32 MCUs. You can measure it. STM's example how to read internal Vref: https://github.com/stm32duino/STM32Exam ... annels.ino

If you want very precise measurements, you have to account for change of resistance with temperature change and few other factors.
If you don't need to measure voltage very often, it's better to use mosfet and much lower value resistors.
brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

Re: Voltage divider on Nucleo STM32L452RE bad accuracy

Post by brixton »

okay thanks for all the help, I really appreciate it.

I've tried the below sketch. That makes the situation significantly better.
GonzoG wrote: Fri Aug 25, 2023 4:35 pm There is an internal voltage reference in most (if not all) STM32 MCUs. You can measure it. STM's example how to read internal Vref: https://github.com/stm32duino/STM32Exam ... annels.ino
I'll consider how to proceed on the voltage divider and next steps in light of what you said about the external IC's.

I also have a very related but somewhat different question, but I'll post that as a different question (and perhaps leave a link to it here).
Post Reply

Return to “Projects”