Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

LCD display flickrign problem. Urgent help required.

Status
Not open for further replies.
Hi,

i want to display data detected by ADC0808 on my 14x2 LCD but by doing this i am facing a problem that the data at my lcd display is not still to see as in Digital Multi-meters. here is the video link that shows my problem. i want to eliminate the flickring on screen.


and here is my code.

Code:
#include <reg52.h>


 #define Port P2  // control port
 #define adc_input P1
 #define data_port P0  // data from microcontroller to LCD
 #define sec 50

 sbit ADC_A=Port^0;	//ADC
 sbit ADC_B=Port^1;	//ADC
 sbit RS=Port^7;  		//LCD
 sbit E=Port^5;		   //LCD
 sbit RW=Port^6;		  //LCD
 sbit SC=Port^4;   //ADC
 sbit CLK=Port^3;  //ADC
 sbit ALE=Port^2;  //ADC

unsigned int test_intermediate3=0, test_final=0;
unsigned int test_intermediate1[10], test_intermediate2[3]={0,0,0};
unsigned char temp[]={"Temp: "}, vna[]={"Volt:    Amp:  "},  hnm[]={"  hr   min     %"}, bnc[]={"Backup:  %Charge"};


		 //------------------- . --------------------------

		void delay(unsigned int msec)
		{
			int i,j;
			for(i=0; i==msec; i++)
				for(j=0; j==1275; j++);

		}




		//---------------- timer 0 interrupt----------------

		void timer0() interrupt 1
		{
		   		
					CLK=~CLK;		// Toggle port bit p3.5
					TR0=0;         // stop timer
					TH0=0xff;	    // 500hz clock for adc
					TL0=0xff;
					TR0=1;			// start timer
		}




		//.................. LCD .................


		void lcd_cmd( unsigned int item )
		{
			data_port=item;  //command on data port p0 of lcd
			RS=0; // selecting command register of lcd
			RW=0;
			E=1;
			delay(1);
			E=0;
		//	return;
		}




		void lcd_data( unsigned int item )
		{
			data_port=item;  //data on data port p0 of lcd
			RS=1; // selecting data register of lcd
			RW=0;
			E=1;
			delay(1);
			E=0;
		//	return;
		}










	  //----------- custom character Generation for Degree symbol-----------

	  void shape()
	  {
	  		
			lcd_cmd(64); 		// first location in CGRAM
			delay(sec);
			lcd_data(2);
			delay(sec);
			lcd_data(5);
			delay(sec);
			lcd_data(2);
			delay(sec);
			lcd_data(0);
			delay(sec);
			lcd_data(0);
			delay(sec);
			lcd_data(0);
			delay(sec);
			lcd_data(0);
			delay(sec);
			lcd_data(0);
			delay(sec);

			return;
	  }


	  //-------------------- for volt symbol-----------------

	   void shape2()
	  {
	  		
			lcd_cmd(72); 		// first location in CGRAM
			delay(sec);
			lcd_data(0);
			delay(sec);
			lcd_data(0);
			delay(sec);
			lcd_data(17);
			delay(sec);
			lcd_data(17);
			delay(sec);
			lcd_data(17);
			delay(sec);
			lcd_data(10);
			delay(sec);
			lcd_data(4);
			delay(sec);
			lcd_data(0);
			delay(sec);

		//	return;
	  }

	 //---------------------- for current symbol-------------------

	  void shape3()
	  {
	  		
			lcd_cmd(80); 		// first location in CGRAM
			delay(sec);
			lcd_data(0);
			delay(sec);
			lcd_data(0);
			delay(sec);
			lcd_data(4);
			delay(sec);
			lcd_data(10);
			delay(sec);
			lcd_data(17);
			delay(sec);
			lcd_data(31);
			delay(sec);
			lcd_data(17);
			delay(sec);
			lcd_data(0);
			delay(sec);

		//	return;
	  }
								





	  //..... Converting binary value of ADC to ASCII value of LCD for Temprature........




	  void convert()
	  {
	  		int s,i;
			lcd_cmd(0xc0);
		
			delay(sec);

	 													 // Farnheit conversion

			for(i=0; temp[i]!='\0' ; i++)
				{
					lcd_data(temp[i]);
					delay(sec);
				}

			 
			test_final=(((9*test_intermediate3)/5)+32);
			
			s=test_final/100;
			test_final=test_final%100;

			lcd_cmd(0xc5);
			delay(sec);
			if (s!=0)
				{
				lcd_data(s+48);	//c5
				delay(sec);
				}
			else
				{
				lcd_cmd(0x06);
				delay(sec);
				}


		  s=test_final/10;
		  test_final=test_final%10;

		  lcd_data(s+48);	   //c6
		  delay(sec);
		  lcd_data(test_final+48);	//c7
		  delay(sec);
		  lcd_data(0);				 // space for degree symbol
		  delay(sec);
		  lcd_data('F');
		  delay(sec);
		  lcd_data(' ');
		  delay(sec);


		//------------------- for Celcius scale----------------

		  test_final=test_intermediate3;

		 // lcd_cmd(0xc1);  // set cursor to second line.
		 
	//	 delay(sec);

	//	 for(i=0; temp[i]!='\0' ; i++)
	//			{
	//				lcd_data(temp[i]);
	//				delay(sec);
	  //
		//		}

		  s=test_final/100;
			test_final=test_final%100;

			lcd_cmd(0xcB);
			delay(sec);
			if (s!=0)
				{
				  lcd_data(s+48);	// 1st digit MS
					delay(sec);
				}
			else
				{
				  lcd_cmd(0x06);
					delay(sec);
				}



		  s=test_final/10;			 // 2nd digit
		  test_final=test_final%10;	 // 3rd digit LS

		  lcd_data(s+48);  //89
		  delay(sec);
		  lcd_data(test_final+48);	 //88
		  delay(sec);
		  lcd_data(0);		   // space for degree symbol
		  delay(sec);
		  lcd_data('C');
		  delay(sec);
		  lcd_data(' ');
		  delay(sec);
		 }







		 // Converting binary value of ADC to ASCII value of LCD for volts


		 void  Convert2()
		 {
		 	int s;
	 //.................... Voltage conversion ............................

					 
		 test_final=test_intermediate3/3;
			
			s=test_final/100;
			test_final=test_final%100;

			 lcd_cmd(0x85);
			delay(sec);
			if (s!=0)
				{
				lcd_data(s+48);
				delay(sec);
				}
			else
				{
				lcd_cmd(0x06);
				delay(sec);
				}


		  s=test_final/10;
		  test_final=test_final%10;

		  lcd_data(s+48);	   
		  delay(sec);
		  lcd_data(test_final+48);	
		  delay(sec);
		  lcd_data(1);
		  delay(sec);
		 }

		//-------------------..................-------------------

		 void  Convert3()
		 {
		 	int s;
	//.................... current conversion ............................

					 
		 test_final=test_intermediate3/5;
			
			s=test_final/100;
			test_final=test_final%100;

			  lcd_cmd(0x8D);
			delay(sec);
			if (s!=0)
				{
				lcd_data(s+48);
				delay(sec);
				}
			else
				{
				lcd_cmd(0x06);
				delay(sec);
				}


		  s=test_final/10;
		  test_final=test_final%10;

		  lcd_data(s+48);	   
		  delay(sec);
		  lcd_data(test_final+48);
		  delay(sec);
		  lcd_data(2);
		  delay(sec);
		 }

	  
	  
	  
	  
	  
	  
	  
	  //.........--------.......Main Program.......-------........

		

		   void main()
		   {

		   		int i,j,k,l,m,n;
				adc_input=0xff; // making p1 as input port
				TMOD=0x01;	   // timer 0,  mode 1
				TH0=0xff;	    // 500hz clock for adc
				TL0=0xff;
				TR0=1;         // timer start

				IE=0x82;		// interrupt enable ; timer interrupt and globle interrupt.
				
				lcd_cmd(0x38);		// initializing LCD module
				delay(sec);

				lcd_cmd(0x0c);
				delay(sec);

				lcd_cmd(0x01);
				 delay(sec);

				lcd_cmd(0x06);
				delay(sec);

				lcd_cmd(0x90);
			    delay(sec);

	//;;;;;;;;;;;;-----------------------;;;;;;;;;;;;;;;;;
	//..........- Back up and %Charge display ----........

				lcd_cmd(0x90);
			    delay(sec);

			for(i=0; bnc[i]!='\0' ; i++)
				{
					lcd_data(bnc[i]);
					delay(sec);
				}							


	//;;;;;;;;;;;;;;-------------------------;;;;;;;;;;;;;;;;;
	//.............- hour and minute display ------............

		lcd_cmd(0xD0);									   
		
			delay(sec);

	 													

			for(i=0; hnm[i]!='\0'; i++)
				{
					lcd_data(hnm[i]);
					delay(sec);
				}

	//;;;;;;;;;;;;;;-----------;;;;;;;;;;;;;;;
				

				while(1)
				{

				//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Temprature samples;;;;;;;;;;;;;;;;;;;;;;


						for(j=0;j<3;j++)
						{
							for(i=0;i<10;i++)
							{
								   ADC_A=0;
								   ADC_B=0; // channel 0 is selected   ; pin 26 of ADC

									delay(200);
								
									ALE=0;
									SC=0;
									delay(1);

									 ALE=1;
									 delay(1);
									 SC=1;
									 delay(1);

									 ALE=0;
									 delay(1);
									 SC=0; 
									 delay(1000);
																		 
									 test_intermediate1[i]=adc_input/10;
								
							}


							for(i=0;i<10;i++)
							test_intermediate2[j]+=test_intermediate1[i];
						}


						test_intermediate2[0]=test_intermediate2[0]/3;
						test_intermediate2[1]=test_intermediate2[1]/3;
						test_intermediate2[2]=test_intermediate2[2]/3;

						test_intermediate3=test_intermediate2[0] + test_intermediate2[1] + test_intermediate2[2];

					

						convert();
						shape();

						delay(1000);
						delay(1000);
						delay(1000);

			 //;;;;;;;;;;;;;;;;;  Voltage samples;;;;;;;;;;;;;;;;;;;;;;;;;


		    lcd_cmd(0x80);
		
			delay(sec);

	 													 // voltage conversion

			for(i=0; vna[i]!='\0'; i++)
				{
					lcd_data(vna[i]);
					delay(sec);
				}


					 //..................................................  ..........


					  	for( k=0;k<3;k++)
						{
							for(l=0;l<10;l++)
							{
								   ADC_A=1;
								   ADC_B=0; // channel 1 is selected

									delay(200);
								

									ALE=0;
									SC=0;
									delay(1);

									 ALE=1;
									 delay(1);
									 SC=1;
									 delay(1);

									 ALE=0;
									 delay(1);
									 SC=0; 
									 delay(1000);
																		 
									 test_intermediate1[i]=adc_input/10;
								
							}


							for(i=0;i<10;i++)
							test_intermediate2[j]+=test_intermediate1[i];
						}


						test_intermediate2[0]=test_intermediate2[0]/3;
						test_intermediate2[1]=test_intermediate2[1]/3;
						test_intermediate2[2]=test_intermediate2[2]/3;

						test_intermediate3=test_intermediate2[0] + test_intermediate2[1] + test_intermediate2[2];
						 
						
						 Convert2();
						 	shape2();

							delay(1000);
							delay(1000);
							delay(1000);

						   //;;;;;;;;;;;;;;;;;  Current samples;;;;;;;;;;;;;;;;;;;;;;;;;

					  	for( m=0;m<3;m++)
						{
							for( n=0;n<10;n++)
							{
								   ADC_A=0;
								   ADC_B=1; // channel 2 is selected

									delay(200);
								

									ALE=0;
									SC=0;
									delay(1);

									 ALE=1;
									 delay(1);
									 SC=1;
									 delay(1);

									 ALE=0;
									 delay(1);
									 SC=0; 
									 delay(1000);
																		 
									 test_intermediate1[i]=adc_input/10;
							}



							for(i=0;i<10;i++)
							test_intermediate2[j]+=test_intermediate1[i];
						}


						test_intermediate2[0]=test_intermediate2[0]/3;
						test_intermediate2[1]=test_intermediate2[1]/3;
						test_intermediate2[2]=test_intermediate2[2]/3;

						test_intermediate3=test_intermediate2[0] + test_intermediate2[1] + test_intermediate2[2];
						
						 Convert3();
						 	shape3();
							delay(1000);
							delay(1000);
							delay(1000);

				}
		   }


the second problem in my code is that i have used the LCD address 90H in order to display "Backup: %Charge" but it is not displaying on that location ... i dont know why?? but if i write the same string with in the vna[] aray with sixteen spaces (vna[]={"Volt: Amp: backup: %charge"} ) it started display the string "Backup: %Charge" in third line. the address for the first line of 16x4 lcd is 80---8f
for 2nd line it is c0---cf ; for 3rd line it is 90----9f and for 4th line it is d0----df.

please guide me about my both problems.

any help will be appritiated.

thank you
 
Last edited by a moderator:
Looks to me as though the input data is updating too fast or is unstable. It's not a fault in the display itself which is causing the flickering. Try increasing the delays in the code and ensure analog inputs are well screened. Can't offer any suggestion re the second problem.
BTW, I'm surprised you need code to generate the degree symbol in CGRAM. Isn't that symbol among the Japanese characters which are part of the standard character set?
 
Last edited:
I agree with Alec_t.
The display is fine. The words are fine, the numbers change every time through the loop. If you output the same information on the serial port you will see the same numbers jumping around.

This is a function of noise on the analog inputs. You need to "average" the numbers by a RC on the inputs and/or in software. Long wire and poor layout and no bypass caps will cause this.
 
I fell for that one.....

1) Alec_t is right you need to average your adc input read it 24 times... then divide by 24.

2) line 1 = 0x80..... line 3 ( actual line 2 ) = 0xC0 as you have 14 chars per line... line 2 = 0x8E and line 4 = 0xCE.

Basically line 1 continues on line 2... Line 3 continues on line 4
 
BTW, I'm surprised you need code to generate the degree symbol in CGRAM. Isn't that symbol among the Japanese characters which are part of the standard character set?

how can i generate it in the standard way as it is not present in my keyboard as english alphabets and numbers??/
 
This is a function of noise on the analog inputs. You need to "average" the numbers by a RC on the inputs and/or in software. Long wire and poor layout and no bypass caps will cause this.

how should i include RC network for how much frequency and for what values of Resistance and capacitance? kindly explain.
 
I fell for that one.....

1) Alec_t is right you need to average your adc input read it 24 times... then divide by 24.

2) line 1 = 0x80..... line 3 ( actual line 2 ) = 0xC0 as you have 14 chars per line... line 2 = 0x8E and line 4 = 0xCE.

Basically line 1 continues on line 2... Line 3 continues on line 4

1) i am using 89c51 and keil compiler is giving the following error if i exceed the number of scan above 20....

Code:
Build target 'Target 1'
compiling DVM...
linking...
*** ERROR L107: ADDRESS SPACE OVERFLOW
    SPACE:   DATA    
    SEGMENT: _DATA_GROUP_
    LENGTH:  000CH
Program Size: data=130.0 xdata=0 code=1951
Target not created


2) i have used 0x8E but result is the same.... :(
 
The '°' symbol is usually at 0xDF (is on mine)

Hang on a minute..... What display are you using.... 16x4 or 14x4, you list both in your original post?

The datasheet WILL state the line positions somewhere (Some displays have 20 chars per line, so 0x80,0x94,0xC0 & 0xD4 EVEN if they are 16x4, this is the bit I fell over on ).

1) i am using 89c51 and keil compiler is giving the following error if i exceed the number of scan above 20....

Explain?
 
Last edited:
Hurrrrraaa...... :)

i solved the two basic problems.......

1) i mistakenly written the routine to display volt and amp within while(1) loop... i cut it out of here and paste it in main function out of while loop. thus flickrig is eleminated. it flickred due to repeatedly display the string and data on the same place.

2)i just write the display routines in a sequence according to address of LCD. i.e; 1st for line 1 and then for 2 and so on up to line4 .

................................;;;;;;;;;;;;;;;;;;......................................


NOW the problem is that the changing analog value on one pin of ADC is causing to change the value of 2nd pin ... i checked it out in proteus simulator and practically on my Hardware...... please help me about this new problem.. i think it is programming problem.
 
Last edited:
The '°' symbol is usually at 0xDF (is on mine)

Hang on a minute..... What display are you using.... 16x4 or 14x4, you list both in your original post?

The datasheet WILL state the line positions somewhere (Some displays have 20 chars per line, so 0x80,0x94,0xC0 & 0xD4 EVEN if they are 16x4, this is the bit I fell over on ).



Explain?

oh sorry i am using 16x4 LCD display JHD164A.

2) you told me to read the input up to 24 times but when i program it to read the input above 20 times ........... keil compilar shows the error as i've given in above post.
 
The '°' symbol is usually at 0xDF (is on mine)
That's the ASCII code for the symbol on my display too.
 
is it 0xdf is in CGRAM or i directly send it as data to LCD as i send alphabets and numbers??
Send 0xDF directly as the character code, just as you would for letters and numbers.
 
oh yes exactly it is at position 0xfd.... thank you very much to all who helped.

please tell me about my second problem,

the changing analog value on one pin of ADC is causing to change the value of 2nd pin ... i checked it out in proteus simulator and practically on my Hardware.
 
Use screened, short wiring to connect to the analogue inputs. Ensure there is no ground loop or any significant impedance in the ground path. Build the circuit on a pcb with a ground plane; NOT on a breadboard.
i checked it out in proteus simulator and practically on my Hardware.
And....? Does the sim show the problem to be present or absent?
 
If you have an ADC connected to P1 and the control on P0 pins 0-1... We will need to see the schematic... What ADC chip are you using?

i am using ADC0808 and here is the image below. please also check if i am using the transistors in right way or not because i write a program to conduct one transistor at a time but at a time 2 or 3 transistors are conducting and with my selection any one of all completely switch its state, others don't OFF completly rather they have small conduction.

View attachment 62178

here is my code.
Code:
#define select P3

 sbit v28=select^4; 
 sbit v14=select^6;
 sbit v7=select^5;
 sbit off=select^7;

Code:
void switching() interrupt 0
		   {
		   		  if(v28==0 && v14==0 && v7==0 && off==1)
				  		{ off=0;  v7=1; v28=0; v14=0; }
					
				    else
                        if(v28==0 && v14==0 && v7==1 && off==0)
                              { v7=0; v14=1; v28=0; off=0; }
					
					else
						if(v28==0 && v14==1 && v7==0 && off==0)
						      { v14=0; v28=1; v7=0;  off=0; }
					
					else
					   { v28=v14=v7=0; off=1; }
						
		   
		   }
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top