LM61 and TMP36 Analog Temperature Sensors

The LM61 is a low cost analog temperature sensor. In addition to surface mount, it is available in a TO-92 3 pin package that will plug directly into a breadboard. Cost for the LM61 can run well under $1 US. Accuracy runs around 2 degrees C and the range is -30C to 100C. The TMP36 available from Sparkfun is very similar, but it has an offset voltage of .5 vs .6 for the LM61. So this demo will also work for it, with that minor change in one line of code shown at the end of this page. Cost for the TMP36 is higher, but it is also a bit more accurate.

/media/uploads/4180_1/lm61to-92.jpg
LM61 sensor in a TO-92 package.


LM61 Datasheet
TMP36 Datasheet

Wiring

mbedLM61 (or TMP36)
GNDGND
Vout(3.3V)Vs
p15Vout



/media/uploads/4180_1/_scaled_mbedtemp.jpg
Sensor attached to mbed on a breadboard. Larger Image

WARNING

Pay attention to the pinout show below, and note that the drawing showing the leads is a BOTTOM VIEW. If you plug in the sensor backwards, it becomes a space heater for a few seconds and dies, or if you are lucky mbed's overcurrent circuit shuts things down. Keep the leads short to reduce analog noise on a breadboard. If a design turns on and off other high current external I/O devices, a (1-10uf?) decoupling capacitor across the analog sensor's power leads (located right at the sensor) can help filter out the transient switching noise on the power supply and produce more accurate and consistent readings.



/media/uploads/4180_1/_scaled_lm61pinout.png

LM61 and TMP36 TO-92 case pinout.

Here is a short code example that displays the temperature from the sensor. From the datasheet, the output is assumed linear with Vout = 0.6 + 0.01*Tc. Since the analog input is scaled between 0 to 1.0 by AnalogIn(), it is multiplied by 3.3 to convert it back to a voltage reading, 0.6 is subtracted and it is multiplied by 100 to obtain the temperature in degrees C. A printf() then displays the temperature in degrees C and F on the PC. For the TMP36, change the voltage offset from 0.600 to 0.500 in the code example.

#include "mbed.h"

//Print temperature from LM61 analog temperature sensor

//set p15 to analog input to read LM61 sensor's voltage output
AnalogIn LM61(p15);

//also setting unused analog input pins to digital outputs reduces A/D noise a bit
//see http://mbed.org/users/chris/notebook/Getting-best-ADC-performance/
DigitalOut P16(p16);
DigitalOut P17(p17);
DigitalOut P18(p18);
DigitalOut P19(p19);
DigitalOut P20(p20);

int main()
{
    float tempC, tempF;

    while(1) {
        //conversion to degrees C - from sensor output voltage per LM61 data sheet
        tempC = ((LM61*3.3)-0.600)*100.0;
        //convert to degrees F
        tempF = (9.0*tempC)/5.0 + 32.0;
        //print current temp
        printf("%5.2F C %5.2F F \n\r", tempC, tempF);
        wait(.5);
    }
}



Import programLM61

Analog Temperature Sensor Demo. See http://mbed.org/users/4180_1/notebook/lm61-analog-temperature-sensor/



/media/uploads/4180_1/lm61demo.png

The temperature displayed with the demo code in RealTerm on the PC.

In a final product, additional steps can be taken to reduce and filter the noise. See http://mbed.org/users/chris/notebook/Getting-best-ADC-performance/ for some suggestions.

Here is a simple code example showing how to setup and use a new C++ class for the LM61

LM61

//Print temperature from LM61 analog temperature sensor

//Setup a new class for LM61 sensor
class LM61
{
public:
    LM61(PinName pin);
    LM61();
    operator float ();
    float read();
private:
//sets up the AnalogIn pin
    AnalogIn _pin;
};

LM61::LM61(PinName pin) : _pin(pin)
{
// _pin(pin) means pass pin to the AnalogIn constructor
}

float LM61::read()
{
//convert sensor reading to temperature in degrees C
    return ((_pin.read()*3.3)-0.600)*100.0;
}
//overload of float conversion (avoids needing to type .read() in equations)
LM61::operator float ()
{
//convert sensor reading to temperature in degrees C
    return ((_pin.read()*3.3)-0.600)*100.0;
}



//use the new class to set p15 to analog input to read and convert LM61 sensor's voltage output
LM61 mylm61(p15);

//also setting unused analog input pins to digital outputs reduces A/D noise a bit
//see http://mbed.org/users/chris/notebook/Getting-best-ADC-performance/
DigitalOut P16(p16);
DigitalOut P17(p17);
DigitalOut P18(p18);
DigitalOut P19(p19);
DigitalOut P20(p20);

int main()
{
    float tempC;

    while(1) {

        tempC = mylm61;
        printf("Float operator overloading avoids .read() above: T=%5.2F C \n\r", tempC);
        printf("As a printf arg it needs a float type convert: T=%5.2F C \n\r", float(mylm61));
        printf("Or Use .read() instead: T=%5.2F C \n\r\n\r", mylm61.read());
        wait(.5);
    }
}



Code modified for TMP36


TMP36

#include "mbed.h"

//Print temperature from TMP36 analog temperature sensor

//Setup a new class for TMP36 sensor
class TMP36
{
public:
    TMP36(PinName pin);
    TMP36();
    operator float ();
    float read();
private:
//class sets up the AnalogIn pin
    AnalogIn _pin;
};

TMP36::TMP36(PinName pin) : _pin(pin)
{
// _pin(pin) means pass pin to the AnalogIn constructor
}

float TMP36::read()
{
//convert sensor reading to temperature in degrees C
    return ((_pin.read()*3.3)-0.500)*100.0;
}
//overload of float conversion (avoids needing to type .read() in equations)
TMP36::operator float ()
{
//convert sensor reading to temperature in degrees C
    return ((_pin.read()*3.3)-0.500)*100.0;
}



//use the new class to set p15 to analog input to read and convert TMP36 sensor's voltage output
TMP36 myTMP36(p15);

//also setting unused analog input pins to digital outputs reduces A/D noise a bit
//see http://mbed.org/users/chris/notebook/Getting-best-ADC-performance/
DigitalOut P16(p16);
DigitalOut P17(p17);
DigitalOut P18(p18);
DigitalOut P19(p19);
DigitalOut P20(p20);

int main()
{
    float tempC;

    while(1) {

        tempC = myTMP36;
        printf("Float operator overloading avoids .read(): T=%5.2F C \n\r", tempC);
        printf("A Printf arg needs a float type convert: T=%5.2F C \n\r", float(myTMP36));
        printf("Or Use .read() instead: T=%5.2F C \n\r\n\r", myTMP36.read());
        wait(.5);
    }
}



For short functions, it might also be worth considering using "inline" to tell the compiler to put the function code inline. It uses more memory to copy the code each time, but saves subroutine call and return execution time.

For some more related examples see:
Calling mbed APIs – How APIs work using C++ and operator overloading
Writing a Library – How to create and publish a new mbed library or program
How printf works in displays – How printf works in display drivers using C++ virtual functions and inheritance


8 comments on LM61 and TMP36 Analog Temperature Sensors:

03 Dec 2012

Nice example, but you could replace operator float with :

LM61::operator float ()
{
//convert sensor reading to temperature in degrees C
    return read();
}
24 May 2013

It's a really nice information , thank you sir

03 Jul 2013

Jim, I had to change your formula to

tempC = ((TMP36 * 3.3) * 100 - 50);

to get the temperature to read accurately.

10 Mar 2015

Thanks for the awesome code but on my output I'm off by a decimal place. So I changed the 100 multiplier to a 10 and I can't verify the temperature but it feels about high 70's in here. Any reason you're output isn't off by a decimal place?

28 Feb 2017

PLEASE WHAT CAN I PUT IN THE CODE TO MAKE IT READ THE TEMPERATURE OF THE ENVIRONMENT REAL TIME

28 Feb 2017

Charles Ekaluo wrote:

  1. include "mbed.h"

Print temperature from LM61 analog temperature sensor

set p15 to analog input to read LM61 sensor's voltage output AnalogIn LM61(p15);

also setting unused analog input pins to digital outputs reduces A/D noise a bit see http://mbed.org/users/chris/notebook/Getting-best-ADC-performance/ DigitalOut P16(p16); DigitalOut P17(p17); DigitalOut P18(p18); DigitalOut P19(p19); DigitalOut P20(p20);

int main() {     float tempC, tempF;

    while(1) {         conversion to degrees C - from sensor output voltage per LM61 data sheet         tempC = ((LM61*3.3)-0.600)*100.0;         convert to degrees F         tempF = (9.0*tempC)/5.0 + 32.0;         print current temp         printf("%5.2F C %5.2F F \n\r", tempC, tempF);         wait(.5);     } }

URGENT!

24 Apr 2019

-

03 May 2019

-

Please log in to post comments.