This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123GH6PGE: Internal temperature sensor reads 10 degrees low

Part Number: TM4C123GH6PGE

Hi,

I can't figure out why the temperature reading is about 10 degC lower than expected. (I know the data sheet says accuracy +/-5degC).

My room ambient is about 22degC. My processor is on a board that consumes very little power and is not even warm to the touch. I am expecting to find the internal temp sensor reading at least 25 degC but it consitently gives me around 15 degC. It is the same on several different boards. I have checked the package temperature with an infra-red thermometer which is reading around 24 degC.

Below is my code for initialising the ADC and then the code for reading the temperature which is run once a second in my application.

Can anyone spot an error or come up with an explanation please?

Thank you.

Richard

void initTemperature(void)
{
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
        while(!(ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_ADC1)));    //wait for peripheral ready

        //ROM_ADCReferenceSet(ADC0_BASE, ADC_REF_EXT_3V);
        ROM_ADCReferenceSet(ADC1_BASE, ADC_REF_INT);
        //need to discard first 3 samples of temp sensor - errata
        ROM_ADCSequenceDisable(ADC1_BASE, 2);                                                    //disable sequence before we change it
        ROM_ADCSequenceConfigure(ADC1_BASE, 2, ADC_TRIGGER_PROCESSOR, 1);                        //select processor (software) trigger
        ROM_ADCSequenceStepConfigure(ADC1_BASE, 2, 0, ADC_CTL_TS);                              //
        ROM_ADCSequenceStepConfigure(ADC1_BASE, 2, 1, ADC_CTL_TS);                              //
        ROM_ADCSequenceStepConfigure(ADC1_BASE, 2, 2, ADC_CTL_TS);                              //
        ROM_ADCSequenceStepConfigure(ADC1_BASE, 2, 3, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);    //
        ROM_ADCIntClear(ADC1_BASE, 2);                                                            //clear the interrupt status flag
        ROM_ADCSequenceEnable(ADC1_BASE, 2);                                                    //enable sequence
}

#define OFFSET        147        //from data sheet
#define MULTIPLIER    247        //75*3.3    3.3V ref

uint32_t ADC1_value[8];
uint32_t raw_temp;
uint8_t temperature, last_temperature;

uint8_t getTemperature(void)
{
    uint8_t chng;

    ADCProcessorTrigger(ADC1_BASE, 2);                //trigger
    while(!ADCIntStatus(ADC1_BASE, 2, false))       //wait complete
    {
    }
    ADCIntClear(ADC1_BASE, 2);                        //clear the ADC interrupt flag
    ADCSequenceDataGet(ADC1_BASE, 2, ADC1_value);   //read ADC values

    raw_temp = ADC1_value[3];

    temperature = (uint8_t)(OFFSET - ((MULTIPLIER * raw_temp) >> 12));    //temperature in degC

    chng = 0;
    if(temperature != last_temperature) {
        last_temperature = temperature;
        chng = 1;
    }

    return chng;
}

  • Hello Richard

    The on-chip temperature sensor has a variation of +/-5C under ideal test conditions. I have tested the same in the region of +/-3C under temperature controlled environment. A lot of the test results depend on the on-chip activity and the voltage reference source accuracy. What is the voltage reference being used?
  • Hi Amit,
    The Vref+ is tied to VDDA and Vref- is tied to GND. I have verified it doesn't make any difference whether I select ADC_REF_INT or ADC_REF_EXT_3V in ADCReferenceSet(). I would be very happy with +/-5degC but it needs to be believable!
    Thanks,
    Richard
  • Hello Richard

    When using an external reference you need to have something like a temperature compensated voltage reference device (REF5030). Using the function is not sufficient. When using VDDA as the reference configuring Internal or External 3V will have no affect as the source is the same. Since the VDDA is used for multiple modules in the device, there is a strong possibility of on-chip noise being coupled to the ADC reference source causing such a variation. Also did you measure the voltage VDDA to be sure that it is 3.300V
  • Hi Amit,
    Yes we have a separate regulator (LM1117MPX-3.3) generating VDDA and I have measured it as 3.294V at the processor pins on this particular board. On-chip noise would most likely cause random changes in the temperature reading rather than a fixed offset I would have thought.
  • Hello Richard

    Well you are right about the fixed offset. That should not have happened. Is this part showing the behavior or every part showing the same behavior?

    Also how are the capacitors placed for the VDDA and VREF+ power pins?
  • Such has been reported in the past (here) - and has been noted upon (other) ARM MCU forum sites - as well.

    We note that you employ ADC_1 for your measure - might a quick switch to ADC_0 - at minimum - prove of interest?

    Further - does other code run while this temperature sensing is performed?   Perhaps limiting running code to "MCU Temperature Sense only" provides insight.

    Lastly - what is the condition of the MCU's (driven) ADC inputs?   Are they active - do buffer circuits drive - are all analog input signals w/in spec - at all times?

    And "supra last" - have you included the appropriate MCU power bypass caps - closely placed - and followed "high-frequency pcb layout guidelines?"   (some provided by this vendor)

  • You have local capacitors, some of significant capacitance, on the reference pin?

    Richard Bland said:
    On-chip noise would most likely cause random changes in the temperature reading rather than a fixed offset I would have thought.

    Noise can be diode coupled leading to a fixed offset.

    Also have you checked the errata on the temperature sensor?

    Robert

  • Hi cb1,

    Thanks for your input - interesting to know others have seen this, I will have a search to see if there's an explanation or workaround.

    ADC_0 is being used to monitor 14 other analog levels on the board, but I could swap ADC_0 and ADC_1 I suppose.

    It is a "single thread" application with interrupts (2 timers and uart) so it is possible other code is running. I will try global interrupt disable around the read.

    The ADC inputs are all actively driven from opamps. These have a diode to 3.3V to ensure they do not go out of spec during switch-on/switch-off. Under normal use they will all be in spec.

    The board layout is done properly with closely placed caps at each supply pin, all looks very clean on the scope.

    The results are consistent across the 60+ boards we have made so far.

    Thanks
    Richard
  • Hello Richard

    Let me try to port your code over to my LaunchPad. One information that i need is the System clock being used?
  • Thanks Amit,
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_25MHZ);
  • Richard Bland said:
    Yes we have a separate regulator (LM1117MPX-3.3) generating VDDA and I have measured it as 3.294V at the processor pins on this particular board

    Have you checked it with an oscilloscope?

    Robert

  • Hello Richard,

    I have been able to reproduce the issue that you been observing with the temperature sensor. Under a thermostream, where the die temperature is stabilized the value comes within the range. Outside of the thermostream the part shows lower die temperature. Unfortunately there is no solution for the same. As long as you can check that the temperature reported by the program follows a heating-cooling profile, the inaccuracy on the on-chip temperature sensor needs to be ignored. If better accuracy is sought then an off-chip temperature sensor would be recommended.
  • Greetings,

    For giggles - we attempted similarly - but used LX4F. (also ran test upon 3 LM3S) And - the results w/these MCUs - was w/in or just outside the  ±5°C spec. (we note that LM3S had (only) a 10 bit ADC)

    As to Amit's results under the thermostream - might this indicate that, "Increased warm-up duration (MCU under bias - NOT sitting unpowered) would raise the die temperature to meet spec?"

    Note too - as new device revisions are released - there may be new and/or further deviations from said spec.

    As poster Robert noted - a "designed to purpose, external temperature sensor" usually proves ideal for those who (really) "need to know!"

  • cb1 said:

    As poster Robert noted - a "designed to purpose, external temperature sensor" usually proves ideal for those who (really) "need to know!"

    I had made the decision to use an external sensor initially based on the fact that there was no documentation on the thermal resistance from the sensor to the ambient. The temperature sensor errata provided further reason to use an external sensor as did the large inherent error (which would be compounded by reference and A/D errors).

    I came to the conclusion that the only reason for using the on-board sensor would be, perhaps, to measure dies temperature to warn/protect against exceeding TJMax. However, although the power consumption was not documented it did not seem likely that there would be a significant temperature rise and the degree of coupling of the sensor to the junction temperature was also undocumented. On the actual board there was little temperature rise for the package and there was no obvious corrective action to take even if TJMax was exceeded so there's never been a serious temptation to use it.

    Robert

  • May I leave a post here, to make it easier for me to find any future considerations on this matter - as I also faced the same problem before.

    My boards also typically report ~8 oC less than what expected. We do have external temperature sensors available, so the onboard temp sensor is not that relevant. Still we discussed that in the past and the conclusion back then was that "it should have worked"... It didn't.

    Waste of resources? Nope! They added the internal sensor so that developers on their initial learning stages can see something out of the ADC! (And of course, get biased that they are doing something wrong, for the number shown is off...) - Or maybe for random number generation?  :)

    Cheers!

  • Thanks all for your replies.

    In conclusion we have to accept that the internal temperature sensor does not meet the +/-5degC accuracy as stated in the data sheet.

    This is not really a problem except that, as a designer I need to be able to rely on the data sheet, and as developer I suspect my implementation when the spec is not met, and I waste alot of time tracking it down.

    In my design I am measuring and reporting the temperatures on 3 Tivas as part of a system status monitor. I can change this to report a "temperature error" should the sensor read over 70degC for instance.

    Thank you and best regards,
    Richard
  • In case it helps anyone else I added this correction to the temperature reading...

    if(temperature < 15) //guess correction for internal temp sensor inaccuracy
    temperature += 10;
    else {
    if(temperature < 55) {
    temperature += (10 - ((temperature - 15) >> 2));
    }
    }

    It adds 10 if the temperature is below 15degC.
    It adds nothing if the temperature is above 55degC.
    It rescales linearly in between these values.

    I must emphasise that this is entirely guesswork, and I only have a hot-air gun and freezer spray to test it with, but it seems to work well enough for my application.

    Regards
    Richard
  • ps I would have thought that a forum that often needs to show software would preserve tabs!!
  • Hello Richard

    Do note that this is the on-die temperature. So 70C on-die would be different from ambient depending on how high or low is the thermal resistance,
  • Richard, use the past code option. That results in much better display.

    Click on Use rich formatting and then click on the </> button

    Robert
  • And depending on the placement details, that temperature may not be well correlated to the die temperature either. There is no documentation that I've seen on the sensor's behaviour.

    Robert