LM35DT Temp Sensor reading low

I have a LM35DT Temperature Sensor and I am using this code

/*LM35 Thermometer
 *
 *LM35 simply connected to:           5+
 *                             0V
 *                             Analog Pin 0
 */

int potPin = 0;                             //input read pin for LM35 is Analog Pin 0
float temperature = 0;                      //variable which will be calculated in process

void setup()
{
  Serial.begin(9600);
  Serial.println("LM35 Thermometer    ");       //Print "LM35 Thermometer" once at start
}

void  printTenths( int value){
   // prints a value of  123 as 12.3
      Serial.print(value / 10);
      Serial.print(".");
      Serial.println( value % 10);
}

void loop ()
{
  int span = 20;
  int aRead = 0;
  for (int i = 0; i < span; i++) {        //loop to get average of 20 readings
    aRead = aRead + analogRead(potPin);
}
  aRead = aRead / span;

  temperature = ((5*aRead*100)/1024);           //convert voltage to temperature
  Serial.print ("Analog in reading: ");
  Serial.print (long(aRead));       //print temperature value on serial screen
    Serial.print (" - Calculated Temp: ");
    printTenths(long(temperature));

  delay(500);
}

The temp. in the room is about 22 Degrees C and yet the sensor is reading around 2 degrees. Any ideas please?

Without testing it, the code looks logically okay to me. I'll look into it a little more because there is obviously something wrong. Programming is not yet my strong point, I'm working on it.

I am only replying now because your resolution is going to be absolutely awful using an LM35 and a 5V Aref voltage.

analogReference(INTERNAL); will use the ATMEGA's internal 1.1V reference. Its not the most accurate thing ever, but it will still give you better resolution and error margin.

Say your temp varies 0C - 50C, which is pretty wide for most applications.

0C = 0.00V = 0 (reported by the ADC) 50C = 0.50V = (0.50/5)*1023 = 102

so you're only using 10% of the ADC's range when going from 0 degrees to 50 degrees.

The internal reference is 1.1V, increasing your utilization to over 50% (in the same example), thus increasing your sensitivity.

EDIT: It's your printtenths function as temperature is already the proper magnitude.

I don't want to think too much right now, but try replacing: temperature = ((5*aRead*100)/1023); with temperature = ((5*aRead*1000)/1023); better yet, temperature = ((5000*aRead)/1023);

This way:

Sensor detects 20C as temperature... , outputs 0.20V 0.20V is read by the ATMEGA as: (0.20V/5.0V)*(1023) = 41 temperature = ((5*41*1000)/1023); = 200.4 (some error, oh well) passed to your printtenths function...

OK I think I worked it out.

The LM35DT has a range from 0-100 degrees C and not -50 to 150 like other versions. I just changed this line..

  temperature = (aRead/10.23);           //convert voltage to temperature

and also included the analogReference(INTERNAL); in setup()

Seems to work fine now.

Thanks

:)

Using temperature = (aRead/10.23); ...

aRead (where temperature = 20C and Aref = 1.1V) = (0.20V/1.1V)*1023 = 186

temperature = 186 / 10.23 = 18.18C NO!


temperature = (100*1.1V*aRead)/1023 will get you 20 , multiply by 10 to get your printtenths function to work how you want it.

I don't get that.

20 Degrees is 204.8 by my calculations

(1024/100)*20 = 204.8

204.8 / 10.24 = 20

You should really read my formulas instead lol.

20C…

As determined by the LM35 specs:

Temperature (C) = (Output Voltage) / (10mV / *C)

The 6 (or 8) ADC inputs of the Arduino have a 10-bit resolution, meaning they are capable of distinguishing between 2^n - 1 voltages (2^10 - 1 = 1023).

The analogRead() function reports the decimal equivalent to the binary number associated with the level detected (0-1023 or 0000000000 to 1111111111) where 0V is reported as 0 (ideally) and Aref is reported as 1023 (again, ideally).
For the temperature 20C you can expect the following to be reported:

(0.20V/Aref)*1023

If Aref is 5V you get 41 and if Aref is 1.1V (analogReference(INTERNAL)) you get 186

To convert this decimal value back into temperature you would use the following function:

Temperature = (ArefAread100)/(2^n - 1)

factor of 100 added because this formula really only turns the aRead back into a voltage, where 10mV is equivalent to a degree, so we multiply it by 100 to make 1V = 1*C.
aRead = Decimal value reported by analogRead()
Aref = Analog reference value as set by analogReference() and in some cases by what you apply to the Aref pin of the Arduino.
n = # bits of resolution the ADC has.

I generalized this formula in case you or anyone else who reads this encounters an 8-bit or 12-bit ADC for example.

I’ve generalized it as best I can.

For your special case, you want to make the factor of 100 into 1000 so your formula for making it a decimal works. Its a way of getting around the problems with using integers (you can store 20.8*C as 208 in an integer and then divide by 10)

Thanks for the info. Scott

The LM35DT is supposed to give a temperature range of 0 to 100 Degrees C from 0 to 5v. If the analogReference is set to 1.1v won't I be limiting the range?

the LM35 gives a temperature proportional to voltage by 10mv/1degreeC so 0C is 0V and 100C is 1V. you'd have to go up to 500C to get to 5V, and by that time the device would fry.

you'd have to make a signal conditioning circuit with a couple op-amps to change the range from 0-1V to 0-5V.

OK thanks I was thinking that because I was putting 5v into it that 100 Degrees C would be 5v out again, but reading the datasheet that is not the case.

I'm trying to gt my head around how the analogReference command works.

I have been looking at this code and trying to work out why the aRead value is cast as a long

  Serial.print (long(aRead));       //print temperature value on serial screen

and even more puzzling, why the value of temperature is cast as long, when it is already a long data type variable?

    Serial.print (" - Calculated Temp: ");
    printTenths(long(temperature));

Can anyone explain please?

Thanks.