LM35: Temperature Readings are not right

Hi,

Starting with Arduino. Attempting to read temperature via a LM35 sensor.

Readings appear way high or way low with current set (image attached).

Ambient temp. in my location is about 25-35 deg.C range

  • LM 35 connected to A2. 5V reference used.
  • Output, code and picture of connection attached.
  • Sensor seems fine. It responds to higher and lower temperatures. I tested by having the sensor close to ice and close to warm food
  • Other attempts made: Tried connecting sensor to A0. Tried with voltages of 5V, 3.3V. All failed to give reasonable readings.
  • I also read A0 with NOTHING connected, and it seems to read in something, is this normal?

To me everything appears correct. The connections, the code and conversion - yet after repeated attempts, the temperature reading is not coming out right.

Please help.

Serial output: Note sensor connected to A2. A0 nothing connected

Sensor [A2]: 161 units | Sensor [A0]: 208 units | Temp.: 7.87 deg.C
Sensor [A2]: 161 units | Sensor [A0]: 208 units | Temp.: 7.87 deg.C
Sensor [A2]: 161 units | Sensor [A0]: 208 units | Temp.: 7.87 deg.C
Sensor [A2]: 162 units | Sensor [A0]: 208 units | Temp.: 7.92 deg.C
Sensor [A2]: 162 units | Sensor [A0]: 208 units | Temp.: 7.92 deg.C

Code:

int sensorValue = 0;
int sensorPin = 2;
float temperature;

void setup() {
  Serial.begin(9600);
}

void loop() {
  // 1 unit value = 3.23 mV = 0.32 deg. C
  sensorValue = analogRead(sensorPin);
  Serial.print ("Sensor ["); Serial.print (sensorPin); Serial.print ("]: ");
  Serial.print (sensorValue);
  Serial.print (" units | ");

  temperature =  (5.0 * sensorValue * 10) / 1023;

  sensorValue = analogRead(A0);
  Serial.print ("Sensor [0]: ");
  Serial.print (sensorValue);
  Serial.print (" units | ");

  Serial.print ("Temp.: ");
  Serial.print (temperature);
  Serial.print (" deg.C");
  Serial.println();
  delay(2000);
}

The only time it appeared close to real temps. is with I used 3.3V Vcc and the following formula. But is this correct? I doubt the line where I set “referenceVoltage = 3.3;”

analogReference(INTERNAL);
referenceVoltage = 3.3;
temperature = (referenceVoltage * sensorValue * 10) / 1023;

This is the code that seemingly works - but I really doubt it is correct.

I use: analogReference(INTERNAL);

And then use “referenceVoltage = 3.3” is this correct?

Attached an image of a graph of the output - so the sensor seems ok - it responds to the temp changes.

int led = 9;
int flag=0;
int sensorValue = 0;
float temperature;
float referenceVoltage;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  analogReference(INTERNAL);
  referenceVoltage = 3.3;

  pinMode(led, OUTPUT);
  pinMode(A0, INPUT);
}

void loop() {

  // 1 unit value = 3.23 mV = 0.32 deg. C
  if (flag==1) {
    digitalWrite(led, HIGH);
    flag=0;
  }
  else {
    digitalWrite(led, LOW);
    flag=1;
  } 
  sensorValue = analogRead(A0);

  Serial.print ("Sensor value: ");
  Serial.print (sensorValue);
  Serial.print (" units | ");

  temperature =  (referenceVoltage * sensorValue * 10) / 1023;

  Serial.print ("Temp.: ");
  Serial.print (temperature);
  Serial.print (" deg.C");

  Serial.println();
  delay(3000);
}

Consult the LM35 data sheet. It is not guaranteed to run on less than 4V.

The sensor output for the type of connection you have is 10 mV per degree C, in the range of 2 to 150 degrees C. The overall calibration will depend on the ADC reference voltage. So, make sure that you understand how to read a known voltage (like a 1.5 V AA battery) with the ADC, before trying to read the LM35 voltage. A multimeter is handy to check everything.

Unconnected ADC inputs read voltages that vary randomly.

Thanks J Remington - glad you have shown me a direction more than a 'map' - let me go back & see what i can do of this

J Remington - I did the following and still don't get correct readings.

  1. Read the data sheets
  2. Vcc = 5V
  3. Correctly read in voltage readings from a battery (1.5 V)
  4. Used a multi meter to check voltage outputs from the sensor
  5. Used another LM35 just to be sure the sensor is ok

Modified my code to reflect the logic

inputVoltage = sensorValue * (5.0/1023) * 1000; // input voltage in mV

temperature = inputVoltage / 10; // convert to deg. C

Sample output: Sensor value: 163 units | Input voltage: 796.68 mV | Temp.: 79.67 deg.C Sensor value: 169 units | Input voltage: 826.00 mV | Temp.: 82.60 deg.C

These temps. are not right for my location

Incidentally - I used the other bit of knowledge from your response (i.e. the full range of 2 to 150 deg. C) to create a linear relation (between this and 0 to 5 V) and it gives me reasonable readings of temperature! But I doubt I have to do this. All data sheets say - one has to simply use the 10 mV/C relation

Linear relation between temp. and voltage: 5 V = 150 oC, 0 V = 2 oC, slope = (150-2)/(5-0) = 29.6 and intercept = 2.0

temperature = (29.6 * inputVoltage) + 2;

Please, always post ALL the code you are using, with code tags.

If the "sensorValue" ADC reading really is 163, and you really are using 5.0 V as the ADC reference, then that converts to 0.797 volts, which is indeed way too high.

Use your multimeter to check the ADC input voltage (that is, the sensor output voltage), to see if it really is 0.797 volts.

glad you have shown me a direction more than a 'map'

Shortcuts will get you lost. A map will always show you the path to and from. ;)

Are you sure it's an LM35. 0.797 is the reading you get at 29.7C with an LM36..... Leo..

Thanks for the attempts to help.

Here is the full code.

JRemington: Yes I had checked - the input was 0.79 V.

Wawa: Well I am 46 and I tried really really hard to see - I can’t read the inscriptions. I hope it is a LM35.

LarryD: I did learn some tips in this beginning thread on this forum already :slight_smile:

int led = 9;
int flag = 0;
int sensorValue = 0;
float temperature = 0.0;
float inputVoltage = 0.0;

void setup() {
  Serial.begin(9600);

  pinMode(led, OUTPUT);
  pinMode(A0, INPUT);
}

void loop() {

   // Alternate LED on-off, just to show it's working
   if (flag == 1) {
    digitalWrite(led, HIGH);
    flag = 0;
  }
  else {
    digitalWrite(led, LOW);
    flag = 1;
  }
  
  // Average 10 readings of the sensor inputs
  sensorValue = 0;
  
  for (int i=0; i<10; i++) {
    sensorValue += analogRead(A0);
    delay (500);
  }

  sensorValue /= 10;

  Serial.print ("Sensor value: ");
  Serial.print (sensorValue);
  Serial.print (" units | ");

  // Convert ADC input into voltage
  inputVoltage = sensorValue * (5.0/1023) * 1000; // input voltage in mV
  
  Serial.print ("Input voltage: ");
  Serial.print (inputVoltage);
  Serial.print (" mV | ");

  // Convert to temperature using LM35 linear relation 
  temperature = inputVoltage / 10;
 
  // Alternative method? Linear relation between temp. and voltage
  // 5 V = 150 oC, 0 V = 2 oC, slope = (150-2)/(5-0) = 29.6 and intercept = 2.0
  // temperature = (29.6 * inputVoltage) + 2;
 
  Serial.print ("Temp.: ");
  Serial.print (temperature);
  Serial.print (" deg.C");

  Serial.println();
}

Yes I had checked - the input was 0.79 V.

Well then, the code is correct. It is either very hot where you are, or the sensor is defective, or the sensor is not what you think it is.

You could try putting it in melting ice. If you get ~500mV, you can be sure it's the LM36. The LM36 has the same resolution as the LM35. 10mV/degreeC. The only difference is a 500mV offset. The LM35 can only measure positive temps (without additional tricks), while the LM36 also can measure temps below zero (~-40C). It should be easy to add that offset in software. Leo..

Thank you again JRemington and Leo.

Well 80 deg.C would be difficult to be habitable anywhere on earth :slight_smile:

So it is most likely a sensor issue - let me confirm that it is a LM35 or order a couple more and see.

Appreciate the help.

RajeshS: or order a couple more and see.

While you're at it, perhaps you should look at getting a better sensor anyway, maybe a DHT22?

Hey Jimbo - I had actually ordered a DHT11 too with the LM35s!

It's expensive (considering I am in India) and I just want to make sure I have a handle on this with the cheaper LM35s and not blow this sensor too :-[

But at one point I do want to try it - I also have an Arduino Ethernet shield ordered in my first purchase. My intention is to eventually build a small web-based project with temp. and humidity readings.

Thanks for the suggestion :)

Rajesh

Did you already measure the sensor in melting ice. As said, it could be the LM36. I consider the LM36 "better" than the LM35. It has a wider temp range without using negative voltage "tricks". With the LM36, -50 degrees C is 0volt, zero degrees C is 500mV. And 1000mV (1volt) is 50 degrees C. With 1.1volt Aref, you have a digital resolution of 0.1degree C, and a range of about -40 to +60 degrees C. Leo..

Dear friends! Mystery solved.

I ordered LM35s. The packet said LM35. It looked 100% like an LM35. But yesterday, I tried to read the inscriptions under strong light and it was still difficult to read what it was.

I took a 16 MP camera and took a picture and zoomed it out - it is a MCP9700!!!

I read the data sheet and Leo, like the LM36, this too had an offset that I programmed into my code and it worked!!

Thank you everyone. Apologies if I wasted your time.

I learnt a lot of lessons in my first small project. Thanks to JRemington, Leo (Wawa) and Larry D

Leo- I will take your advice when I have to build something for a better cause. This is just my learning phase.

thanks, Rajesh

MCP-9700 v1.jpg

Glad you have solved your problem. The specs of that sensor look similar to the LM36. Leo..

https://www.youtube.com/watch?v=TyKy_n2S1Lw

I can give you the code for it analizės please write a comment on my channel .... coming to my house I am sending the code and how to connect.

greetings.

puedo darte el código para que lo analizes por favor escribe un comentario en mi canal....llegando a mi casa te envío el codigo y como conectarlo.

saludos.

sore but you use the wrong formula ;

int ThermistorPin = A2; int VTemp; float R1 = 10000; float logR2, R2, T, Temp; float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;

void setup() { Serial.begin(9600); }

void loop() {

VTemp = analogRead(ThermistorPin); R2 = R1 * (1023.0 / (float)VTemp - 1.0); logR2 = log(R2); T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2)); Temp = T - 273.15;

Serial.print("Temperature: "); Serial.print(Temp); Serial.println(" C");

delay(800); }

open the serial and you will get it

Mastermex:
sore but you use the wrong formula ;

And you are 4 1/2 years late to the party…