Reputation: 1
//Code for HIGH TEMPERATURE ALERT SYSTEM using 8051
#include<reg51.h> // Includes 8051 microcontroller definitions
// Function declarations
void delay(unsigned int i); // Generates a delay for LCD enable pulse
void lcd_cmd(unsigned char a); // Sends a command to the LCD
void lcd_data(unsigned char b); // Sends data (characters) to the LCD
void lcd_init(void); // Initializes the LCD
void lcd_str(unsigned char *str); // Displays a string on the LCD
void hex2ascii(unsigned char value); // Converts hex value to ASCII for display
// Pin and port definitions
sbit rs = P2^0; // Register select pin for LCD
sbit en = P2^1; // Enable pin for LCD
sfr ldata = 0xb0; // Data port for LCD (Port 3)
sbit rd = P2^2; // Read pin for ADC
sbit wr = P2^3; // Write pin for ADC
sbit intr = P2^4; // Interrupt pin from ADC
sfr adc = 0x90; // ADC data from Port 1
sbit buz = P2^5; // Buzzer control pin
// Main function
void main ()
{
// LCD welcome message
lcd_init(); // Initialize LCD
buz = 0; // Ensure the buzzer is off at the start
lcd_str(" WELCOME "); // Display first line of welcome message
lcd_cmd(0xc0); // Move to the second line
lcd_str(" TO PROJECT "); // Display second line of welcome message
delay(65000); // Delay for display
lcd_cmd(0x01); // Clear the display
// Display project title
lcd_cmd(0x81); // Position the cursor
lcd_str(" TEMPERATURE "); // Display project title
lcd_cmd(0xc2); // Move to the second line
lcd_str(" ALERT "); // Display 'ALERT' text
delay(65000); // Delay for display
lcd_cmd(0x01); // Clear display
// Display temperature label
lcd_cmd(0x80); // Move cursor to first line, start position
lcd_str(" Temp ="); // Display 'Temp =' text
lcd_cmd(0x8b); // Move cursor to show temperature in degrees
lcd_data((char)223); // Display degree symbol
lcd_str("C"); // Display 'C' for Celsius
// Infinite loop to continuously monitor temperature
while(1)
{
// ADC conversion process
rd = 1; // Set read high
wr = 0; // Start conversion by setting write low
delay(100); // Wait for conversion
wr = 1; // Set write high
while(intr == 1); // Wait until conversion finishes (interrupt flag low)
delay(100); // Small delay
rd = 0; // Set read low to fetch ADC result
// Display temperature value
lcd_cmd(0x89); // Set cursor position to display temperature value
hex2ascii(adc*2); // Convert ADC value to ASCII and display
// High-temperature alert condition
if(adc*2 > 0x1d) // Check if temperature exceeds threshold (29°C)
{
// Display alert message and activate buzzer
lcd_cmd(0xC0); // Move cursor to second line
lcd_str("HIGH TEMP ALERT!"); // Display high temp alert message
buz = 1; // Turn buzzer on
}
else
{
// Clear alert message and turn off buzzer
lcd_cmd(0xC0); // Move cursor to second line
lcd_str(" "); // Clear the alert message
buz = 0; // Turn buzzer off
}
intr = 1; // Ready for next ADC conversion
}
}
// Function to convert hex value to ASCII and display on LCD
void hex2ascii(unsigned char value)
{
unsigned char x, d1, d2, d3;
x = value / 10; // Extract tens digit
d3 = value % 10; // Extract ones digit
d2 = x % 10; // Extract tens digit
d1 = x / 10; // Extract hundreds digit
//lcd_data(d1 + 0x30); // Display hundreds digit (ASCII)
lcd_data(d2 + 0x30); // Display tens digit (ASCII)
lcd_data(d3 + 0x30); // Display ones digit (ASCII)
}
// LCD initialization function
void lcd_init()
{
lcd_cmd(0x38); // Initialize LCD for 8-bit mode
lcd_cmd(0x0c); // Display on, cursor off
lcd_cmd(0x01); // Clear display
lcd_cmd(0x80); // Set cursor to beginning of first line
}
// Delay function
void delay(unsigned int i)
{
unsigned int j;
for(j = 0; j < i; j++); // Simple loop for delay
}
// Function to send command to LCD
void lcd_cmd(unsigned char a)
{
rs = 0; // Set for command mode
ldata = a; // Load command to data port
en = 1; // Enable LCD
delay(5); // Small delay
en = 0; // Disable LCD
delay(5); // Small delay
}
// Function to send data (characters) to LCD
void lcd_data(unsigned char b)
{
rs = 1; // Set for data mode
ldata = b; // Load data to data port
en = 1; // Enable LCD
delay(5); // Small delay
en = 0; // Disable LCD
delay(5); // Small delay
}
// Function to display string on LCD
void lcd_str(unsigned char *str)
{
while(*str) // Loop until the end of the string
{
lcd_data(*str++); // Send each character to the LCD
}
}
I tried adjusting the formula used in my code to display the temperature values from an ADC connected to an LM35 temperature sensor. Initially, I multiplied the ADC value by 2, but that only displayed even temperatures.
What I Expected: I was expecting the temperature display to show both even and odd values as the sensor reads the temperature. I anticipated a smooth progression of temperature values (e.g., 29°C, 30°C, 31°C) as the sensor detects the changes, without skipping or rounding errors.
Upvotes: -1
Views: 100
Reputation: 12653
On a first glance you seem to ask why you have only even values. And as we commented, this is because you multiply the result of the ADC by two.
You cannot have odd results with multiples of two.
After deeper and time consuming investigation, which you could have saved us by adding this information upfront in the question, it is understandable why you multiply by two:
Unfortunately the history of your question created this situation with the remaining question here, and the double-posted version at SE/EE deleted, even if that site is better suited. So I feel you deserve an answer anyway, even if it is here. Please put some more effort into your questions the next time to avoid this confusion.
The real question you have is, "how do I measure the voltage in a way that I can distinguish single °C?"
Solution 1: Reduce the Reference Voltage
Since your ADC cannot extend its digital range, you can reduce the reference voltage. See the ADC's data sheet to learn more.
To have the ADC output a digital value resembling the temperature in °C, you need a reference voltage of 2.56V. The pin "VREF/2" needs to be driven by the half of this value, that is 1.28V.
For a quick experiment you can use a common (not an extra-bright) red LED, which has roughly 1.2V forward voltage. The results will not be good, but you will see the effect.
For a real solution you need a more exact reference. There are specialized components for this, you will need to do your own research.
Solution 2: Amplify the Input Voltage
As an alternative you can amplify the voltage of the LM35 by two.
Use an operational amplifier. Since the signal is practically DC, you don't need a fancy high-speed device. Use any common part.
How to build the circuit is left as an exercise, and it clearly beyond the area of StackOverflow.
Final Note
Don't forget to remove the multiplication by two from your code.
Upvotes: 1