Arduino Projects    |   Raspberry Pi  |     Electronic Circuits    |    AVR    |    PIC    |    8051    |    Electronic Projects   |   Free TI Design & Simulation Tools 

Error using Lm35 Interface with Atmega 16

5 posts / 0 new
Last post
Hamza Khan
hamza.92000khan's picture
Offline
Joined: 20/02/2012
Posts: 1
Points: 0
Error using Lm35 Interface with Atmega 16

hey I am using the following code to interface LM35 with ATMEGA16 and displaying the result on LCD. 
 

When the temprature is above 100 degree centigrade the output of ADC is fine but when the temperature falls below 99 degree centigrade the ADC outputs garbage value. 

 

like for 150 degree to 100 it displays the same but for 99 to 10 degree centigrade it displays 990 degree to 100 and then from 9 to 0 centigrade the output is 900 degree centigrade to 100.

 

here is the code tell me the mistake.

 

#include<avr/io.h>
#include<avr/delay.h>
//#include<inttypes.h>
//#include <stdint.h>
#define rs PA0
#define rw PA1
#define en PA2
void lcd_init();
void ADC_init();
unsigned int ADC_read(unsigned char);
void dis_cmd(char);
void dis_data(char);
void lcdcmd(char);
void lcddata(char);
 
int main(void)
{
DDRA=0xEF;
while (1)
{
ADC_init();
unsigned char data0[]="Temperature=";
unsigned int data1,adc_val,a;
char int_buffer[10];
lcd_init();
LCD_print(data0);
adc_val=ADC_read(3);
data1=(adc_val/2.048);
//a=(((308*5)*100)/1024);
itoa(data1, int_buffer, 10);
 
dis_cmd(0xC0);
 
LCD_print(int_buffer);
}
}
 
void lcd_init()     // Function for initialize
{
dis_cmd(0x02); // To initialize LCD in 4-bit mode.
dis_cmd(0x28); // To initialize LCD in 2 lines, 5X7 dots in 4bit mode.
dis_cmd(0x0F); // Blinking Cursor
dis_cmd(0x06); // Entry mode
dis_cmd(0x80); // This command gives the location of first letter  ** 80 + 'x' ** shifts the display 'x' units right.
_delay_ms(500);
}
void dis_cmd(char cmd_value)
{
char cmd_value1;
cmd_value1 = cmd_value & 0xF0; // Mask lower nibble because PA4-PA7 pins are used (Extracting Upper Four bits)
// Masking means clearing bits
// Upper nibble is sent first and then the lower nibble
lcdcmd(cmd_value1); // Send to LCD
cmd_value1 = ((cmd_value<<4) & 0xF0); // Shift 4-bit and mask (Extracting Upper Four Bits)
lcdcmd(cmd_value1); // Send to LCD
}
void dis_data(char data_value)
{
char data_value1;
data_value1=data_value & 0xF0;
lcddata(data_value1);
data_value1=((data_value<<4)&0xF0);
lcddata(data_value1);
}
void lcdcmd(char cmdout)
{
//Commands on LCD is initialized by having a negative transition on the enable pin.
// 1) RS=RW=0 & EN=1;
// 2) RS=RW=0 & EN=0;
PORTA=cmdout;
PORTA&=~(1<<rs);
PORTA&=~(1<<rw);
PORTA|=(1<<en);
_delay_ms(1);
PORTA&=~(1<<en);
}
void lcddata(char dataout)
{
//Letters on LCD is displayed by having a negative transition on the enable pin.
// 1) RS=RW=1 & EN=1;
// 2) RS=RW=1 & EN=0;
PORTA=dataout;
PORTA|=(1<<rs);
PORTA&=~(1<<rw);
PORTA|=(1<<en);
_delay_ms(1);
PORTA&=~(1<<en);
}
 
void ADC_init()
{
ADMUX=(1<<REFS0);
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS0);
}
unsigned int ADC_read(unsigned char ch)
{
ch= ch & 0b00000111; // channel must be b/w 0 to 7
ADMUX |= ch; // selecting channel
 
ADCSRA|=(1<<ADSC); // start conversion
while(!(ADCSRA & (1<<ADIF))); // waiting for ADIF, conversion complete
ADCSRA|=(1<<ADIF); // clearing of ADIF, it is done by writing 1 to it
return (ADC);
 
}
void LCD_print(char * str)
{
unsigned char i=0;
while(str[i]!=0)
{
dis_data(str[i]);
i++;
}
}
 
mohammad amin
avr1083's picture
Offline
Joined: 17/09/2013
Posts: 3
Points: 10

HI

 

code software LM35

 

#include <mega16.h>
#include <stdio.h>
#include <delay.h>
#asm
   .equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h> 
#define  Up        PIND.0
#define  Down      PIND.1
#define  Enter     PIND.2 
#define  high_LED  PORTA.1
unsigned char compare=0,set=0xff;
float   temp; 
//__________________________________________
void display(){  
char   lcd_buf[32];
sprintf(lcd_buf,"Temp=%3.1f\xdfC\nHigh Temp=%i",temp,compare);
lcd_clear();
lcd_gotoxy(0,0);
lcd_puts(lcd_buf);
lcd_gotoxy(13,1);
if(high_LED==1) lcd_putsf("on ");
if(high_LED==0) lcd_putsf("off");

//_________________________________________                        
interrupt [ADC_INT] void adc_isr(void){
unsigned int adc_data;
adc_data=ADCW;
temp=adc_data*2.56/1024; 
temp=temp*100;
if(temp>=set) high_LED=1;
else high_LED=0;
}
//_________________________________________up
void inc_set_temp(){
if(compare<99) compare++;
}
//__________________________________________Down
void dec_set_temp(){
if(compare!=0) compare--;
}             
//__________________________________________
void main(){
PORTD=0XFF;
DDRD=0X00;
PORTA.1=0;
DDRA.1=1; 
ACSR=0XC0;
SFIOR=0X00;
ADMUX=0XC0;
ADCSRA=0X8F;
lcd_init(16);
#asm("sei")
ADCSRA=0XCF;
while(1){
   display();
   delay_ms(250);
   ADCSRA=0XCF;
   if(Up==0)    inc_set_temp();
   if(Down==0)  dec_set_temp();
   if(Enter==0) set=compare;
 };
}

Ganesh Selvaraj
strangeganesh's picture
Offline
Joined: 15/07/2011
Posts: 72
Points: 325

Hello Hamza Khan, I guess the problem is that the variable "data1" is declared as int type and so it doesn't take decimals. Try changing it to float type.

A M Bhatt
A M Bhatt's picture
Offline
Joined: 21/12/2010
Posts: 149
Points: 1955

the problem is sending and printing values on LCD. to display values in correct order use following function

void display(unsigned char z)
  {
  unsigned int tmp1,tmp2,t,t1,i;
unsigned char ASCII[3];
tmp1 = (z & 0x0F);
tmp2 = z>>4;
tmp2 = tmp2*16;
t = tmp1+tmp2;
if(t>=100)
 {
i=2;
while(t>10)
{
t1=t%10;
ASCII[i]=t1+0x30;
t=t/10;
i--;
}
ASCII[0]=t+0x30;
 }
else
 {
t1=t%10;
ASCII[2]=t1+0x30;
t=t/10;
ASCII[1]=t+0x30;
ASCII[0]=0x30;
 }
writedata(ASCII[0]);
writedata(ASCII[1]);
writedata(ASCII[2]);
  }
harsh dhiman
harshdhiman's picture
Offline
Joined: 18/04/2013
Posts: 1
Points: 5

can u plz provide the circuit diagram . the code gets complied (Y)

 

Login or register to post comments
You are here