
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.