reading internal temperature sensor

Today I slapped together some simple sketch to read the internal temperature sensor. According to the datasheet it would need calibration but it should deliver ~0.5 degrees of resolution. However when I played around with it it seems to deliver only 5-10 degrees resolution.

uint16_t read_temperature() {

  // enable conversion
  ADCSRA |= 1<<ADSC;  
  // wait for conversion to finish  
  while (ADCSRA & (1<<ADSC)) {};
  
  uint16_t temperature = ADCL;
  temperature += ADCH<<8;
  
  return temperature;
}

void enable_temperature_conversion() {
  // Set AD reference to 1.1V (internal) and enable reading the temperature sensor
  // According to Datasheet "24.8 Temperature Measurement"
  ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<MUX3);

}

void setup() {
    Serial.begin(115200);
  
    enable_temperature_conversion();
}

void loop() {
  Serial.println(read_temperature(), DEC);
  delay(500);
}

Has anyone a hint for me why this does not provide the desired resolution?

Maybe OT but this internal temp sensor has been talked about often in the past here and at the AVR freak site. I get the impression that the real challenge is that no one has been able to come up with a good application for taking this measurement. The device's internal temperature is going to mostly be influenced by the total current draw being consumed from all the output pins used in most projects. So what usage do you might see for taking this measurement, other then maybe detecting being close to the devices maximum safe operating temperature and taking steps to deal with that?

Lefty

Only one word "curiosity" :wink: I am fully aware that using a 1 wire temperature sensor is easier to deal with and gives much better readings. However I just wanted to figure it out myself how good or bad this sensor is. So far the results are diaspointing. The question however is: is this due to the sensor or due to a programming error on my side? From your comment it seems more like the sensor is to blame.

I've never played with the internal temp sensor myself, however read several postings here and elsewhere and to best of my recall all came away with the same impression, kind of disappointing with it's performance and not seeing a clear useful application for it.

Lefty

This page explains it all : http://arduino.cc/playground/Main/InternalTemperatureSensor

But it is only for ATmega328P types. My Arduino Leonardo has different values, but I haven't yet determined the gain and the offset for the Leonardo.

I have a routine I have to get the internal temperature on the 32u4. The only part I wasn't 100% sure of was the returned value, but the research I did in the Atmel documentation led me to believe it's the absolute temperature in kelvin. Here's the routine:

int getTemperature() {
  // routine provided by TCWORLD in Sparkfun forums - thank you very much TCWORLD!
  // see here for details: http://forum.sparkfun.com/viewtopic.php?f=32&t=32433
  ADMUX = 0b11000111;                  // set the adc to compare the internal temp sensor against
  ADCSRB |= (1 << MUX5);               // the 2.56v internal reference (datasheet section 24.6)
  delay(5);                            // wait a moment for the adc to settle
  sbi(ADCSRA, ADSC);                   // initiate the first conversion - this one is junk as per datasheet
  while (bit_is_set(ADCSRA, ADSC));    // wait for the conversion to finish
  delay(5);                            // another little extra pause just in case
  sbi(ADCSRA, ADSC);                   // initiate the second conversion - this is the good one
  while (bit_is_set(ADCSRA, ADSC));    // wait for the conversion to finish
  byte low  = ADCL;                    // read the low byte
  byte high = ADCH;                    // read the high byte
  int temperature = (high << 8) | low;     // result is the absolute temperature in Kelvin * i think *
  temperature = temperature - 273;     // subtract 273 to get the degrees C
  temperature = temperature * 18;      // times by 90 & divide by 5 (.1 precision without floats)
  temperature = temperature + 320;     // then add 320 to get degrees F x 10
  temperature = temperature / 10;      // then divide by 10 to get degrees F
  return temperature;
}

Cheers!

This seems to be more or less the same code I am using plus some scaling. Since the raw values are already to coarse the scaling will not improve resolution at all. So my question is still the same: why do I experience such a poor resolution?

You use the 16-bits value from the ADC, but the ADC is only 10-bits.
Just use the example: Arduino Playground - InternalTemperatureSensor
And determine the gain and offset for your chip.