Lm35 values capped at 31degree C

I have a strange problem, using typical code from many examples reading the temperature values of my LM35, displaying it on the LCD and writing it to an SD card. (Both the displayed and recorded values are the same).

All values below 31 degrees C seems fine but higher temperatures (when placing the sensor near a light bulb) the values increase and change as follows: 30, 31, -31, -30, -29... etc. and then reverse when removing the sensor when it cools down.

If I put the sensor in boiling hot water, the values "drop" to 0 and then increase further in the single digits. As it cools down, it goes down to 0 and, then up the negative values to -31 again and down from 31 to room temperature (around 25 deg C).


The relevant code is quite standard:

pinMode(lm35_pin, INPUT);

void loop:

temperature = analogRead(lm35_pin);
temperature = (temperature*500)/1023;


lcd.setCursor(8, 1);

Why would it max out at 31 degrees?

BTW: I use the 5volt source for the sensor.

your variable overflows. Try declare it as float...

Thanks, that solved it!


It is my interest to explore your problem a little bit more for which I would like to request you to give answer to the following questions:

  1. All codes of your original program (without float) with code tags. This is to see that you have or have not really declared data type for your variable temperature.

  2. Which Arduino (UNO, NANO, DUE, MEGA) have you used with LM35 sensor?

  3. Which analog channel have you used to acquire analog signal from LM35?

  4. What is the reference voltage (DEFAULT = 5V; INTERNAL = 1.1V, EXTERNAL = AREF) that you have used for the ADC?


Wonderful when it works and to get such a helpful answer. Far be it for me to comment, but even I can't see anything in your code that declares what sort of number to use - int, long, unsigned int, unsigned long.
Numbers increasing and decreasing over a critical value do indicate an overflow. The critical numbers are 2^8, 2^16 and 2^32. If declaring long fixed it, then that's the answer. Don't forget the ranges of these numbers and the difference between signed and unsigned - signed have half the positive or negative range of unsigned numbers. Even the biggest number 2^32 unsigned eventually overflows. Counting milliseconds, you get the overflow at about 51-days. Eventually you end up having to split the big numbers into byte-sized chunks like high and low bytes.
I wish all problems were that straightforward.

Thanks for all the replies. For those who wish to look at the complete code, here it is below:

The problem comes in when declaring the temperature value as int in this formula: temperature = (temperature*500)/1023;
indicated in the code below with // <<----- (comment) behind

/* Reading temperature using LM35 */

//Include LCD library
#include <LiquidCrystal.h>
#include <SD.h>
#include <SPI.h>

File data_file;

int LED = 13;
int lm35_pin = A0;

float temperature; // <<----- If set to int, the temp readings go 29, 30, -31, -30, -29…0 1 2… when exposed to high temperatures
int chip_select_pin = 10;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(9, 8, 5, 4, 3, 2);

void setup() {

pinMode(LED, OUTPUT);
pinMode(lm35_pin, INPUT);
pinMode(chip_select_pin, OUTPUT);

if (SD.begin())

Serial.println(“Initialization Successful. Ready to use”);
} else
Serial.println(“Initialization failed. Check your pin connections or change your SD card”);

unsigned long StartTime = millis();

void loop() {

digitalWrite(LED, HIGH);
unsigned long CurrentTime = millis();
unsigned long ElapsedTime = CurrentTime - StartTime;

if(ElapsedTime > 500){ // read the value every __ milliseconds to mimmic a delay before refreshing the display

temperature = analogRead(lm35_pin);
temperature = (temperature*500)/1023; // <<----- This is the formula that does not work using integers.
data_file = SD.open(“Temp.txt”, FILE_WRITE);

if (data_file) {







else {

Serial.println(“error opening your SD card file. Try again”);


//int v1 = analogRead(LDR1);
//int v2 = analogRead(LDR2);
// set up the LCD’s number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.setCursor(8, 0);
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
//Print a message to second line of LCD
lcd.setCursor(8, 1);
lcd.setCursor(14, 1);
StartTime = CurrentTime;



If you want a higher resolution (0.1C) from that LM35 sensor, then add this line to void setup()

analogReference(INTERNAL); // use internal 1.1volt Aref

and replace the two temperature lines in void loop() with this line

temperature = ((analogRead(lm35_pin) * 0.1039)); // calibrate by changing the last digit(s) of "0.1039"

Then you can print the temperature with one decimal place.

lcd.print(temperature, 1);

Assuming you have declared temperature as a float.

Thanks so much! I read many times that using 1.1v gives higher resolution but I thought the Arduino need such a pin which mine (nano) doesn't. I didn't realise it can be programmed in. This is really very helpful. Thanks again. :slight_smile:

BTW: I also learnt a valuable lesson during my temperature experiment (when comparing a solid plate stove cooking time too an induction hob), that the induction skrews up the lm35's readings! :frowning:
luckily I realised quickly that the stove was literally busy cooking the metal in the sensor too through the induction process and I immediately removed it, eventhough the sensor was not near the bottom of the metal pot! I checked and the sensor was still fine afterwards.
At least I could continue measuring the temp during the cool down process when the induction was off.
It was a fun and informative experiment none the less. Thanks for all the help that made it possible!