[SOLVED] LM35 not working with 5 volts

I've been trying to figure this out for a while. I have temperature sensor LM35 and I connect it to the A0 pin, +5V and Ground. When I run my sketch, it shows crazy temperature (like 900 F). But if Connect it to 3.3V and use AREF, it works great, no issues at all. I had same problem with Arduino Uno, Arduino Mega and now on bare ATMega644P setup. I want to avoid putting 3.3V circuitry on my custom Arduino clone, so I'd like to get by with just 5 Volts. What am I doing wrong? This is pretty much how I have it connected (1st picture): http://learn.adafruit.com/tmp36-temperature-sensor/using-a-temp-sensor And here's snips from my code:

#define aref_voltage 5
byte tempPin = A0; //the analog pin the LM35's Vout (sense) pin is connected to

void showTemp(byte color){
  //if (blinking) return; // If time setting in progress, don't do anything!
  int tempReading = analogRead(tempPin);
  float tempC = ( (tempReading * aref_voltage) / 1024.0 ) * 100 ;
  float tempF = (tempC * 9.0 / 5.0) + 32.0; // Convert to Farenheit
  dtostrf(tempF,1,1,tempChar); // Convert Float Temp to String
  sprintf(tempString, "Temp:%sF ",tempChar); // Format String for Farenheight
   scrolltextsizexcolor(8,tempString,color,25); 
   sayTemp((int)tempF);
}

You missed the "subtract 500" when converting from millivolts to degrees centigrade. Change it to:

  const long int aref_voltage_millivolts = 5000;
  float tempC = (((tempReading * aref_voltage_millivolts) / 1024.0) - 500.0) / 10.0 ;

The "((tempReading * aref_ aref_voltage_millivolts) / 1024.0)" part converts the ADC reading to millivolts.

The "((millivolts) - 500.0) / 10.0" part converts from millivolts to degrees centigrade.

Note that either tempReading or aref_voltage_millivolts has to be a LONG integer. The result of the multiplication is likely to be way outside the range of a 16-bit integer.

1 Like

Thanks John! It didn’t work for me tho :frowning:
But I think I found issue. For some reason naming pin A0 doesn’t work, but when it’s just 0 it works…
I also found an example online which seems to be working and showing correct temperature in my room.

int analogPin = 0;
int readValue = 0;
float temperature = 0;
float temperatureF = 0;

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

void loop() {
  readValue = analogRead(analogPin);
  //Serial.println(readValue);
  temperature = (readValue * 0.0049);
  temperature = temperature * 100;
  temperatureF = (temperature * 1.8) + 32;
  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.print("C ");
  Serial.print(temperatureF);
  Serial.println("F");
  delay(1000);
}
1 Like

You can combine these two lines:

  temperature = (readValue * 0.0049);
  temperature = temperature * 100;

into this one line:

  temperature = (readValue * 0.49);
1 Like

johnwasser: You can combine these two lines:

  temperature = (readValue * 0.0049);
  temperature = temperature * 100;

into this one line:

  temperature = (readValue * 0.49);

Of course! :) Thanks!

Does anyone know the reason behind multiplying by 0.49?

0.49 is very close to 0.48828125 ((5.0 / 1024.0) * 100.0). That is the conversion from analog reading to centivolts (hundredths of a volt).

Thanks for your response John

That’s is a poor way of reading an LM35. Potentially unstable and low resolution.
Better to use the internal 1.1volt reference (assuming Uno/Nano).
That increases stability, and increases resolution from ~0.5C to ~0.1C per A/D step.

void setup() {
  analogReference(INTERNAL);
}

void loop() {
  float tempC = analogRead(tempPin) * 0.1039; // calibrate by changing the last digit(s)
}

Leo…

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.