Real-Time Temperature Display with LM35 & PIC16F877A
Real-Time Temperature Display with LM35 & PIC16F877A file 1hdzDLcNEMt3NuThnjwESR

Real-Time Temperature Display with LM35 & PIC16F877A

Project Overview

This project uses a PIC16F877A microcontroller to read temperature data from an LM35 temperature sensor and display it on a 16×2 LCD in real-time.

Troubleshooting Tips

  1. LCD Not Displaying Correctly
    • Ensure the contrast pin (V0) is properly adjusted.
    • Check LCD connections to PORTD.
  2. Temperature Not Updating
    • Confirm the LM35 sensor is correctly powered (VCC to 5V, GND to GND).
    • Verify ADC connections and initialization settings.
  3. Inaccurate Temperature Readings
    • Ensure correct ADC conversion factor (0.488 for 10-bit resolution).
    • Shield the sensor from external heat sources.

Let me know if you need modifications or further enhancements! 🚀

/*

Project: Temperature Monitoring System using PIC Microcontroller

Title: Real-Time Temperature Display with LM35 & PIC16F877A

Microcontroller: PIC16F877A

Sensor: LM35

LCD Display: 16×2 LCD (connected in 4-bit mode)

Compiler: MPLAB XC8

*/

#include <xc.h>

#define _XTAL_FREQ 20000000  // Define operating frequency for delay

// Define LCD Pins

#define RS RD0

#define EN RD1

#define D4 RD2

#define D5 RD3

#define D6 RD4

#define D7 RD5

// Function Prototypes

void LCD_Command(unsigned char);

void LCD_Char(unsigned char);

void LCD_Init();

void LCD_String(const char*);

void ADC_Init();

unsigned int ADC_Read(unsigned char);

void main() {

    unsigned int adc_value;

    float temperature;

    char temp_str[10];

    TRISA = 0xFF; // Configure PORTA as input (for ADC)

    TRISD = 0x00; // Configure PORTD as output (for LCD)

    ADC_Init();   // Initialize ADC

    LCD_Init();   // Initialize LCD

    LCD_String(“Temp: “);

    while(1) {

        adc_value = ADC_Read(0); // Read ADC value from channel 0

        temperature = adc_value * 0.488; // Convert ADC value to temperature

        sprintf(temp_str, “%.2f C”, temperature); // Convert float to string

        LCD_Command(0x86); // Move cursor to display temperature

        LCD_String(temp_str);

        __delay_ms(500);

    }

}

void ADC_Init() {

    ADCON0 = 0x41;  // Enable ADC, select channel 0

    ADCON1 = 0x80;  // Configure result format and voltage reference

}

unsigned int ADC_Read(unsigned char channel) {

    ADCON0 &= 0xC5; // Clear existing channel selection

    ADCON0 |= (channel << 3); // Select ADC channel

    __delay_ms(2); // Acquisition time delay

    GO_nDONE = 1; // Start ADC conversion

    while(GO_nDONE); // Wait for conversion to finish

    return ((ADRESH << 8) + ADRESL); // Return 10-bit ADC result

}

void LCD_Command(unsigned char cmd) {

    RS = 0;

    D4 = (cmd >> 4) & 1;

    D5 = (cmd >> 3) & 1;

    D6 = (cmd >> 2) & 1;

    D7 = (cmd >> 1) & 1;

    EN = 1;

    __delay_ms(1);

    EN = 0;

    D4 = cmd & 1;

    D5 = (cmd >> 7) & 1;

    D6 = (cmd >> 6) & 1;

    D7 = (cmd >> 5) & 1;

    EN = 1;

    __delay_ms(1);

    EN = 0;

}

void LCD_Char(unsigned char data) {

    RS = 1;

    D4 = (data >> 4) & 1;

    D5 = (data >> 3) & 1;

    D6 = (data >> 2) & 1;

    D7 = (data >> 1) & 1;

    EN = 1;

    __delay_ms(1);

    EN = 0;

    D4 = data & 1;

    D5 = (data >> 7) & 1;

    D6 = (data >> 6) & 1;

    D7 = (data >> 5) & 1;

    EN = 1;

    __delay_ms(1);

    EN = 0;

}

void LCD_Init() {

    LCD_Command(0x02); // Initialize LCD in 4-bit mode

    LCD_Command(0x28); // 2 lines, 5×7 matrix

    LCD_Command(0x0C); // Display on, cursor off

    LCD_Command(0x06); // Increment cursor

    LCD_Command(0x01); // Clear screen

    __delay_ms(2);

}

void LCD_String(const char *str) {

    while(*str) {

        LCD_Char(*str);

        str++;

    }

}