Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ADC interfacing with LCD display

Status
Not open for further replies.

selvakumar c

Newbie level 4
Newbie level 4
Joined
Jun 5, 2013
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,365
Hi friends this is selvakumar i am interfacing ACD with LCD display, in that i am facing a problem with ADC reading
i could't get stable output in LCD display e.g For 5v analog input i get output like this- 1023,1021,1022(it does not remains constant) but
i get proper output in PROTEUS but not in real hardware .

this is my program



Code:
#include<pic18.h>    //pic18f452
#include<htc.h>	     //header file for delay

__CONFIG(1, OSC_HS );
__CONFIG(2, PWRT_ON & BOR_OFF & WDT_OFF);
__CONFIG(4, STVR_ON & LVP_OFF & DEBUG_OFF);


#define _XTAL_FREQ 11059200
#define rs RD0 //lcd control signal 
#define rw RD1 //lcd control signal
#define en RD2 //lcd control signal
#define ld PORTB

unsigned char j=0,ad2 ;
int adc = 0;
unsigned char d1,d2,d3,d4,ad;

void delay()
{
	unsigned char i,j;
	for(i=0;i<150;i++)
	for(j=0;j<150;j++);
}

void l_cmd(unsigned char t)  //lcd command function
{
	ld = t; rs=0;rw=0;en=1; __delay_ms(5); en=0;
}

void l_dt(unsigned char t)   //lcd data function
{
	ld = t; rs=1;rw=0;en=1; __delay_ms(5); en=0;
}

void l_init()             //lcd initialization function
{
	l_cmd(0x38);
	l_cmd(0x00);
	l_cmd(0x0c);
	l_cmd(0x80);
}


void adt(unsigned char i)
{
	d1 = i%10;	i/=10;
	d2 = i%10;	i/=10;
	d3 = i%10;	i/=10;
	d4 = i;

	l_cmd(0x80);	

	l_dt(48+d4);
	l_dt(48+d3);
	l_dt(48+d2);
	l_dt(48+d1);

}
void main()
{
	unsigned char i;
	TRISB = 0; 		//set portb as an output for lcd display
	TRISD = 0; 		//set portd as an output for lcd display 
	TRISA = 0xff;           //set porta as an input for adc



	ADCON1 = 0x40;  //ADFM=0(Left justified)
	ADCON0 = 0x81;  // ADON=1; Fosc/64 clock source 



	l_init();
	__delay_ms(5);
	l_dt('A');
	delay();

	while(1)
	{	


		CHS0=0;CHS1=0;CHS2=0;GO=1; while(GO);l_cmd(0x80);		adt(ADRESH);   //read adc0 channel first
		CHS0=1;CHS1=0;CHS2=0;GO=1; while(GO);l_cmd(0xC0);		adt(ADRESH);   //read adc1 channel second
		CHS0=0;CHS1=1;CHS2=0;GO=1; while(GO);l_cmd(0x94);		adt(ADRESH);   //read adc2 channel thirt
		CHS0=1;CHS1=1;CHS2=0;GO=1; while(GO);l_cmd(0xD4);		adt(ADRESH);   //read adc3 channel fourth


	}	
}

Any one help me to solve this problem....

Thank u..
 
Last edited by a moderator:

i don't think its a problem. you are applying 5V DC and you are getting 1023(4.995V ),1022(4.990V) etc .There always will be a slight variation in the power supply.You got proteus output because it is a virtual circuit and almost takes devices ideal.
 

Try this

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
while(1)
{
 
   CHS0=0;CHS1=0;CHS2=0;
   __delay_ms(10);
   GO=1; 
   while(GO);
   l_cmd(0x80); 
   adt(ADRESH); //read adc0 channel first
 
   __delay_ms(100);
}



first consider a single channel and tell what happens....
 
As already pointed out by S.P.S , the power supply fluctuation will be there in any power supply and how much that will be can be found from the tolerance of the power supply design sheet. Use high accuracy multimeter to find the fluctuation in your power supply, u can also see the 5V waveform on CRO to find any irregularities at lesser volt/div and time/div.
If the shift in digital value increases too high, then the issue is with the PCB design. The stray values of capacitance, inductance makes it worse if PCB design is improper. The note on PCB design for ADC is given on microchip website, i wil send the document number once i find it.
 

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ADCON0=0x41;
ADCON1=0x40;
while(1)
{
 
   CHS0=0;CHS1=0;CHS2=0;
   __delay_ms(10);
   GO=1; 
   while(GO);
   l_cmd(0x80); 
   adt(ADRESH & 0xfc); //read adc0 channel first
 
   __delay_ms(50); __delay_ms(50);
}

 

When you try your circuit in proteus it'll show the results in it's idle condition. But in real hardware the idle characteristics canot be achieved. As you are using 10 bit resolution variation in 1's and 2's 'll not affect your result much. Just convert it to voltage and see the result. It'll be constant... It would be arise even because of your connection problem too...
 

post your hardware schematic if any possible because surly this is a power problem to get 5v output use 7805 or any adepter or not?
 

In my view you should go with some kind of averaging algorithm to be implemented such that this will give you smother output.... but this will reduce some times the resolution.... Please select the ACD of proper to the Input Signal resolution that you want..... I mean if you have let say range of input signal 0-5v to be measured with 0.04 v resolution then you need to have at least 8 bit ADC .....I mean 5/0.04 = 127 so double the resolution for obtaining the values with at least one least count variation ....

Good Luck
 

Thats true, by reducing resolution you the display will be stable but note that we are neglecting small variation in the signal but it is actually present.So the efficiency of the system get reduced.
 

Code with averaging try this

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#define ADC_CHNLS   4
#define ADC_SAMPLES 10
#define RATIO       10
 
 
int ADC_result[ADC_CHNLS],CH1_result,CH2_result,CH3_result;
int Raw_ADC[ADC_CHNLS], ch, sample;
 
 
void ADC_init(void)
{
    ADCON1 = 0x80;
    TRISA  = 0x2F;
    TRISE  = 0x07;
    ADCON0 = 0x81;
}
 
 
int convert_ADC(int channel)
{
    ADCON0 &= 0xc7;      
    ADCON0 |= (Channel<<3); 
    
    __delay_ms(10);         
                            
    GO  = 1;            
 
    while(GO);        
 
    return ((ADRESH<<8)+ADRESL);   
}
 
 
void interrupt Timer1()
{
    if(TMR1IF)
    {
        for(ch=0; ch<ADC_CHNLS; ch++)
        {
         Raw_ADC[ch] += convert_ADC(ch);
        }
        
        if(++sample > ADC_SAMPLES)
        {
            sample = 0;
            
            for(ch=0; ch<ADC_CHNLS; ch++)   
            {
                ADC_result[ch] = Raw_ADC[ch] / ADC_SAMPLES / RATIO;
                Raw_ADC[ch] = 0;
            }
        }
        
    }
}
 
void Timer_init()
{
    TMR1H = 0;           
    TMR1L = 0;           
    // Timer1 is 16bit timer
    T1CON = 0x01;        
 
    TMR1IF = 0;          
    TMR1IE = 1;          
    PEIE   = 1;              
    GIE    = 1;     
}
 
void main()
{
    
    ADC_init();
    Timer_init();
    lCD_init();
 
    while(1)
    {   
        LCD_cmd(0x80);      
        display(ADC_result[0]);   //read adc0 channel first
        LCD_cmd(0xC0);      
        display(ADC_result[1]);   //read adc1 channel second
        LCD_cmd(0x94);      
        display(ADC_result[2]);   //read adc2 channel thirt
        LCD_cmd(0xD4);      
        display(ADC_result[3]);   //read adc3 channel fourth
    }   
}

 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top