In this tutorial we will see how to interface LM35 Temperature sensor with ARM7 LPC2148 Microcontroller. LM35 is a well known low cost temperature sensor. It is directly calibrated in Degrees Celsius meaning that the output voltage is directly proportional to Degrees Celsius readings. Its measurement range is from -55°C to 150°C having typical accuracy(s) of 0.25°C at room temperature and 0.75°C for full range. LM35 also supports a wide range of supply voltage from 4V to 30V and is available in 4 different packages viz. TO-CAN, TO-92, SOIC and TO-220.
LM35 Pinout for TO-92 Package:
Pin 1 (+Vs) is the positive power supply pin, Pin 2 (VOUT) provides the output voltage linearly proportional to temperature and Pin 3 is for Ground.
LM35 can be configured in two ways:
- Basic Centigrade Temperature Sensor (2°C to 150°C)
- Full Range Centigrade Temperature sensor (-55°C to 150°C)
For the sake of simplicity, we will use LM35 in basic configuration. The first thing to note when interfacing LM35 with 3.3v MCUs is that LM35 has a supply voltage range of 4V to 30V. Hence, another supply of say 5V would be required to get proper readings. The second thing to note is that the output voltage has a scale factor of 10mV per Degree Centigrade and this is fixed irrespective of what supply voltage you use between 4V to 30V. Hence, the output voltage can go max up to 1.5V and as low as -55mV when configured as Full Range Centigrade Sensor.
When using the Basic configuration we have an output swing of ~0V(20mV) to 1.5V. So, if we use a VREF of 3.3 Volts we get a resolution of 3.3V/1024 = 0.00322V or 3.22mV since LPC2148 has a 10-bit ADC. Considering that LM35’s typical accuracy at room temperature(25°C) is 0.25°C (worst case accuracy = 0.5°C @ 25°C) and scale factor of 10mV/°C, a resolution of 3.22mV barely fits the bill. To get better resolution we can use a lower voltage reference like 1.8V or 2V. For example, using 1.8V reference we get a resolution of 1.75mV. For the interfacing example given below, we will assume a voltage reference of 3.3V which is commonly used on development boards. If these connections are not present on your development board please make sure VREF pin is connected to 3.3V.
LM35 Transfer Function & Output Conversion to °C
The formula for VOUT is given as:
Using the above formula, with VERF in Volts and Scale-factor in V/°C, we can compute the temperature(T) from 10-bit ADC Result as:
°C
Which can be simplified as,
°C
So, when using VREF = 3.3V we get,
°C
Example for LM35 Interfacing with ARM7 LPC2148
Now lets cover a simple programming example. As obvious, we will use the ADC block of LPC214x for interfacing our temperature sensor using reference voltage as mentioned above. We will use UART0 to send the data to terminal. You can refer my LPC2148 ADC Tutorial and UART Tutorial for more. The example project linked below also contains retargeted printf() for KEIL which redirects its output to UART0.
Interfacing Schematic:
Source code:
/*(C) Umang Gajera- www.ocfreaks.com
Interfacing LM35 with LPC2148 - Example Source Code for KEIL ARM.
Also see: https://www.ocfreaks.com/lpc2148-adc-programming-tutorial/
More Embedded tutorials @ www.ocfreaks.com/cat/embedded/
License: GPL.*/
#include <lpc214x.h>
#include <stdio.h> //visit https://www.ocfreaks.com/retarget-redirect-printf-scanf-uart-keil/
#include "lib_funcs.h" //OCFreaks LPC214x Tutorials Library Header
#define AD06 ((1<<9)|(1<<8)) //Select AD0.6 function for P0.4
#define SEL_AD06 (1<<6) //Select AD0.6 Channel
#define CLKDIV (15-1) //4Mhz ADC clock (ADC_CLOCK=PCLK/CLKDIV) where "CLKDIV-1" is actually used, in our case PCLK=60mhz
#define BURST_MODE_OFF (0<<16) //1 for on and 0 for off
#define PowerUP (1<<21)
#define START_NOW ((0<<26)|(0<<25)|(1<<24)) //001 for starting the conversion immediately
#define ADC_DONE (1UL<<31)
#define VREF 3.3 //Reference Voltage at VREF pin
int main(void)
{
initClocks(); //Set PCLK = CCLK = 60Mhz - used by: UART, Timer and ADC
initUART0(); //Initialize UART0 for retargeted printf()
initTimer0(); //Init Timer for delay functions
PINSEL0 |= AD06; //select AD0.6 for P0.4
unsigned long AD0CR_setup = (CLKDIV<<8) | BURST_MODE_OFF | PowerUP;
int result = 0;
float temp = 0;
printf("OCFreaks.com LPC214x LM35 Interfacing Tutorial\n");
AD0CR = AD0CR_setup | SEL_AD06; //Setup ADC block
AD0CR |= START_NOW; //Start new Conversion
while( (AD0DR6 & ADC_DONE) == 0 );
//Ignore the first ADC reading.
while(1)
{
AD0CR |= START_NOW; //Start new Conversion
while( (AD0DR6 & ADC_DONE) == 0 );
result = (AD0DR6>>6) & 0x3FF; //get the 10bit ADC result
temp = ((float)result * VREF * 100)/1024; //As per the Equation given in the tutorial
printf("Temp = %0.1f Deg. Celsius\n" , temp);
delayMS(1000); //1 Update per second
}
//return 0; //This won't execute normally
}
Screenshot:
Reference(s):