
PIC Microcontroller-Based Temperature Monitoring System
Overview
This project involves using a PIC16F877A microcontroller to read temperature data from an LM35 temperature sensor and display it on a 16×2 LCD. Such a system is useful in applications like home automation, industrial temperature monitoring, and weather stations.
Learning Objectives
- Understand how to interface an LM35 temperature sensor with a PIC microcontroller.
- Learn to display temperature readings on an LCD (HD44780 controller).
- Implement ADC (Analog-to-Digital Conversion) on the PIC16F877A.
- Develop C programming skills using MPLAB X IDE and XC8 compiler.
- Debug and troubleshoot microcontroller interfacing issues.
Required Tools and Components
Hardware:
- PIC16F877A Microcontroller
- LM35 Temperature Sensor
- 16×2 LCD Display (HD44780-compatible)
- 10kΩ Potentiometer (for LCD contrast adjustment)
- 4.7kΩ & 330Ω Resistors
- 22pF & 100nF Capacitors
- 20MHz Crystal Oscillator
- Breadboard & Jumper Wires
- 12V DC Adapter or Battery
- IC7805 Voltage Regulator
Software:
- MPLAB X IDE
- XC8 Compiler
- Proteus (for simulation, optional)
Background Information
LM35 Temperature Sensor
The LM35 outputs an analog voltage proportional to temperature. The output voltage follows the formula:
T (°C) = V_out × 100
Since LM35 provides 10mV per °C, a temperature of 30°C will result in 0.30V at the sensor output.
ADC in PIC16F877A
The PIC16F877A has a 10-bit ADC that converts the analog voltage to a digital value between 0 and 1023. The conversion formula is:
Digital Value = (V_in / V_ref) × 1023
With a V_ref of 5V, each ADC step represents 4.88mV.
Circuit Connections
- LM35 Output connects to AN0 (RA0) of the PIC16F877A.
- LCD Pins:
- RS → RD0 (Register Select)
- RW → RD1 (Read/Write, set to 0 for write)
- E → RD2 (Enable)
- D4-D7 → RD4-RD7 (4-bit data mode)
- Oscillator: A 20MHz crystal connects to pins 13 and 14.
- Power Supply: The microcontroller operates on +5V, regulated using an IC7805.
Source Code (XC8 for MPLAB X)
Below is the C program to read temperature from the LM35 and display it on an LCD.
#include <xc.h>
#include <stdio.h>
#define _XTAL_FREQ 20000000 // 20MHz Clock Frequency
// CONFIGURATION BITS
#pragma config FOSC = HS // High-speed Oscillator
#pragma config WDTE = OFF // Watchdog Timer disabled
#pragma config PWRTE = OFF // Power-up Timer disabled
#pragma config BOREN = ON // Brown-out Reset enabled
#pragma config LVP = OFF // Low Voltage Programming disabled
// Function prototypes
void ADC_Init();
unsigned int ADC_Read(unsigned char);
void LCD_Init();
void LCD_Command(unsigned char);
void LCD_Char(char);
void LCD_String(const char*);
void LCD_Clear();
void main() {
float temp;
char buffer[16];
ADC_Init(); // Initialize ADC
LCD_Init(); // Initialize LCD
while(1) {
unsigned int adc_value = ADC_Read(0); // Read from AN0 (RA0)
temp = (adc_value * 4.88) / 10.0; // Convert ADC value to temperature
sprintf(buffer, "Temp: %.2f C", temp);
LCD_Clear();
LCD_String(buffer);
__delay_ms(1000);
}
}
// ADC Initialization
void ADC_Init() {
ADCON0 = 0x41; // ADC ON, Select AN0 (RA0)
ADCON1 = 0x80; // Right justified result, Vref = VDD
}
// Read ADC value from given channel
unsigned int ADC_Read(unsigned char channel) {
ADCON0 &= 0xC5; // Clear channel selection bits
ADCON0 |= (channel << 3); // Select channel
__delay_ms(2); // Acquisition time
GO_nDONE = 1; // Start conversion
while(GO_nDONE); // Wait for conversion to complete
return ((ADRESH << 8) + ADRESL); // Return 10-bit result
}
// LCD Functions
void LCD_Init() { /* LCD initialization sequence */ }
void LCD_Command(unsigned char cmd) { /* Send command to LCD */ }
void LCD_Char(char data) { /* Send character to LCD */ }
void LCD_String(const char* str) { /* Send string to LCD */ }
void LCD_Clear() { LCD_Command(0x01); }
Testing and Troubleshooting
Common Issues and Solutions:
- LCD displays garbage characters: Verify wiring and ensure proper initialization.
- LCD not turning on: Adjust the 10kΩ potentiometer for contrast.
- Temperature always reads 0°C: Check ADC configuration.
- Display flickers: Add a 1-second delay after updating the LCD.
- Incorrect temperature readings: Verify the conversion formula (ADC * 4.88) / 10.
Extensions & Improvements
- Add a Buzzer: Sound an alarm when temperature exceeds a threshold.
- Use EEPROM Storage: Store max/min temperature values.
- Wireless Transmission: Send temperature data via Bluetooth (HC-05) or WiFi (ESP8266).
- Upgrade Display: Use an OLED display instead of a 16×2 LCD.
This project is an excellent introduction to PIC microcontrollers, ADC, and LCD interfacing, offering practical applications in real-world scenarios. Let me know if you need additional details or modifications!