Project Title: Digital Thermometer with LCD Using PIC16F877A
Project Title: Digital Thermometer with LCD Using PIC16F877A f755db7d 4e50 494e 9ccb b0bc1553

Project Title: Digital Thermometer with LCD Using PIC16F877A


1. Introduction

In this project, you’ll build a digital thermometer using the PIC16F877A microcontroller and the LM35 temperature sensor. The measured temperature will be displayed on a 16×2 LCD in Celsius format.

Real-world applications include:

  • Home automation
  • Weather monitoring systems
  • Environmental control units in HVAC

2. Learning Objectives

Through this project, you will learn to:

  • Read analog sensor data using the ADC module of a PIC microcontroller.
  • Display real-time data on an LCD.
  • Perform voltage-to-temperature conversion based on sensor output.
  • Understand embedded C programming using MPLAB X and XC8 compiler.

3. Tools and Components

Microcontroller and Peripherals:

  • 1x PIC16F877A Microcontroller
  • 1x 16×2 LCD Display
  • 1x LM35 Temperature Sensor

Support Components:

  • 1x 10kΩ Potentiometer (for LCD contrast)
  • 1x 10kΩ Resistor (pull-up for MCLR if needed)
  • 1x 20 MHz Crystal Oscillator
  • 2x 22pF Ceramic Capacitors

Additional Items:

  • Breadboard and jumper wires
  • MPLAB X IDE and XC8 Compiler
  • PICkit 3/4 Programmer

4. Background and Definitions

PIC16F877A
A popular 40-pin 8-bit microcontroller featuring:

  • Multiple I/O ports
  • 10-bit ADC with selectable input channels
  • Compatible with standard external oscillators

LM35 Sensor
An analog sensor that provides:

  • 10mV output per 1°C temperature increase
  • Linear voltage-temperature relationship

16×2 LCD Module
A character display module that shows:

  • 2 lines of 16 characters each
  • Interfaced in either 4-bit or 8-bit mode (this project uses 4-bit)

5. Step-by-Step Guide

Wiring Instructions

LCD Connections (using 4-bit mode):

  • VSS → GND
  • VDD → +5V
  • V0 → Middle pin of potentiometer (contrast adjustment)
  • RS → RC0
  • RW → GND
  • EN → RC1
  • D4 → RC2
  • D5 → RC3
  • D6 → RC4
  • D7 → RC5

LM35 Sensor:

  • V+ → +5V
  • Output → RA0 (Analog channel 0)
  • GND → GND

Crystal Oscillator Setup:

  • Crystal connected between pins 13 (OSC1) and 14 (OSC2)
  • One 22pF capacitor from each pin to ground

Embedded C Code (MPLAB X with XC8 Compiler)

#include <xc.h>
#include <stdio.h>

// Configuration bits
#pragma config FOSC = HS, WDTE = OFF, PWRTE = OFF, BOREN = ON, LVP = OFF, CPD = OFF, WRT = OFF, CP = OFF

#define _XTAL_FREQ 20000000

// LCD control pins
#define RS RC0
#define EN RC1
#define LCD PORTC

void lcd_cmd(char cmd);
void lcd_init();
void lcd_data(char data);
void lcd_print(const char *str);

void ADC_Init();
unsigned int ADC_Read(unsigned char channel);

void main() {
    char buffer[16];
    unsigned int adc_value;
    float temperature;

    TRISA = 0x01;  // RA0 as input (AN0)
    TRISC = 0x00;  // PORTC as output
    ADC_Init();
    lcd_init();

    while (1) {
        adc_value = ADC_Read(0);
        temperature = adc_value * 0.488; // Convert ADC value to Celsius

        lcd_cmd(0x80);
        lcd_print("Temp: ");
        sprintf(buffer, "%.2f C", temperature);
        lcd_print(buffer);

        __delay_ms(1000);
    }
}

void lcd_cmd(char cmd) {
    RS = 0;
    LCD = (LCD & 0x0F) | (cmd & 0xF0);
    EN = 1; __delay_ms(2); EN = 0;
    LCD = (LCD & 0x0F) | ((cmd << 4) & 0xF0);
    EN = 1; __delay_ms(2); EN = 0;
}

void lcd_data(char data) {
    RS = 1;
    LCD = (LCD & 0x0F) | (data & 0xF0);
    EN = 1; __delay_ms(2); EN = 0;
    LCD = (LCD & 0x0F) | ((data << 4) & 0xF0);
    EN = 1; __delay_ms(2); EN = 0;
}

void lcd_init() {
    lcd_cmd(0x02);
    lcd_cmd(0x28);
    lcd_cmd(0x0C);
    lcd_cmd(0x06);
    lcd_cmd(0x01);
}

void lcd_print(const char *str) {
    while (*str) {
        lcd_data(*str++);
    }
}

void ADC_Init() {
    ADCON0 = 0x01; // Channel 0, ADC ON
    ADCON1 = 0xC0; // Right justified
}

unsigned int ADC_Read(unsigned char channel) {
    ADCON0 &= 0xC5;
    ADCON0 |= channel << 3;
    __delay_ms(2);
    GO_nDONE = 1;
    while (GO_nDONE);
    return ((ADRESH << 8) + ADRESL);
}

6. Testing and Debugging Tips

If the LCD does not show any text:

  • Adjust the contrast via the potentiometer
  • Confirm RS/EN and data pin connections are correct
  • Check the initialization sequence in code

If the temperature seems inaccurate:

  • Ensure your VDD is a stable 5V
  • Confirm the LM35 output is properly routed to RA0
  • Recalculate the scaling factor if using a different reference voltage

If the microcontroller is unresponsive:

  • Verify crystal oscillator connections and power supply
  • Check your programmer’s connection and hex upload

7. Project Extensions and Enhancements

  • Add a push-button to toggle between Celsius and Fahrenheit.
  • Log the temperature values on an SD card using SPI.
  • Use a Bluetooth module (e.g., HC-05) to send data to a mobile app.
  • Upgrade to a graphical OLED or TFT for dynamic data visualization.