wierd problem with the CFAH2004A

gdx9902

New member
Hi,

I have just purchased a CFAH2004A from you guys, and I am having trouble utilizing all the lines in the 20x4 character lcd display.

It seems that I can display on lines 1 and 3, but everytime i change the address to 0x40(line2) or 0x54(line 4), it gets reset to line 1, and what ever I have written on line 1 gets cleared with the new string i was supposed to write on line 2 and 4.

I have read and reread the data sheet and the HD44780 data sheet several times over, and am still completely stumped.

I am not sure if it is in my initialization sequence.

I have set it as


delayMs(15)
0x30 // function set
delayMs(6)
0x30 // function set
delayMs(2)
0x30 // function set
delayMs(2)

0x30 // final function set
delayMs(2)

0x08 // turn off display
delayMs(1)

Lcd_clearscreen

0x0F// turn on display with full blinking cursor

// finish initialization.

if you could please help me and let me know what I am doing wrong.

Thank you
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 

gdx9902

New member
Thanks for the tip,

I've tried it initializing it with 0x38, but here's the funny thing

now the LCD fails to initialize.

i can initialize it with 0x3C, or 0x30, but with 0x38 i get nothing at all.

any thoughts?
 
Hmm, that's strange.

My advice was based on generic experience with the HD44780 type of displays, as I do not have this particular model to experiment with.

Meanwhile, here is the init function extracted from the CFAH Win Test app:
Code:
void CCFAH_WinTestDlg::Init_LCD_8(ubyte enable)
  {
  //This sequence is from the initialization on page 45 of the HD44780U
  //data sheet.
  Sleep(40);
  Write_LCD_Control_8(0x38,enable);
  //Yes, the data sheet says write it twice.
  Sleep(5);
  Write_LCD_Control_8(0x38,enable);
  //Yes, the data sheet says write it three times.
  Sleep(125);
  Write_LCD_Control_8(0x38,enable);
  //Yes, the data sheet says write it four times, but at least this one counts.
  //038h is Function set:
  //8 bit,
  //2 line
  //F = (5x8)
  Sleep(1);
  Write_LCD_Control_8(0x38,enable);
  //"Display off"
  Sleep(2);
  Write_LCD_Control_8(0x08,enable);
  //"Display clear"
  Sleep(2);
  Write_LCD_Control_8(0x01,enable);
  //006h is Entry mode set, increment, no shift
	Sleep(2);
  Write_LCD_Control_8(0x06,enable);
  //Display on, cursor on, blinking
	Sleep(2);
  Write_LCD_Control_8(0x0F,enable);
  //Clear the display again. This seems to fix a power-up problem
  //where the display shows "{{{{{" in a couple of places.
	Sleep(2);
  Write_LCD_Control_8(0x01,enable);
  }
Did you use the 0x38 for all 4 writes?
 

gdx9902

New member
Thanks for the code, but I wonder how long a sleep function sleeps for.

is it in milliseconds or microseconds?
 
Milliseconds, I'd suppose, since it is the Windoze API call. I wouldn't worry about those values, as your code has appropriate delays.
 

gdx9902

New member
THis is wierd because it's identical to my code:

RSclear();
DelayUs(1);
RWclear();
DelayUs(1);
Eclear();
data = 0x00;
portd_set(data);
DelayMs(40);// more than 15 ms delay

data = 0x38;// function set 1
portd_set(0x38);
DelayUs(1);
LCD_Strobe();
DelayMs(6);//5ms

portd_set(0x38); // function set 2
DelayUs(1);
LCD_Strobe();
DelayMs(2);

portd_set(0x38); // function set 3
LCD_Strobe();
DelayMs(2);

data=0x38; // final function set
portd_set(0x38);
LCD_Strobe();
DelayMs(2);

data = 0x08; // turn display off
portd_set(data);
LCD_Strobe();
DelayMs(2);

LCD_ClearScreen(); // sends command 0x01

data = 0x06;// Entry mode set
portd_set(data);
LCD_Strobe();
DelayMs(2);

data = 0x0F; // turn display on
portd_set(data);
LCD_Strobe();
DelayMs(2);

LCD_cursorreset(); // sends command 0x02

and it doesnt seem that the 0x38 command is liked
it loves the 0x30 command and displays characters accordingly,
could it be the lcd module its self?
i'd like to check that line 2 and line 4 start with 0x40 hex and 0x54 hex accordingly
i can switch between 0x00 and 0x14 hex but the other two the lcd doesnt seem to like it
 
Are you sure that your wiring is OK? Maybe you've got two data lines shorted or something. On the display lines that work (1 & 3), try writing an ascending sequence of letters, from 0x20 thru 0x7F, and see if it looks right. Otherwise, I'd suspect something is wrong with the module.

Oh, and be sure that your E signal pulse width is not too short, minimum 250 nS high.
 

gdx9902

New member
Thanks for the tip,

I've rechecked my circuit again, and thank god there were no shorts. And as per your advice i rechecked the e signal integrity, and found that the PIC microcontroller I am using has a quite a bit of oscillations when switching between 0 and 5 volts. I'm wondering if this has anything to do with the lcd not triggering latching properly.

There seems to be quite a bit of noise oscillations as I go drive E high and low.

If this may be the cause, how do i clean the signals up?
 
If this may be the cause, how do i clean the signals up?
This could very well be the cause. But be sure your scope ground is short, and connected to the CFAH end of the wires, or you may be fooling yourself.

How long are the wires from the PIC to the CFAH? Try shorter wires. Make sure ground is good, perhaps use a separate power and signal ground.

Use a damping resistor in series with the E signal where it connects to the display, perhaps 1000 ohm (or 100 ~ 10K, depends on the wiring capacitance). Maybe add a capacitor where the damping resistor connects to E, to ground, to make an RC filter, using 25 ~ 100 pF. See what value looks good on the scope.

Add some NOPs to be sure the data settles before the E signal strobe, and stretch the E a bit, too.

If the PIC has a port configuration option to increase the output drive, try that, for a lower impedance drive.
 

gdx9902

New member
Thanks Cosmic,

The e line is much cleaner now. but I wonder about what you said about the low impedance drive. I'm currently using the PORT A and PORTD to control the LCD:
From the data sheet, PORT A is cmos driven while PORTD is Tristate buffered and is from my understanding of buffers, they are always high impedance. is there a way round this?

I'm thinking of using some pull up resistor arrays aroudn the 10k-100k, i'm wondering if this would help lower the impedance.
 
You haven't commented on whether any of this has solved your init problem. What did you actually do?

Buffers are only high impedance when they are tri-stated (disabled), otherwise they are CMOS outputs. So as long as your control port is set for output, there is no problem.

Pull up/down resistors will lower the impedance (assuming they are low enough resistance to have a noticeable effect), but that is not necessarily the cure to your ringing issue.
 

gdx9902

New member
Well, I've finished making the adjustments, and the Enable is triggering like a dream, and just makes it under the rise and fall time restrictions of the LCD, as well as some pull ups for the data port, which reduced the ringing nicely.

But unfortunately, the LCD shows no sign of life =(

I'm thinking at this point i most likely have burnted it out.

what do you think?
 

gdx9902

New member
Oh and I should also note that I'm holding the Enable line much longer than 250ns, i'm holding it for 1 ms.
 
What about your original init scheme, using 0x30? You implied that rows 1 & 3 of the display worked ok. Is that still the case?
 

gdx9902

New member
Ok scratch my 2nd to last post,
the lcd works, but it still only works if i set the function for 0x30, not 0x38, and I'm beginning to understand why i need two lines since the second line starts at 0x40.

But this 0x38 problem is really starting to frustrate me.
 

gdx9902

New member
as i got up to address 0x40, the cursor went back to the home position and continued to displayed the characters at the home position, constantly rewriting until 0x7F
 

gdx9902

New member
funny thing i'd like to add is that the cursor doesnt reset until the address counter reaches 0xCF and displays 'o'

i wonder if this is any significance
 
Top