LM35: A Not So Simple Temperature Sensor for The Arduino
Needs more than three wires to work as advertised.
An Internet search for a temperature sensor to connect to the Arduino microcontroller board brings up the LM35DZ (or LM35 for short). An inexpensive one-wire temperature sensor from National Semiconductor. Every how-to article has a diagram or picture of three wires—power, out, and ground — connecting the sensor on the breadboard to the Arduino. A little bit of copy-and-paste code uploaded to the Arduino makes it possible to measure room temperature.
Except for one small problem — that simple circuit doesn’t work.
After I connected the three jumper wires from the LM35 on the breadboard to the 5V, A5 and GND pins on the Arduino, and uploaded the code to display a temperature every second to the serial console, the numbers alternated between zeroes and random numbers. The number I expected to see was 28°C degrees, the ambient temperature for my home office.
After reading numerous comments that the circuit doesn’t work and plenty of bad advice on how to fix it, I came across a comment that pinpointed the real problem: all those how-to articles were nothing more than copy-and-paste click bait for the websites.
The LM35 with only three wires probably worked on early Arduino boards years ago. (The LM35 came out in 1999, and the first Arduino came out in 2006.) No one tested the circuit against the newer Arduino boards to see if it still works. Updating the how-to articles would take away from the click-bait simplicity of measuring room temperature with a sensor and three wires.
What does it take to make the LM35 work with the Arduino today?
The first thing I did was to check that I had correctly connected the LM35 to the Arduino.
The LM35DZ comes in a TO-92 package like a transistor. A plastic cylinder body with one side flat and three pins poking out from the bottom. It’s quite easy to connect power and ground backwards. The best way to remember pinout is to look at the flat side of the LM35: left pin is power, center pin is output, and right pin is ground.
I had the LM35 wired correctly in my circuit.
The two other LM35s that I had also behaved the same way when I put them into the circuit. With my multimeter set to millivolts and the positive probe tip on the out pin, all three had bouncing voltages. This wasn’t a software issue. Something was missing from the circuit.
Three common reasons why the simple circuit for the LM35 doesn't work.
Chinese Counterfeits From eBay
When buying electronic components from eBay, Chinese counterfeits are always a risk. Which is why I never buy anything from eBay. If something looks too good to be true, it’s probably a counterfeit.
I buy all my electronic parts from Jameco Electronics, a San Francisco Bay Area company that I’ve done business with for years. While it’s possible that counterfeit parts may enter their supply chain, I consider it unlikely.
The few problems I’ve had with components came from my own stupidity, like connecting the power and ground to the wrong pins. I always buy extra components— a lot if inexpensive, a few if expensive — in case something goes pop and blue smoke pours out.
Unreliable Power Via USB Cable
When the Arduino draws 5V DC from the USB cable, not every computer can deliver reliable power to each USB port. Any variations in power can affect how the Arduino performs within itself and external circuitry.
A 7V to 12V DC power supply connected to the barrel connector, or a battery pack connected to the VIN and GRN pins, can power the Arduino. Either one will disable power from the USB cable and use the onboard power regulators to produce 3.3V and 5V DC.
I plugged my Arduino Uno into a powered USB hub that provides full power to each port, and I also tested with a 9V DC wall wart plugged into the barrel connector. I didn’t notice any measurable differences between the two.
Three Wires Weren’t Enough
A lot of bad advice on what additional components needed to make the LM35 work with the Arduino seems to be the rule and not exception. This is where the LM35 data sheet becomes useful, presenting other example circuits in addition to the simple circuit. In particular, the LM35 with a R-C damper circuit.
The LM35 supposed to be a remote sensor at the end of a coaxial cable (one wire with grounded shielding). One way to stop the cable from acting like an antenna that interferes with the sensor is to add a resistor-capacitor (R-C) damper between out and ground. A bypass capacitor across power and ground eliminates unwanted electromagnetic interference (EMI).
Adding those three components fixed the LM35 as a temperature sensor for the Arduino.
After looking at so many how-to articles, I settled on “Reading the Room Temperature with an LM35 Sensor” by rastating as the basis for my own project. It clearly explains how the LM35 works, uses the Arduino's internal voltage reference for better accuracy, and the copy-and-paste code works without modification with the revised circuit.
I added the R-C damper with a 75Ω resistor and a 0.22μF tantalum capacitor, and a 0.1μF bypass capacitor to modify the simple circuit.
The data sheet calls for a 0.2μF or 1μF capacitor in the R-C damper. As the Jameco support tech pointed out to me, 0.2μF haven’t been a standard value in years. The closest standard value was 0.22μF and Jameco carried that value as tantalum capacitors. (Since those cost twice as much as ceramic disc capacitors, I bought 20 instead of 100.) I went with 0.22μF since 1μF didn’t work at all (the serial console reported a zero every second).
The LM35 in the revised circuit takes several minutes for the numbers to settle down and then consistently report the room temperature in the serial console.
If I touch the LM35 with my thumb and forefinger, the numbers will spike up to 42°C until I let go and then slowly settle down to room temperature.
The LM35 now works as advertised — albeit with a few extra components — with the Arduino.