The LM35 is the easiest sensor to wire and one of the easiest to misread. Three pins, no resistor, no calibration, and a single specification that is the whole datasheet:
10 mV per °C, linear, 0 V at 0 °C
25 °C gives 0.25 V. 100 °C gives 1.00 V. That is it. Which means everything that goes wrong happens in the arithmetic, not the circuit.
Wiring: three pins, one of which people skip
V+ to 5 V, GND to ground, OUT straight to an analog pin. No series resistor — the LM35 is a voltage source, not a resistance, so a resistor between it and the pin does nothing except make the reading worse.
The pin people skip is V+. The LM35 needs at least 4 V to work, and below that it has no output at all. Simulated at 3 V it reads 0.0000 V at every temperature; at 5 V and at 12 V it reads the same 0.2500 V at 25 °C, because the output does not depend on the supply once the supply is sufficient. If your sensor reads a flat zero, the supply is the first thing to check, not the code.
The conversion, and where it goes wrong
analogRead does not give you volts. It gives a ratio against the reference, scaled to ten bits:
float volts = analogRead(A0) * 5.0 / 1023.0;
float tempC = volts * 100.0; // ۱۰۰ = inverse of 10 mV per °C
Or in one line:
float tempC = analogRead(A0) * 5.0 / 1023.0 * 100.0;
Three ways this goes wrong, in order of how often:
Integer division. analogRead(A0) 5 / 1023 100 is all integers, so the division truncates to 0 before the multiply and you get 0 every time. Write 5.0 and 1023.0, with the decimal points.
Overflow. analogRead(A0) 100 on an int is fine, but analogRead(A0) 5000 is not — 1023 × 5000 is 5,115,000 and an int on an AVR holds 32,767. Cast to long or uint32_t before multiplying by anything large.
The wrong reference. If you have called analogReference(), the 5.0 in your formula is wrong and every reading is scaled by a constant you cannot see.
The 0.5 °C trap
This is the part worth internalising, because no amount of careful code fixes it.
On a 5 V reference, one ADC count is 5.0 / 1023 = 4.887 mV. At 10 mV per degree that is 0.49 °C per count. Your temperature reading can only ever move in half-degree steps.
It is easy to see in practice. At 25 °C the LM35 outputs 250 mV. The ADC returns 51. Convert 51 back and you get 249 mV, which is 24 °C — the reading is a degree low, and no bug caused it. That is quantisation, and it is the real limit on accuracy in almost every LM35 project. The sensor is specified to ±0.5 °C; the ADC is throwing away about the same amount again.
The fix is a lower reference, because resolution is the reference divided by 1023:
| Reference | Volts per count | Degrees per count | Max temperature |
|---|---|---|---|
| 5 V (default) | 4.9 mV | 0.49 °C | 500 °C |
1.1 V (INTERNAL on an Uno) | 1.1 mV | 0.11 °C | 110 °C |
| 2.56 V (ATmega16 internal) | 2.5 mV | 0.25 °C | 256 °C |
void setup() {
analogReference(INTERNAL); // 1.1 V on an ATmega328P
}
// and the conversion becomes
float tempC = analogRead(A0) * 1.1 / 1023.0 * 100.0;
That is 4.5× better resolution for one line of code, and the only thing you give up is the ceiling: 1.1 V is 110 °C, which is above anything an LM35 in a room is going to see. Change the reference and you must change the constant in the conversion — forgetting that is the most common follow-on bug.
Note the ordering rule: after analogReference(), throw away the first reading. The reference takes a moment to settle and the first conversion after a change is not trustworthy.
On a bare AVR
There is no analogReference() outside the Arduino API — you set the REFS bits in ADMUX yourself:
ADMUX = (1 << REFS0) | channel; // AVCC as reference
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // enable, clock /64
On an ATmega16, REFS1:0 = 11 selects the internal 2.56 V, which gives 0.25 °C per count — the middle row of that table. The ATmega16 walkthrough covers the ADC registers in full, including the AREF and AGND pins that the Arduino form hides.
Circuits worth building with it
A thermostat. Read the temperature, compare against a threshold, drive an output. The interesting part is not the comparison — it is the hysteresis, because a threshold with no deadband chatters on and off around the set point.
A temperature bar graph. One LED per band, which makes the quantisation visible: with a 5 V reference the bands do not land where you expect, and that is the lesson.
A readout. The temperature on a display is where the conversion arithmetic stops being abstract, because a wrong cast shows up as 0 or a nonsense number rather than a slightly-off reading.
Try it
Open the simulator, place a microcontroller and an LM35 from the Sensors palette, wire V+ to 5 V, GND to ground and OUT to A0, and paste the conversion above. The sensor has ± buttons on the canvas — set the temperature and the reading follows.
Or describe it — "an Arduino Uno with an LM35 on A0 printing the temperature" — and get the circuit and the sketch built for you.
If your reading is not just imprecise but zero or nonsense, simulating analogRead covers the analog-input failures that are not specific to this sensor.
Frequently asked questions
How do you convert an LM35 reading to temperature?
Multiply the ADC count by the reference voltage, divide by 1023, then multiply by 100. On a 5 V board that is tempC = analogRead(A0) * 5.0 / 1023.0 * 100.0. The 100 is the inverse of 10 mV per degree.
Does the LM35 need a resistor?
No. It is a voltage output, not a resistance, so it connects straight to the analog pin. A series resistor does nothing useful and, with the ADC's own input requirements, a large one makes the reading worse.
Why does my LM35 read 0 always?
The most likely cause is the supply. The LM35 needs at least 4 V on V+ and a ground connection; without both it has no output at all. After that, check you are reading an analog pin and not a digital one.
Can the LM35 measure below 0 °C?
Not on a single supply. Its output would have to go negative, which a single-supply circuit cannot do, so it clamps at 0 V. Sub-zero readings need a negative supply and a pull-down resistor, which is a different circuit.
How accurate is an LM35 with Arduino?
The sensor is accurate to about ±0.5 °C. The limit in practice is the ADC, not the sensor: on a 5 V reference one count is 4.9 mV, which is 0.49 °C, so you cannot resolve better than half a degree no matter how good the part is.