Electronic – STM32 MCU – Temp sensor gives weird values

adccnucleostm32f10xtemperature

I'm fooling around with a Nucleo-F103RB STM32 board and I'm trying to measure the ambient temperature using its internal sensor. I activate the ADC and get data normally via the HAL_ADC_GetValue() function (the value is around 1700 – 1800 and varies with temperature as it should) but the problem is that I get really weird numbers when converting to Celsius using the formula given in the manual, namely: $$\frac{V_{25} – V_{ADC}}{AvgSlope} + 25$$ (about 70-80 degrees when the real temperature is no more than 25).

I suspect that has to do with the way I'm converting the ADC value into volts, but I can't see something obviously wrong, so I came to ask here.

Code is here :

#include "TempMsr.h"

volatile uint32_t sensorData = 0;
volatile uint32_t temp = 0;

uint32_t getTemp(ADC_HandleTypeDef* ADCHandle)
{
    sensorData = HAL_ADC_GetValue(ADCHandle);
    temp = ((V25 * 1000 - sensorData * 0.8) / AVGSLOPE) + 25;

    //V25 and sensorData must be in mV for this formula to work, as the
    //AVGSLOPE value is given in mV/oC

    //the 0.8 multiplication comes from dividing the max ADC voltage (3.3V) with its resolution (12 bits => 4096) which is 0.8mV/ADC unit

    return temp;
}

Its header file:

#ifndef TEMPMSR_H_
#define TEMPMSR_H_

#include "stm32f1xx_hal.h"

#define AVGSLOPE 4.3
//average slope of T-V chart according to datasheet pg 79
//(min is 4 mV/C, max 4.6, default (4.3): typical)

#define V25 1.43
//voltage of temperature sensor at 25C according to datasheet pg 79 (in V)
//(min is 1.34, max is 1.52, default(1.43): typical)

uint32_t getTemp(ADC_HandleTypeDef* ADCHandle);


#endif /* TEMPMSR_H_ */

Thanks in advance!

EDIT: I just noticed in the reference manual that the sensor has a bias (of up to +- 45 degrees) due to the manufacturing process, which is different on every chip and I have neither calculated it for my particular MCU nor included it in the formula. Could this be the problem?

Best Answer

I'm not C expert, perhaps

You have to parse uint to float, then calculate, then parse again to uint, if the result has to be uint.

{
    sensorData = HAL_ADC_GetValue(ADCHandle);
    temp = (uint32_t)(((V25 * 1000.0 - (float)sensorData * 0.8) / AVGSLOPE) + 25.0);

    //V25 and sensorData must be in mV for this formula to work, as the
    //AVGSLOPE value is given in mV/oC

    //the 0.8 multiplication comes from dividing the max ADC voltage (3.3V) with its resolution (12 bits => 4096) which is 0.8mV/ADC unit

    return temp;
}