
PIC Microcontroller Project: Temperature Monitoring System with LCD Display
1. Introduction
This project demonstrates how to design a temperature monitoring system using a PIC microcontroller, a temperature sensor (LM35), and a 16×2 LCD display. The system measures temperature in real-time and displays it on the LCD. It can be used in applications like environmental monitoring, industrial temperature control, and home automation systems.
2. Learning Objectives
- Understand how to interface an LM35 temperature sensor with a PIC microcontroller.
- Learn how to configure and use the ADC (Analog-to-Digital Converter) module in PIC.
- Interface and program a 16×2 LCD display to show real-time data.
- Gain practical skills in debugging and troubleshooting embedded systems.
3. Tools and Components
- Hardware:
- PIC microcontroller (e.g., PIC16F877A or PIC16F887)
- LM35 temperature sensor
- 16×2 LCD display
- 10kΩ potentiometer (for LCD contrast adjustment)
- 10µF and 0.1µF capacitors
- 7805 voltage regulator (for 5V supply)
- Resistors (330Ω for LCD backlight)
- Breadboard and connecting wires
- Power supply (5V)
- Oscilloscope or multimeter (for testing)
- Software:
- MPLAB X IDE
- XC8 compiler
- Proteus (optional, for simulation)
4. Background/Definitions
- LM35 Sensor: A precision temperature sensor with an analog voltage output proportional to the temperature (10mV per °C).
- ADC: Converts the analog signal from LM35 into a digital value that the PIC microcontroller can process.
- LCD Display: A 16×2 alphanumeric display used for outputting text or numeric data.
5. Step-by-Step Guide
Step 1: Circuit Design
- Connect the LM35 sensor:
- VCC pin to 5V.
- GND pin to GND.
- Output pin to the analog input channel (e.g., RA0/AN0) of the PIC.
- Connect the LCD:
- Data pins (D4–D7) to PORTD (e.g., RD0–RD3).
- Control pins:
- RS to RB0
- RW to GND
- E to RB1
- Adjust contrast using a 10kΩ potentiometer connected to the VEE pin of the LCD.
- Add bypass capacitors (10µF and 0.1µF) near the power pins of the PIC for stability.
- Ensure a regulated 5V power supply to the circuit using a 7805 voltage regulator.
Circuit Diagram: (Describe connections or provide visual details to recreate the setup accurately.)
Step 2: Programming
Here’s the annotated source code:
cCopy code#include <xc.h>
#define _XTAL_FREQ 8000000 // Define oscillator frequency for delay
// Configuration bits
#pragma config FOSC = HS // High-speed oscillator
#pragma config WDTE = OFF // Watchdog Timer disabled
#pragma config PWRTE = ON // Power-up Timer enabled
#pragma config BOREN = ON // Brown-out Reset enabled
#pragma config LVP = OFF // Low-Voltage Programming disabled
#pragma config CPD = OFF // Data EEPROM memory code protection disabled
#pragma config WRT = OFF // Flash Program Memory Write Protection off
#pragma config CP = OFF // Flash Program Memory Code Protection off
// Function prototypes
void ADC_Init();
unsigned int ADC_Read(unsigned char channel);
void LCD_Init();
void LCD_Command(unsigned char cmd);
void LCD_Char(unsigned char data);
void LCD_String(const char *str);
void Display_Temperature(unsigned int temp);
void main() {
unsigned int adcValue;
float temperature;
ADC_Init(); // Initialize ADC
LCD_Init(); // Initialize LCD
while(1) {
adcValue = ADC_Read(0); // Read analog value from channel 0
temperature = adcValue * 0.488; // Convert ADC value to temperature (LM35 scale: 10mV/°C)
// Display temperature on LCD
LCD_Command(0x80); // Move cursor to first line
LCD_String("Temp: ");
Display_Temperature((unsigned int)temperature);
LCD_String(" C");
__delay_ms(1000); // Refresh every second
}
}
void ADC_Init() {
ADCON0 = 0x01; // ADC enabled, channel 0 selected
ADCON1 = 0x0E; // Configure AN0 as analog, others as digital
ADRESH = 0; // Clear ADC result registers
ADRESL = 0;
}
unsigned int ADC_Read(unsigned char channel) {
ADCON0 &= 0xC5; // Clear previous 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 complete
return ((ADRESH << 8) + ADRESL); // Return 10-bit ADC result
}
void LCD_Init() {
// Initialize LCD in 4-bit mode
LCD_Command(0x02);
LCD_Command(0x28);
LCD_Command(0x0C);
LCD_Command(0x06);
LCD_Command(0x01);
}
void LCD_Command(unsigned char cmd) {
PORTD = (cmd & 0xF0); // Send upper nibble
RB0 = 0; // RS = 0 for command
RB1 = 1; // Enable high
__delay_ms(1);
RB1 = 0; // Enable low
PORTD = ((cmd << 4) & 0xF0); // Send lower nibble
RB1 = 1; // Enable high
__delay_ms(1);
RB1 = 0; // Enable low
}
void LCD_Char(unsigned char data) {
PORTD = (data & 0xF0); // Send upper nibble
RB0 = 1; // RS = 1 for data
RB1 = 1; // Enable high
__delay_ms(1);
RB1 = 0; // Enable low
PORTD = ((data << 4) & 0xF0); // Send lower nibble
RB1 = 1; // Enable high
__delay_ms(1);
RB1 = 0; // Enable low
}
void LCD_String(const char *str) {
while (*str) {
LCD_Char(*str++);
}
}
void Display_Temperature(unsigned int temp) {
LCD_Char((temp / 100) + '0'); // Hundreds place
temp %= 100;
LCD_Char((temp / 10) + '0'); // Tens place
LCD_Char((temp % 10) + '0'); // Units place
}
6. Testing and Debugging Tips
- LCD Display Issues:
- Ensure the contrast potentiometer is adjusted for clear visibility.
- Verify correct wiring for RS, RW, E, and data pins.
- ADC Reading Incorrect:
- Check the voltage at the LM35 output using a multimeter.
- Ensure the ADC reference voltage is stable and matches the configured range.
- Temperature Value Incorrect:
- Verify the LM35 is connected correctly.
- Check the conversion formula (
0.488factor may vary slightly based on ADC resolution and Vref).
- System Not Powering On:
- Ensure the 7805 regulator output is 5V.
- Use bypass capacitors to filter noise in the power supply.
7. Extensions
- Add a buzzer to alert when the temperature exceeds a set threshold.
- Use a serial interface (UART) to log temperature data to a PC.
- Replace the LM35 with a digital sensor like DHT11 or DS18B20.
- Implement a graphical user interface using an OLED display for advanced monitoring.
This complete guide ensures a smooth learning experience while building a robust temperature monitoring system.