cancel
Showing results for 
Search instead for 
Did you mean: 

Getting wrong ADC readings

sal92
Associate

Split from:

https://community.st.com/t5/stm32-mcus-embedded-software/how-to-use-analogue-pins-not-adc-to-read-voltage/td-p/792208

Please keep to one question per thread.


Hi,

 

One more related question, I have changed the pins and now i am reading the voltage but all the pins are giving me a voltage of 1.7v while my actual value is 1.2-1.4v. I use Vref internal 3v.

 

Can anyone guide me what i am doing wrong?

I think it has to do with the value of my Vref 

How to use the STM32 ADC's internal reference volt... - STMicroelectronics Community

I have read this but its not sufficient.

 

I just have a simple question in order to read any voltage value under 3v what Vref internal i shoul use?

 

Thanks in advance !

3 REPLIES 3
Sarra.S
ST Employee

Hello @sal92

According to your product datasheet, the internal reference voltage (VREFINT) for the STM32F733xx is typically 1.21 V, with a minimum of 1.18 V and a maximum of 1.24 V. 

SarraS_0-1746529133277.png

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

TDK
Guru

Load a CubeMX example project that shows how to use the ADC, or show your work.

If you feel a post has answered your question, please click "Accept as Solution".

@sal92 wrote:


How to use the STM32 ADC's internal reference volt... - STMicroelectronics Community


So I assume you calibrate the ADC during startup as mentioned in the article. The article also mentions compensating the error in VREF+ by measuring the internal reference voltage using VREF+.
Additionally you need to make sure your signal source impedance is not too high and your ADC is not clocked too high (prescaler and sample time). The datasheet lists what sampling rate is acceptable for what source impedance. You can also use a buffer.

 

 

@sal92 wrote:

i am reading the voltage but all the pins are giving me a voltage of 1.7v while my actual value is 1.2-1.4v. I use Vref internal 3v.


 

The internal reference voltage is not perfect. But it has been characterized in factory at a specific VREF+ voltage. You can use this to measure your actual VREF voltage. These values are stored in ROM.
ST has defined macros to access these ROM values in *ll_adc.h:

#define VREFINT_CAL_ADDR                   ((uint16_t*) (0x1FF1E860UL)) /* Internal voltage reference, address of parameter VREFINT_CAL: VrefInt ADC raw data acquired at temperature 30 DegC (tolerance: +-5 DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */

#define VREFINT_CAL_VREF                   (3300UL)     

Not all MCUs use the same calibration voltage so it is recommended to use both these macros (or use the HAL functions)


I recommend writing an init function that reads this ROM value once and uses it to create a multiplication value. You can combine this with the ADC full_scale value of 2^N-1 to create a multiplier.
Example:

resolution N = 12 bit
FULL_SCALE = 2^12-1 = 4095 counts
VREFINT_CAL_VALUE = 1531 counts
VREFINT_CAL_VREF (VREF+ during calibration) = 3300 mv

This means the internal reference voltage in this case is about:
VREFINT_CAL_VREF * VREFINT_CAL_VALUE / FULL_SCALE = 3300 mV * 1531 / 4095 1234 mV

init:
multiplier = VREFINT_CAL_VALUE * VREFINT_CAL_VREF = 5052.3


measure:
vrefint channel counts (you need to measure this every time in case your VREF+ drifts or changes) = 1605
channel 1 counts = 2000
calc:
vref+ = multiplier / vrefint channel counts = 3.14785 V
channel 1 voltage = channel 1 counts * vref+ * (1.0f/FULL_SCALE) = 2.026V


 

 

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.