Skip to main content
Yuval Klein
Associate
February 13, 2018
Solved

ADC does not read voltage linearly

  • February 13, 2018
  • 7 replies
  • 2119 views
Posted on February 13, 2018 at 16:09

Hi,

I using STM32F103 and I'm measuring voltage on PB1 (AIN9) using ADC1.

As seen in the table below the ADC readouts in 1.59V and 1.34V are basically the same. It seems the turn point is around 1.49V.

Can anyone help please.

AIN9 (V)ADC Value

1.1922185

1.2192140

1.2712100

1.3052060

1.3412030

1.3782010

1.3852000

1.43031965

1.4351930

1.4811895

1.4821880

1.5031880

1.511900

1.5962030

1.7322290

1.8612545

#stm32f103 #adc
This topic has been closed for replies.
Best answer by Yuval Klein
Posted on February 14, 2018 at 16:30

I fond the problem, my Vdd was dropping as well and in faster rate then the voltage in the Ain. I solved it by measureing the VrefInt and using it as a reference to the ADC measurement. 

Thank you everyone for the help. 

7 replies

raptorhal2
Lead
February 13, 2018
Posted on February 13, 2018 at 16:56

All the lower voltages conversion values are wrong.

What is the sampling time for each sample in cycles?

What is the signal source impedance?

Cheers, Hal

Yuval Klein
Associate
February 13, 2018
Posted on February 13, 2018 at 17:35

This is the code I'm using to initiate the ADC:

/* Configure PB.00 and PB.01 (Channel8 and Channel9) as analog input -----*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_Init(GPIOB, &GPIO_InitStructure);

/*Battery ADC Init*/

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

ADC_InitStructure.ADC_ScanConvMode = DISABLE; //ENABLE;

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStructure.ADC_NbrOfChannel = 1;

ADC_Init(ADC1, &ADC_InitStructure);

/* ADC1 regular channels configuration */

ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_239Cycles5);

/* Enable ADC1 */

ADC_Cmd(ADC1, ENABLE);

/* Enable ADC1 reset calibration register */

ADC_ResetCalibration(ADC1);

/* Check the end of ADC1 reset calibration register */

while(ADC_GetResetCalibrationStatus(ADC1));

/* Start ADC1 calibration */

ADC_StartCalibration(ADC1);

/* Check the end of ADC1 calibration */

while(ADC_GetCalibrationStatus(ADC1));

/* Start ADC1 Software Conversion */

ADC_SoftwareStartConvCmd(ADC1, ENABLE);

I'm measuring a 9 volt battery in the real device, during the test above I've used a very accurate power supply. The goes through a voltage divider. The measurements above are taking from the pin on the MCU.

waclawek.jan
Super User
February 13, 2018
Posted on February 13, 2018 at 18:21

VREF+/VREF-/VSSA/VDDA connection problem?

JW

raptorhal2
Lead
February 13, 2018
Posted on February 13, 2018 at 18:16

Sampling time is max, so that is not the problem.

I suspect you have a ground loop problem between the MCU and the power supply. I presume the 9V battery is grounded to the MCU board, so try using the battery with test voltage dividers as a signal source and see if the conversions are correct.

Cheers, Hal

T J
Senior III
February 13, 2018
Posted on February 13, 2018 at 21:36

If you can carefully measure the voltages between Ground pins,

the 9V battery Ground on the battery, Processor Ground and  Vssa.

you are likely to find several mVs between them.

Did you run the calibration function ?

there are a few posts about this.

Yuval Klein
Yuval KleinAuthorBest answer
Associate
February 14, 2018
Posted on February 14, 2018 at 16:30

I fond the problem, my Vdd was dropping as well and in faster rate then the voltage in the Ain. I solved it by measureing the VrefInt and using it as a reference to the ADC measurement. 

Thank you everyone for the help.