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.
LM61 sensor in a TO-92 package.
LM61 Datasheet
TMP36 Datasheet
Wiring
mbed | LM61 (or TMP36) |
---|---|
GND | GND |
Vout(3.3V) | Vs |
p15 | Vout |
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.
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/
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:
Please log in to post comments.
Nice example, but you could replace operator float with :