Internal temperature sensor
Posted: Thu Aug 06, 2020 3:09 pm
Any simple example of use internal temperature sensor to read ambient temperature ?
(Arduino / STM32G071)
Tks
(Arduino / STM32G071)
Tks
Everything relating to using STM32 boards with the Arduino IDE and alternatives
https://www.stm32duino.com/
Code: Select all
/* Reading Vdd and Temperature Sensor: http://stm32duino.com/viewtopic.php?f=3&t=1317#p16970
Pito 8/2016
Temperature sensor at ADC16, VREFINT at ADC17
Sketch uses 21,772 bytes (17%) of program storage space. Maximum is 122,880 bytes.
Global variables use 4,488 bytes of dynamic memory.
*/
void setup_vdd_tempr_sensor() {
adc_reg_map *regs = ADC1->regs;
regs->CR2 |= ADC_CR2_TSEREFE; // enable VREFINT and Temperature sensor
// sample rate for VREFINT ADC channel and for Temperature sensor
regs->SMPR1 |= (0b111 << 18); // sample rate temperature
regs->SMPR1 |= (0b111 << 21); // sample rate vrefint
adc_calibrate(ADC1);
}
void setup(){
setup_vdd_tempr_sensor();
Serial.begin(115200);
delay(1);
}
void loop() {
float tempr, vdd;
// reading Vdd by utilising the internal 1.20V VREF
vdd = 1.20 * 4096.0 / adc_read(ADC1, 17);
// following 1.43 and 0.0043 parameters come from F103 datasheet - ch. 5.9.13
// and need to be calibrated for every chip (large fab parameters variance)
tempr = (1.43 - (vdd / 4096.0 * adc_read(ADC1, 16))) / 0.0043 + 25.0;
Serial.print("Vdd= ");
Serial.print(vdd);
Serial.println(" V");
Serial.print("Temp= ");
Serial.print(tempr);
Serial.println(" C");
delay(500);
}
Code: Select all
static int32_t readVref()
{
#ifdef __LL_ADC_CALC_VREFANALOG_VOLTAGE
return (__LL_ADC_CALC_VREFANALOG_VOLTAGE(analogRead(AVREF), LL_ADC_RESOLUTION)); // VRef result more accurate
#else
return (VREFINT * ADC_RANGE / analogRead(AVREF)); // ADC sample to mV // like this
#endif
}
Code: Select all
#ifdef ATEMP
static int32_t readTempSensor(int32_t VRef)
{
#ifdef __LL_ADC_CALC_TEMPERATURE
return (__LL_ADC_CALC_TEMPERATURE(VRef, analogRead(ATEMP), LL_ADC_RESOLUTION)); // TempSensor results less accurate
#elif defined(__LL_ADC_CALC_TEMPERATURE_TYP_PARAMS)
return (__LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(AVG_SLOPE, V25, CALX_TEMP, VRef, analogRead(ATEMP), LL_ADC_RESOLUTION)); // like this
#else
return 0;
#endif
}
#endif
Code: Select all
VRef(mv)= 3366 Temp(°C)= 265 A0(mv)= 229
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 230
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 230
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 229
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 229
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 230
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 230
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 229
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 229
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 229
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 229
VRef(mv)= 3366 Temp(°C)= 266 A0(mv)= 230
Code: Select all
ADC internal channels
Available in core version greater than 1.5.0
analogRead() can now be used to read some internal channels with the following definitions:
ATEMP: internal temperature sensor
AVREF: VrefInt, internal voltage reference
AVBAT: Vbat voltage
Code: Select all
VRef(mv)= 3294 Temp(°C)= 32 A0(mv)= 317
VRef(mv)= 3296 Temp(°C)= 32 A0(mv)= 315
VRef(mv)= 3296 Temp(°C)= 32 A0(mv)= 330
VRef(mv)= 3294 Temp(°C)= 32 A0(mv)= 329
VRef(mv)= 3294 Temp(°C)= 32 A0(mv)= 319
VRef(mv)= 3292 Temp(°C)= 33 A0(mv)= 324
VRef(mv)= 3301 Temp(°C)= 31 A0(mv)= 327
VRef(mv)= 3301 Temp(°C)= 31 A0(mv)= 313
VRef(mv)= 3296 Temp(°C)= 32 A0(mv)= 308
VRef(mv)= 3296 Temp(°C)= 32 A0(mv)= 309
Code: Select all
VRef(mv)= 3325 Temp(°C)= -8 A0(mv)= 886
VRef(mv)= 3325 Temp(°C)= -7 A0(mv)= 881
VRef(mv)= 3318 Temp(°C)= -7 A0(mv)= 882
VRef(mv)= 3327 Temp(°C)= -8 A0(mv)= 881
VRef(mv)= 3327 Temp(°C)= -8 A0(mv)= 884
VRef(mv)= 3325 Temp(°C)= -8 A0(mv)= 883
VRef(mv)= 3327 Temp(°C)= -8 A0(mv)= 883
VRef(mv)= 3325 Temp(°C)= -8 A0(mv)= 880
VRef(mv)= 3325 Temp(°C)= -8 A0(mv)= 886
Hi,hmeijdam wrote: Tue Dec 01, 2020 4:10 pm Thanks for checking
And now it works perfect and now I also get different results between genuine and counterfeit
When I test my bluepill boards with genuine STM32F103C8 chips, manufactured by STMicro I get these results:
There is no two degrees difference between the boards and when I put my finger on it Ii can see the temperature rise.Code: Select all
VRef(mv)= 3294 Temp(°C)= 32 A0(mv)= 317 VRef(mv)= 3296 Temp(°C)= 32 A0(mv)= 315 VRef(mv)= 3296 Temp(°C)= 32 A0(mv)= 330 VRef(mv)= 3294 Temp(°C)= 32 A0(mv)= 329 VRef(mv)= 3294 Temp(°C)= 32 A0(mv)= 319 VRef(mv)= 3292 Temp(°C)= 33 A0(mv)= 324 VRef(mv)= 3301 Temp(°C)= 31 A0(mv)= 327 VRef(mv)= 3301 Temp(°C)= 31 A0(mv)= 313 VRef(mv)= 3296 Temp(°C)= 32 A0(mv)= 308 VRef(mv)= 3296 Temp(°C)= 32 A0(mv)= 309
Now when I test a few counterfeit bluepill board with a (re-etched markings as STM32) Gigadivices GD32F chip I get these results:
The temperature is way off compared to a genuine chipCode: Select all
VRef(mv)= 3325 Temp(°C)= -8 A0(mv)= 886 VRef(mv)= 3325 Temp(°C)= -7 A0(mv)= 881 VRef(mv)= 3318 Temp(°C)= -7 A0(mv)= 882 VRef(mv)= 3327 Temp(°C)= -8 A0(mv)= 881 VRef(mv)= 3327 Temp(°C)= -8 A0(mv)= 884 VRef(mv)= 3325 Temp(°C)= -8 A0(mv)= 883 VRef(mv)= 3327 Temp(°C)= -8 A0(mv)= 883 VRef(mv)= 3325 Temp(°C)= -8 A0(mv)= 880 VRef(mv)= 3325 Temp(°C)= -8 A0(mv)= 886
Another CKS clone of the STM32F103C8 can't be identified via the internal temperature sensor, as some (not all) behave just like a genuine part. There is a huge spread between the temperature they report. I will have to use the chip serial number approach to identify them.