Internal temperature sensor

Post here first, or if you can't find a relevant section!
Renato
Posts: 11
Joined: Thu Feb 20, 2020 9:19 pm

Internal temperature sensor

Post by Renato »

Any simple example of use internal temperature sensor to read ambient temperature ?
(Arduino / STM32G071)
Tks
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: Internal temperature sensor

Post by mrburnette »

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);
}
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Internal temperature sensor

Post by fpiSTM »

Renato
Posts: 11
Joined: Thu Feb 20, 2020 9:19 pm

Re: Internal temperature sensor

Post by Renato »

Great.
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
hmeijdam
Posts: 6
Joined: Fri Nov 27, 2020 7:41 pm

Re: Internal temperature sensor

Post by hmeijdam »

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:

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
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?
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Internal temperature sensor

Post by fpiSTM »

This is an example, probably that the formula and value used are not correct for G0. Check the datasheet to customize.
hmeijdam
Posts: 6
Joined: Fri Nov 27, 2020 7:41 pm

Re: Internal temperature sensor

Post by hmeijdam »

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

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
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.
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Internal temperature sensor

Post by fpiSTM »

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.
hmeijdam
Posts: 6
Joined: Fri Nov 27, 2020 7:41 pm

Re: Internal temperature sensor

Post by hmeijdam »

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:

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
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:

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
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.
lostromos
Posts: 1
Joined: Mon Dec 28, 2020 8:48 pm

Re: Internal temperature sensor

Post by lostromos »

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:

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
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:

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
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.
Hi,

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.
Post Reply

Return to “General discussion”