cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F042C6T6 ADC Reading 8-10% Low

rishabhsareen
Associate II
Posted on June 09, 2015 at 17:56

I have the ADC reading the voltage drop across a 10k thermistor setup in a voltage divider w/ a 57k resistor. If I probe the board itself I can easily read the voltage drop across the thermistor and to the appropriate input pin of the STM This reading isconsistently 8-10% higher than the 12 bit reading the ADC outputs (so the ADC is reading low). I am using the HAL ADC drivers and the ADC is reading in single conversion mode. I tried adjusting the sampling time to be longer, but it had no impact. Any idea what it could be? I inserted the code I am using for the ADC below (these functions are called by the main program):

#include ''stm32f0xx_hal.h''
#include ''adc.h''
ADC_HandleTypeDef hadc;
/* ADC init function */
void
adc_init(
void
)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC;
hadc.Init.Resolution = ADC_RESOLUTION12b;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.Overrun = OVR_DATA_PRESERVED;
HAL_ADC_Init(&hadc);
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
}
uint32_t adc_read(uint32_t channel) {
HAL_StatusTypeDef adc_status;
//ADC_ChannelConfTypeDef sConfig;
//sConfig.Channel = channel;
//HAL_ADC_ConfigChannel(&hadc, &sConfig);
hadc.Instance->CHSELR = 1 << channel;
HAL_ADC_Start(&hadc);
adc_status = HAL_ADC_PollForConversion(&hadc, 1000);
if
(adc_status == HAL_OK) {
return
HAL_ADC_GetValue(&hadc);
}
return
0;
}

#adc #hal #stm32f0
10 REPLIES 10
Posted on June 09, 2015 at 19:20

And how are you converting the ADC measurement into a voltage?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rishabhsareen
Associate II
Posted on June 09, 2015 at 19:50

What do you mean by that? The ADC measurement is read and then communicated over CAN, using the STM32's built-in CAN interface.

Posted on June 09, 2015 at 21:08

What do you mean by that? The ADC measurement is read and then communicated over CAN, using the STM32's built-in CAN interface.

You're telling me the number is off by 10%, and I'm asking you how you compute the voltage based on the value you receive.

So a) I'm looking for the formula you're using, and b) what reference voltage you are using on your F0 board implementation.

There's a classic off by 10% issue a lot of people fall into, especially with DISCO boards.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rishabhsareen
Associate II
Posted on June 09, 2015 at 21:27

Ah, I see.

The value from the ADC would be 0-4095 and reference voltage is 3.3V. So the voltage I calculate is: ADC_value*(3.3/4096).

Posted on June 09, 2015 at 21:46

And is this a board you built? Or the DISCO board?

Because the DISCO is not 3.3V

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rishabhsareen
Associate II
Posted on June 09, 2015 at 22:05

Yes, this is a custom board.

Posted on June 09, 2015 at 22:10

Ok, then I'll assume you know what voltage the reference pin is at.

Can you attach a 1.2V or 1.5V battery to one of the chips ADC input pins, with no other circuitry attached. Does that give you expected values?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
carl2399
Associate II
Posted on June 10, 2015 at 05:03

Have you considered the input impedance of the ADC. You might find it lower than you expect. Put the input impedance as a resistor in your ''divider'' (thermocouple + resistor). 

I found that I needed an OpAmp to buffer the analogue.

Regards,

Carl.

rishabhsareen
Associate II
Posted on June 11, 2015 at 16:20

Sorry for the delayed response. Using a AAA battery I found lying around (discharged, reading 1.21V) I hooked it up directly to the STM32 pins. The reading I am seeing is 1440, so around 1.16V. Still lower, but not by the same 10% as before. Although the readings before were at a much lower range (around 0.6V).

I should mention there is a MUX before the input pin of the STM32, which I concluded was leading to the 10% off reading as it's ON resistance for a certain channel was around 100 ohms. However, I conducted the battery test anyways to be sure and I don't understand where the 4% error in this case is coming from. The resistance of the PCB trace from where I hooked up the battery to the STM32 pins is negligible. 

Edit: To clarify, the battery test was conducted bypassing the MUX.