Pimpri Chinchwad College Of Engineering
Academic Year 2025-26
Semester – 5
Course – Advanced Microcontroller and Interfacing techniques
Subject Code – BET25MD01
Formative Assessment – 1
Topic – Smart Temperature Monitoring and Control System
Report By- Atharva Mujumdar (123B1G070)
1. Introduction
In the age of automation, the need for intelligent environmental control systems is
paramount. Many industrial processes, agricultural systems, and even domestic
environments require precise temperature regulation to ensure safety, efficiency, and
comfort. This project details the design and simulation of a "Smart Temperature Monitoring
and Control System" using the versatile PIC18F4520 microcontroller. The system provides a
closed-loop control mechanism, capable of sensing ambient temperature, displaying it for
the user, and automatically actuating control elements like a fan and an alarm based on a
user-defined setpoint. This project serves as a practical demonstration of core embedded
systems concepts, including analog-to-digital conversion, device interfacing, and real-time
control logic.
2. Problem Statement
Manual monitoring and control of temperature in sensitive environments is often inefficient,
prone to human error, and lacks immediate responsiveness. In scenarios like server rooms,
greenhouses, or medical storage, a failure to maintain temperature within a specific range
can lead to equipment damage, loss of produce, or spoilage of sensitive materials.
Therefore, there is a need for an automated system that can continuously monitor
temperature, compare it against a critical threshold, and trigger corrective actions without
human intervention.
3. Objectives
The primary objectives of this project are:
• To interface an LM35 analog temperature sensor with the PIC18F4520
microcontroller to accurately measure ambient temperature.
• To implement the Analog-to-Digital Converter (ADC) module of the PIC to convert the
sensor's analog output into a digital value.
• To interface a 16x2 character LCD to display the real-time temperature and the user-
defined setpoint temperature.
• To allow the user to adjust the setpoint temperature using push buttons.
• To develop a control logic that activates a cooling fan (simulated by an LED) and an
alarm (simulated by a buzzer and LED) when the measured temperature exceeds the
setpoint.
• To build and validate the entire system through a software simulation using Proteus
Design Suite.
4. Simulation Model Description
The system was modeled and simulated in Proteus. The circuit consists of the following key
components:
• PIC18F4520 Microcontroller: This is the central processing unit of the system. It is
responsible for executing the control program, reading sensor data, processing it,
displaying information on the LCD, and controlling the output devices. It is operated
with a 20MHz crystal oscillator.
• LM35 Temperature Sensor: An analog sensor that outputs a voltage linearly
proportional to the temperature in Celsius (10mV per degree Celsius). Its output is
connected to the microcontroller's ADC pin (AN0).
• 16x2 Character LCD: This display is connected in 4-bit mode to the microcontroller's
PORTD and PORTC. It serves as the primary user interface, showing the current
temperature and the setpoint.
• Push Buttons: Two buttons are connected to PORTB, allowing the user to increment
or decrement the temperature setpoint.
• Output Devices:
o A Green LED simulates the cooling fan.
o A Red LED and a Buzzer simulate the alarm system. These are connected to
PORTC.
Circuit under Threshold Temperature:-
Circuit above Threshold Temperature :-
5. Working Principle
The operation of the system follows a logical sequence defined in the firmware's main loop:
1. Initialization: Upon power-up, the System_Init() function configures the I/O ports
(TRIS registers), initializes the ADC module, and sets up the LCD display. An initial
message is shown on the LCD.
2. Temperature Sensing: The ADC_Read(0) function reads the analog voltage from the
LM35 sensor connected to channel AN0.
3. Data Conversion: The 10-bit digital value from the ADC is converted into a voltage
reading. This voltage is then scaled by a factor of 100 to calculate the temperature in
degrees Celsius, based on the LM35's specifications.
4. Display: The calculated temperature and the current setpoint value (stored in a
global variable) are formatted into strings using sprintf() and displayed on the two
lines of the LCD.
5. User Input: The program continuously scans the state of the two push buttons (RB0
and RB1). If a button press is detected (a LOW signal), the setpoint variable is either
incremented or decremented. A small debounce delay is included to prevent multiple
triggers from a single press.
6. Control Logic: The measured temperature is compared with the setpoint.
o If temperature > setpoint: The system enters an "ALERT" state. The
microcontroller sends a HIGH signal to the pins controlling the fan (RC3) and
the alarm (RC4), turning them ON. The message "ALERT!" is displayed on the
LCD.
o If temperature <= setpoint: The system is in a "NORMAL" state. The control
pins for the fan and alarm are set to LOW, turning them OFF. The message
"NORMAL" is displayed.
7. Loop: This cycle of reading, displaying, checking input, and controlling outputs
repeats indefinitely, ensuring continuous monitoring.
Code:-
/*
* File: main.c
* Author: Atharva Mujumdar
* Project: Smart Temperature Monitoring and Control System
* Target: PIC18F4520
* Compiler: XC8
* IDE: MPLAB X
*/
// CONFIGURATION BITS
#pragma config OSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock
Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator
Switchover mode disabled)
#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bits (Brown-out Reset enabled)
#pragma config BORV = 3 // Brown-out Reset Voltage bits (Minimum setting)
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is
placed on the SWDTEN bit))
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
#pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with
RC1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured
as digital I/O on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer 1 Oscillator Enable bit (Timer1
configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin
disabled)
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack
full/underflow will cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set
extension and Indexed Addressing mode disabled (Legacy mode))
#include <xc.h>
#include <stdio.h> // For sprintf function
#define _XTAL_FREQ 20000000 // Define clock frequency for delay functions (20MHz)
// LCD Pin Definitions
#define LCD_RS PORTCbits.RC0
#define LCD_RW PORTCbits.RC1 // We tie this to ground in the circuit
#define LCD_EN PORTCbits.RC2
#define LCD_DATA PORTD
// Button and Output Pin Definitions
#define BTN_INC PORTBbits.RB0
#define BTN_DEC PORTBbits.RB1
#define FAN_CTRL PORTCbits.RC3
#define ALARM_CTRL PORTCbits.RC4
// --- Function Prototypes ---
void ADC_Init(void);
unsigned int ADC_Read(unsigned char channel);
void LCD_Command(unsigned char cmd);
void LCD_Char(unsigned char data);
void LCD_String(const char *str);
void LCD_String_xy(unsigned char row, unsigned char pos, const char *str);
void LCD_Init(void);
void System_Init(void);
// --- Global Variables ---
int setpoint = 30; // Default temperature setpoint in Celsius
void main(void) {
unsigned int adc_value;
float voltage, temperature;
char temp_str[10];
char setpoint_str[10];
System_Init();
LCD_String_xy(0, 0, "Temp Monitor");
__delay_ms(2000);
LCD_Command(0x01); // Clear display
while (1) {
// 1. Read Temperature
adc_value = ADC_Read(0); // Read from channel 0 (AN0)
voltage = adc_value * (5.0 / 1023.0); // Convert ADC value to voltage (assuming 5V Vref)
temperature = voltage * 100.0; // For LM35, 10mV = 1 degree Celsius
// 2. Display Temperature and Setpoint
sprintf(temp_str, "T:%.1fC ", temperature);
sprintf(setpoint_str, "S:%dC ", setpoint);
LCD_String_xy(0, 0, temp_str);
LCD_String_xy(1, 0, setpoint_str);
// 3. Check for Button Presses to adjust setpoint
if (BTN_INC == 0) {
__delay_ms(100); // Debounce delay
if(BTN_INC == 0) setpoint++;
if (BTN_DEC == 0) {
__delay_ms(100); // Debounce delay
if(BTN_DEC == 0) setpoint--;
// 4. Control Logic
if (temperature > setpoint) {
FAN_CTRL = 1; // Turn fan ON
ALARM_CTRL = 1; // Turn alarm ON
LCD_String_xy(1, 9, "ALERT!");
} else {
FAN_CTRL = 0; // Turn fan OFF
ALARM_CTRL = 0; // Turn alarm OFF
LCD_String_xy(1, 9, "NORMAL");
__delay_ms(200); // Delay for stability
void System_Init(void) {
// Configure I/O Ports
TRISA = 0xFF; // RA0 as input for ADC
TRISB = 0x03; // RB0 and RB1 as inputs for buttons
TRISC = 0x00; // PORTC as output
TRISD = 0x00; // PORTD as output for LCD
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
// Initialize peripherals
ADC_Init();
LCD_Init();
void ADC_Init(void) {
ADCON1 = 0x0E; // Vref+=Vdd, Vref-=Vss, AN0 is analog
ADCON2 = 0x8E; // Right Justified, Fosc/64, 4Tad
ADCON0 = 0x01; // Select AN0, turn on ADC
unsigned int ADC_Read(unsigned char channel) {
if(channel > 13) return 0; // Invalid channel
ADCON0 = (channel << 2); // Select ADC channel
ADCON0 |= 0x01; // Turn on ADC
__delay_us(30); // Acquisition time delay
ADCON0bits.GO_nDONE = 1; // Start conversion
while (ADCON0bits.GO_nDONE); // Wait for conversion to complete
return ((ADRESH << 8) + ADRESL); // Return 10-bit result
void LCD_Init(void) {
LCD_Command(0x02); // Return home
LCD_Command(0x28); // 4-bit mode, 2 lines, 5x7 font
LCD_Command(0x0C); // Display ON, Cursor OFF
LCD_Command(0x06); // Increment cursor
LCD_Command(0x01); // Clear display
__delay_ms(2);
void LCD_Command(unsigned char cmd) {
LCD_RS = 0; // Select command register
LCD_DATA = (cmd & 0xF0); // Send higher nibble
LCD_EN = 1;
__delay_ms(1);
LCD_EN = 0;
__delay_ms(1);
LCD_DATA = ((cmd << 4) & 0xF0); // Send lower nibble
LCD_EN = 1;
__delay_ms(1);
LCD_EN = 0;
__delay_ms(2);
void LCD_Char(unsigned char data) {
LCD_RS = 1; // Select data register
LCD_DATA = (data & 0xF0); // Send higher nibble
LCD_EN = 1;
__delay_ms(1);
LCD_EN = 0;
__delay_ms(1);
LCD_DATA = ((data << 4) & 0xF0); // Send lower nibble
LCD_EN = 1;
__delay_ms(1);
LCD_EN = 0;
__delay_ms(2);
void LCD_String(const char *str) {
while (*str != '\0') {
LCD_Char(*str);
str++;
}
void LCD_String_xy(unsigned char row, unsigned char pos, const char *str) {
if (row == 0)
LCD_Command(0x80 + pos);
else
LCD_Command(0xC0 + pos);
LCD_String(str);
6. Applications
This system, or an enhanced version of it, has numerous real-world applications:
• Server Room Monitoring: To prevent servers from overheating.
• Greenhouse Automation: To maintain optimal growing conditions for plants.
• Home Automation: As a smart thermostat for controlling HVAC systems.
• Industrial Process Control: To monitor and regulate temperature in chemical
processes or manufacturing.
• Medical and Laboratory Storage: To ensure that vaccines, medicines, and biological
samples are kept within a safe temperature range.
7. Observations
During the simulation in Proteus, the following behaviors were observed:
• The LCD correctly displayed the real-time temperature as read from the LM35 sensor.
• Adjusting the temperature on the simulated LM35 component resulted in a
corresponding change on the LCD.
• Pressing the increment and decrement buttons successfully changed the setpoint
value displayed on the second line of the LCD.
• When the sensor's temperature was raised above the setpoint, the green LED (fan),
red LED (alarm), and buzzer all activated simultaneously.
• When the temperature dropped back below the setpoint, all output devices
deactivated, and the LCD status returned to "NORMAL".
8. Result and Analysis
The simulation of the Smart Temperature Monitoring and Control System was a success. The
system performed exactly as intended, demonstrating a reliable closed-loop control
mechanism. The firmware effectively integrated the ADC, LCD, and digital I/O functionalities
of the PIC18F4520. The use of sprintf() for formatting floating-point temperature values
proved to be an efficient method for creating a user-friendly display. The control logic was
robust and responded instantly to changes in temperature relative to the user-defined
setpoint.
9. Conclusion
This project successfully demonstrates the design and implementation of an automated
temperature control system using a PIC microcontroller. It showcases the practical
application of fundamental embedded systems principles. The project is not only a valuable
learning exercise but also forms a solid foundation that can be expanded for more complex,
real-world applications by adding features like data logging, variable fan speed control
(PWM), or wireless communication (IoT).