Internal temperature sensor
Internal temperature sensor
Any simple example of use internal temperature sensor to read ambient temperature ?
(Arduino / STM32G071)
Tks
(Arduino / STM32G071)
Tks
-
- Posts: 633
- Joined: Thu Dec 19, 2019 1:23 am
Re: Internal temperature sensor
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);
}
Re: Internal temperature sensor
Great.
Below some observations.
Your comment please.
Below some observations.
Your comment please.
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
Re: Internal temperature sensor
When I compile and upload the code (mentioned on the github page in the third post) to my blue pill board with STMF103C8T6 the VRef and the A0 sampling work ok, but I always get 266 or 267 degrees Celcius temperature. Even when i heat it up a little, it does not change.
This is what I get:
I tested with 3 original STM bluepills as well a GD fake and a CKS fake bluepill, with all the same result.
Am I missing something?
This is what I get:
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
Am I missing something?
Re: Internal temperature sensor
This is an example, probably that the formula and value used are not correct for G0. Check the datasheet to customize.
Re: Internal temperature sensor
I checked the datasheet of the STMF103C8T6, but the only thing it tells me is that the temperature sensor is on ADC1_IN16.
I looked at the header files in the STM32 Arduino package and see that the ATEMP is defined depending on MCU as the last analog pin +1
So I redefined "ATEMP", which was defined as "36" into anything from 1 to 40 and never observed any outputs that changed when temperature of the chip was changed.
This is what I read in the API Wiki on the Github page
Is there a logic between the "36" that ATEMP is defined for STMF103C8T6 and the ADC1_IN16 ?
I doo not understand how I can define the analog pin ADC1_IN16.
analogRead(ADC1_IN16) did not compile, as it is not a defenition in any of the header files.
I looked at the header files in the STM32 Arduino package and see that the ATEMP is defined depending on MCU as the last analog pin +1
So I redefined "ATEMP", which was defined as "36" into anything from 1 to 40 and never observed any outputs that changed when temperature of the chip was changed.
This is what I read in the API Wiki on the Github page
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
I doo not understand how I can define the analog pin ADC1_IN16.
analogRead(ADC1_IN16) did not compile, as it is not a defenition in any of the header files.
Re: Internal temperature sensor
ATEMP is just an alias and internally this alias is well used to use the ADC1_IN16 for F1.
I've check and found why you got this result.
In fact the __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS assume the ADC resolution is 12 bits.
But we have harden the ADC resolution management for Arduino compatibility and so the default one is 10 bits. Before the hardenning the resolution was 12 bits so the example code was correct.
Setting the correct resolution to 12 bits solve the issue.
I've updated the wiki example and now value are correct.
I've check and found why you got this result.
In fact the __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS assume the ADC resolution is 12 bits.
But we have harden the ADC resolution management for Arduino compatibility and so the default one is 10 bits. Before the hardenning the resolution was 12 bits so the example code was correct.
Setting the correct resolution to 12 bits solve the issue.
I've updated the wiki example and now value are correct.
Re: Internal temperature sensor
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.
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 chip
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.

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:
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:
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
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.
Re: Internal temperature sensor
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.
I have same problem about reading stm32f103 internal temp sensor values. I always get minus values from serial port. Which code did you use to solve this problem?
Thanks.