LM35 Temperature Sensor with 7-Segment Display using Pic Microcontroller

In this tutorial, we will design a digital temperature sensor using LM35 sensor and PIC16F877A microcontroller. Unlike the previous posts, we will use 7-segment displays to print measured temperature values in the Celsius scale. You can use other types of temperature sensors also. This is also known as a digital thermometer with a seven-segment display. You can read our last tutorial where we used 16X2 LCD to print temperature using PIC16F877A microcontroller.

Prerequisites

In order to completely understand the LM35 temperature sensor with 7-segment, you should have some basic background of PIC microcontroller features such as the ADC module and 7-segment displays interfacing with Pic microcontroller. Therefore, I recommend reading these posts:

LM35 Temperature Sensor Introduction

Let’s begin with the introduction of an LM35 temperature sensor. It provides temperature in the range of -55°C to 150°C.  Furthermore, it supports a wide operating voltage range between -2 to 35 volts. But we usually use volts supply while interfacing with microcontrollers such as PIC16F877A.  On top of these features, it draws only 60uA current and temperature accuracy is ±0.5°C .

Pinout Diagram

This picture shows the pinout diagram of LM35 temperature sensor. It consists of three terminals which makes it easy to use with microcontrollers.

LM35 temperature sensor pinout diagram

 Pin description is given in the table below:

Pin NumberNameFunctionality
1VccConnect voltage supply to this pin (Usually 5 volts)
2VoutOutput voltage pin ( Connect with Microcontroller ADC)
3GroundGround reference

How to convert output voltage into temperature?

Its output is analog voltage. Most importantly, output voltage and temperature are directly proportional to each other and response of sensor is linear. That means that the voltage on output pin rise linearly with respect to temperature surrounding. This equation is used to determine the correlation between output voltage and temperature:

1°C = 10mv

Above equation simply means that for every 10mV increase in output voltage there will be 1 degree increase in temperature. In other words, whenever, the temperature of surrounding rise by 1°C, the output voltage also increases by 10mV.

Hence, if we can compute output voltage of LM35 temperature sensor, we can convert it into temperature (degrees Celsius) by using above equation. Therefore, we rewrite above equation like this:

1mv = 1/10 degree Celsius 
1v = 100 degree Celsius

For example, if the output voltage of LM35 temperature sensor is 225mv. Therefore, according to above equation, the temperature value is 22.5 degree Celsius.

LM35 Based Digital Thermometer Circuit diagram

This circuit diagram shows the connection between the LM35 temperature sensor, PIC16F877A microcontroller, and 4-digit seven-segment display. You should make connections according to this schematic and if you want to change pins, you should also make changes in the code. But do it only if you fully understand the interfacing circuit and program.

LM35 temperature sensor with 7-segment display using pic microcontroller

Connection between LM35 and PIC16F877A Microcontroller

We will use PIC16F877A microcontroller in this project. It has a built-in ADC module and each analog to digital converter channel is of 10-bit. That means it can measure a minimum voltage of 4.88mV which is less than 10mV. Hence, we can easily measure 10mV with ADC of PIC16F877A microcontroller without using any amplifier circuit. Because the minimum voltage that we can measure with PIC16F877A ADC is more than the two times the minimum voltage output of LM35 temperature sensor. Therefore, we do not require any interfacing circuit between temperature sensor and PIC16F877A microcontroller.

PIC16F877ALM35
+5 VoltsVcc
AN0/RA0Vout
Ground pinGround

For further information on how to use PIC microcontroller ADC, read this article:

  • How to use PIC Microcontroller ADC Module

Connection with 4-digit 7-segment display

As you can depict from above circuit diagram, We connected PORTD 8 pins from RD0-RD8 with a-g segments of 4-digit 7-segment display. Because we send display codes to each seven segment from microcontroller GPIO pins and also four control lines to select seven-segment digit.

We use four-digit 7-segment display. Because we want to print both decimal and fractional values of temperature. 4-digit display can print numbers between 0-9999. Hence, we will use two 7-segments to display decimal value and remaining two for printing fractional values.

Here we used pin multiplexing method to control four 7-segments with 7 GPIO pins of PIC16F877A microcontroller. If we do not use multiplexing method, we will need 7×4=28 pins to interface with PIC16F877A microcontroller. But it will be wastage of microcontroller GPIO pins and also not all pic microcontroller have that too many pins available. Hence, by using multiplexing method, we can save almost 16 GPIO pins of microcontroller and we can drive 4-digit 7-segment device with 12 pins only.

  • 7 pins for a-g and one for dp
  • 4 pins for common anode or common anode terminal of 7-segments.

Now make the connections of 4-digit seven-segment with PIC16F877A microcontroller according to this table:

PIC16F877A PORTD4-digit 7-Segment display pins
RD0Segment-A
RD1Segment-B
RD2Segment-C
RD3Segment-D
RD4Segment-E
RD5Segment-F
RD6Segment-G
RD7DIP
PIC16F877A4-Digit Display pins
RB01
RB12
RB23
RB34

To explore further on 7-segments displays interfacing and how to achieve multiplexing, you can read this in-depth guide:

  • Interfacing 7-Segment displays with Pic Microcontroller

MikroC Code

This code is written using MikroC for Pic compiler.  Create a new project with MikroC compiler by selecting PIC16F877A microcontroller and set frequency to 8MHz. If you don’t know how create new project in mikroC, we suggest you read this post:

// define name to each control signal for 7-segment
sbit digit1 at PORTB.B0;
sbit digit2 at PORTB.B1;
sbit digit3 at PORTB.B2;
sbit digit4 at PORTB.B3;
// This array stores binary bit pattern that will be send to PORTD
unsigned char binary_pattern[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; // without Dp turn
unsigned char display1[10]= {0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xE7};    // with dp turn on

// variables to store digits, digital value and output voltage
unsigned int a1,a2,a3,a4; // temporary variables to store data of adc
int adc_value; //store output value from Analog Read functoion
unsigned int number;
long tlong;
unsigned int voltage;

// this function retrive each digita that will displayed on device
void get_digits()
  {
           a1 =  voltage / 1000u;   // holds 1000's digit
           a2 = ((voltage/100u)%10u); // holds 100's digit
           a3 = ((voltage/10u)%10u);  // holds 10th digit
           a4 = (voltage%10u);  // holds unit digit value
   }

// this function displays measured voltage on seven-segments
void display_voltage()
 {
            PORTD = binary_pattern[a2]; // send 1000's place data to fourth digit
            digit1 = 0;   //  turn on forth display unit
            delay_ms(3);
            digit1 = 1;   //  turn off forth display unit
            PORTD = display1[a3];  // send 100's place data to 3rd digit
            digit2 = 0;    //  turn on 3rd display unit
            delay_ms(3);
            digit2 = 1;  //  turn off 3rd display unit
            PORTD = binary_pattern[a4];  // send 10th place data to 2nd digit
            digit3 = 0;  //  turn on 2nd display unit
            delay_ms(3);
            digit3 = 1;   //  turn off 2nd display unit
            PORTD=binary_pattern[a1];  // send unit place data to 1st digit
            digit4 = 0;  //  turn on 1st display unit
            delay_ms(3);
            digit4 = 1;  //  turn off 1st display unit
   }
void interrupt()
{

            get_digits();   // call function to split data
            display_voltage(); //call display_data() function to output value to seven segment

            T0IF_bit = 0;  // clear source of timer0 interrupt
}
void main(void)
{
    TMR0   = 0;         // timer0 reset bit
    OPTION_REG = 0x83;  // select prescalar value 1:16 for timer0
    INTCON = 0xA0;      // turn on global interrupt and timer0 overflow interrupt
    TRISD = 0x00; //define PORTD as a output pin
    PORTD=0x00;   // initialize PORTD pins to active low
    TRISB=0x00;// Set PORTB as a output port
  // set control pins pins initially active high
    digit1 = 1;
    digit2 = 1;
    digit3 = 1;
    digit4 = 1;

    while(1)
    {

           adc_value = ADC_Read(0);  // read data from channel 0
           tlong = (float)adc_value*4.88768555; //converts voltage into temperature
           voltage = tlong;


    }

}

How code works?

The working of a digital temperature sensor with a 7-segment display code is the same as the working of the digital dc voltmeter project with 7-segment display. The only difference is the conversion of voltage into temperature.

First we start by defining RA0/AN0 pin of PIC16F877A microcontroller as an analog pin. This line reads output volage of LM35 temperature sensor and store its value inside a “adc_value” variable.

adc_value = ADC_Read(0);  // read data from channel 0

After that, we should convert ADC measured digital value into temperature. We multiply the adc_value variable with ‘4.88768555’. Here 4.88768555 comes from (5 x 1000) /1023. Here 5000/1023 converts the voltage into millivolts and again divided by 10 will get us a temperature value. Because of 10mv=1 degree celsius.

tlong = (float)adc_value*4.88768555; //converts voltage into temperature 

We define a global variable “voltage” that will be used to split data for each digit and print its value on a 7-segment display. This line stores the value of “tlong” in “voltage” variable. Global variables are defined when we want to use them anywhere in the whole program. Hence we can use “voltage” anywhere in the program.

 voltage = tlong;

Proteus Simulation

We used proteus simulation software to simulate this circuit. As you can observe from this circuit, as soon as we are changing temperature sensor value, PIC16F877A microcontroller outputs temperature sensor value on four digit 7-segment display.

MPLAB XC8 Code

This code is for MPLAB XC8 Compiler. If you don’t know how to use MPLAB and XC8 compiler, you can read this complete in-depth guide:

After creating a new project, set configuration bits by generating configuration bit file with MPLAB XC8. While generating this file, select the HS crystal option and leave the remaining setting as to default settings.

#include <xc.h>
#define _XTAL_FREQ 20000000 //define crystal frequency to 20MHz
#define digit1 PORTBbits.RB0
#define digit2 PORTBbits.RB1
#define digit3 PORTBbits.RB2
#define digit4 PORTBbits.RB3
// This array stores binary bit pattern that will be send to PORTD
unsigned char binary_pattern[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char display1[10]= {0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xE7};    // with dp turn on
unsigned int a1,a2,a3,a4;
unsigned int counter = 0;
int adc_value; //store output value from Analog Read functoion
unsigned int number;
long tlong;
unsigned int voltage;
void Analog_setting(){
    ADCON0 = 0x81;
    ADCON1 = 0x02;
}

unsigned int Analog_read(unsigned char channel){
    int aadc,bbdc, ccdc;
    if(channel>7)return 0;
    ADCON0 = ADCON0 & 0xC5;
    ADCON0 = ADCON0 | (channel << 3);
    __delay_ms(2);
    ADCON0bits.GO_DONE = 1;
    while(ADCON0bits.GO_DONE);
    aadc = ADRESH;
    aadc = aadc<<2;
    bbdc = ADRESL;
    bbdc = bbdc >>6;
    ccdc = aadc|bbdc;
    return ccdc;

}
void main(void) 
{
    Analog_setting();
    TRISD = 0x00; //define PORTD as a output pin
    PORTD=0X00;   // initialize PORTD pins to active low
    TRISB=0X00;
    digit1 = 1;
    digit2 = 1; 
    digit3 = 1;
    digit4 = 1;
    while(1)
    {
          adc_value = Analog_read(0);  // read data from channel 0
           tlong = (float)adc_value*4.88768555;
           voltage = tlong;
        
           a1 = voltage / 1000;   // holds 1000's digit
           a2 = ((voltage/100)%10); // holds 100's digit
           a3 = ((voltage/10)%10);  // holds 10th digit
           a4 = (voltage%10);  // holds unit digit value
           
        
PORTD=binary_pattern[a2]; // send 1000's place data to fourth digit
digit1=0;   //  turn on forth display unit
__delay_ms(3);
digit1=1;   //  turn off forth display unit
PORTD=display1[a3];  // send 100's place data to 3rd digit
digit2=0;    //  turn on 3rd display unit
__delay_ms(3);
digit2=1;  //  turn off 3rd display unit
PORTD=binary_pattern[a4];  // send 10th place data to 2nd digit
digit3 = 0;  //  turn on 2nd display unit
__delay_ms(3);
 digit3 = 1;   //  turn off 2nd display unit
PORTD=binary_pattern[a1];  // send unit place data to 1st digit
digit4 = 0;  //  turn on 1st display unit
__delay_ms(3);
digit4 = 1;  //  turn off 1st display unit


    }
    return ;
}

Related Projects

4 thoughts on “LM35 Temperature Sensor with 7-Segment Display using Pic Microcontroller”

Leave a Comment