Temperature Monitoring System using PIC16F877A
Temperature Monitoring System using PIC16F877A file 8LCKJv1LGYCuaYWHdiNSo6

Temperature Monitoring System using PIC16F877A

Introduction

This project implements a temperature monitoring system using a PIC16F877A microcontroller and an LM35 temperature sensor. The system reads the temperature, displays it on a 16×2 LCD, and turns on an LED alert if the temperature exceeds a set threshold.

Real-World Applications

  • Home automation (smart thermostats)
  • Industrial temperature control
  • Medical equipment monitoring

Learning Objectives

By completing this project, you will learn:
✅ How to interface an LM35 temperature sensor with a PIC16F877A
✅ How to read analog signals using the ADC (Analog-to-Digital Converter)
✅ How to display data on a 16×2 LCD in 4-bit mode
✅ How to implement an LED-based alert system


Required Components & Tools

Electronic Components

  • PIC16F877A microcontroller
  • LM35 temperature sensor
  • 16×2 LCD display
  • 10kΩ potentiometer (for LCD contrast adjustment)
  • 220Ω resistor
  • LED (Red) for temperature warning
  • Breadboard & Jumper wires
  • 5V DC power supply

Software & Programming Tools

  • MPLAB X IDE
  • XC8 Compiler
  • PICkit 3/4 for programming

Background Concepts

LM35 Temperature Sensor

  • Analog output proportional to temperature
  • 10mV per °C (e.g., 25°C → 250mV)
  • Requires ADC conversion to process data

ADC in PIC16F877A

  • Converts analog signals to digital values (0-1023)
  • 10-bit resolution
  • Formula for temperature calculation: Temperature(°C)=(ADC Value1024)×500Temperature (°C) = \left( \frac{ADC\ Value}{1024} \right) \times 500Temperature(°C)=(1024ADC Value​)×500

Interfacing a 16×2 LCD in 4-bit Mode

  • Uses RS (Register Select), RW (Read/Write), and E (Enable) pins
  • Displays real-time temperature readings

Circuit Wiring

Key Connections

LM35 to PIC16F877A:

  • VCC → 5V
  • GND → GND
  • Vout → RA0 (AN0) (ADC input)

LCD to PIC16F877A (4-bit mode):

  • RS → RD0
  • E → RD1
  • D4-D7 → RD2-RD5 (data pins)
  • VEE (Contrast) → 10kΩ potentiometer

LED Alert:

  • Anode → RC0 (Output pin)
  • Cathode → GND (via 220Ω resistor)

Step-by-Step Implementation

1. Circuit Wiring

  • Connect LM35 sensor to RA0 (AN0)
  • Connect LCD in 4-bit mode
  • Attach LED to RC0

2. Writing the Code (MPLAB XC8)

Here’s the fully commented C code:

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

#define _XTAL_FREQ 20000000 // 20MHz Crystal

// Configuration bits
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF

// 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(char);
void LCD_Char(char);
void LCD_Init();
void LCD_String(const char*);
void ADC_Init();
int ADC_Read(int);
void Display_Temperature();

void main() {
TRISA = 0xFF; // Set Port A as input (LM35)
TRISD = 0x00; // Set Port D as output (LCD)
TRISC0 = 0; // RC0 as output (LED)

LCD_Init(); // Initialize LCD
ADC_Init(); // Initialize ADC

while(1) {
Display_Temperature();
__delay_ms(500); // Small delay for stability
}
}

// Function to send command to LCD
void LCD_Command(char cmd) {
RS = 0; // Command mode
D4 = (cmd >> 4) & 0x01;
D5 = (cmd >> 3) & 0x01;
D6 = (cmd >> 2) & 0x01;
D7 = (cmd >> 1) & 0x01;
EN = 1;
__delay_ms(2);
EN = 0;
}

// Function to send character to LCD
void LCD_Char(char data) {
RS = 1; // Data mode
D4 = (data >> 4) & 0x01;
D5 = (data >> 3) & 0x01;
D6 = (data >> 2) & 0x01;
D7 = (data >> 1) & 0x01;
EN = 1;
__delay_ms(2);
EN = 0;
}

// Function to initialize LCD
void LCD_Init() {
LCD_Command(0x02); // 4-bit mode
LCD_Command(0x28); // 2 lines, 5x8 matrix
LCD_Command(0x0C); // Display on, cursor off
LCD_Command(0x06); // Shift cursor right
LCD_Command(0x01); // Clear display
}

// Function to display a string on LCD
void LCD_String(const char* str) {
while(*str) {
LCD_Char(*str++);
}
}

// Function to initialize ADC
void ADC_Init() {
ADCON1 = 0x80; // Right justified, Vref = VDD
ADCON2 = 0x89; // Acquisition time, Fosc/8
ADCON0 = 0x01; // Enable ADC
}

// Function to read ADC value
int ADC_Read(int channel) {
ADCON0 &= 0xC3;
ADCON0 |= (channel << 3);
__delay_ms(2);
GO_nDONE = 1;
while(GO_nDONE);
return ((ADRESH << 8) + ADRESL);
}

// Function to display temperature
void Display_Temperature() {
int adc_value = ADC_Read(0); // Read from AN0
float temperature = adc_value * 0.488; // Convert ADC to Celsius

char temp_str[16];
sprintf(temp_str, "Temp: %.1f C", temperature);

LCD_Command(0x80); // Move to first row
LCD_String(temp_str);

if(temperature > 30.0) { // Temperature threshold
RC0 = 1; // Turn on LED
} else {
RC0 = 0; // Turn off LED
}
}

Troubleshooting & Debugging Tips

LCD Not Displaying?

  • Check contrast adjustment using the 10kΩ potentiometer
  • Ensure correct pin connections (RS, RW, Enable, Data pins)

Incorrect Temperature Readings?

  • Verify LM35 sensor wiring (VCC, GND, Output to AN0)
  • Use a stable 5V power source

LED Not Turning On?

  • Check RC0 is set as an output (TRISC0 = 0;)

Extensions & Improvements

💡 Add a buzzer for a sound alert when temperature is high
💡 Send temperature data via Bluetooth/WiFi for IoT applications
💡 Log temperature values on an SD card for data analysis