Enhanced LiquidCrystal

Mowcius: the hardware would let you do that. My software, however, sends the user defined characters to both hd44780s. My philosophy has been to try to make the software for the 40x4 act like its one device. You'd have to change the API if you wanted to be able to tell the software which lines you were defining the characters for. I suppose you could write your own code outside LiquidCrystal (or subclass it!) to LOAD the user definitions and LiquidCrystal would never know the difference.

I knew you would have the answer :stuck_out_tongue:
Right. I might look into it. I think it might be useful for a few projects I have in mind.

Thanks,

Mowcius

Inside init(), should en2 be checked for 255 instead of 0 to see if it's unused?

That one looks like an actual bug to me. It would only show up if someone passed pin 0 for en2, but a bug nonetheless.

Thanks for pointing this out!!

I updated the zip file with the changes Paul pointed out:
http://www.healthriskappraisal.org/LiquidCrystal4Bit.zip

I realized a day or two ago that the advice I gave Mowcius is needlessly complex. The 40x4 display can be thought of as two 40x2 displays each with its own hd44780 controller chip and with all the pins in common except the enable line.

Here is some completely untested code to illustrate the concept:

#include <LiquidCrystal.h>
LiquidCrystal lcdwhole(rs,rw,enable1,enable2,d0,d1,d2,d3);  //this refers to the whole 40 x4
void setup (void){
lcdwhole.begin(40,4); //initialize the whole LCD

LiquidCrystal lcdBottomHalf(rs,rw,enable2,d0,d1,d2,d3); //define a temporary LCD object that only has 2 lines
lcdBottomHalf.begin(40,2);  //initialize the 2 line object


//now load custom characters into the whole LCD:
      uint8_t bell[8] = {0x4,0xe,0xe,0xe,0x1f,0x0,0x4};
      uint8_t note[8] = {0x2,0x3,0x2,0xe,0x1e,0xc,0x0};
      uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0};
      uint8_t heart[8] = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0};
      uint8_t duck[8] = {0x0,0xc,0x1d,0xf,0xf,0x6,0x0};
      uint8_t check[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0};
      uint8_t cross[8] = {0x0,0x1b,0xe,0x4,0xe,0x1b,0x0};
      uint8_t retarrow[8] = { 0x1,0x1,0x5,0x9,0x1f,0x8,0x4};      
      lcdwhole.createChar(0, bell);
      lcdwhole.createChar(1, note);
      lcdwhole.createChar(2, clock);
      lcdwhole.createChar(3, heart);
      lcdwhole.createChar(4, duck);
      lcdwhole.createChar(5, check);
      lcdwhole.createChar(6, cross);
      lcdwhole.createChar(7, retarrow);

//now redefine custom char 0 for the lower 2 lines:
lcdBottomHalf.createChar(0,retarrow);

}  //end setup(); the temporary LCD object expires.

void loop (void){

      i = 0;
      lcdwhole.clear();
      while (i<4) {
            lcdwhole.setCursor(0,i);
            lcdwhole.print("user:");
            for (int j=0; j<7; j++) {
                  lcdwhole.print(j, BYTE);
            }
            
            i++;
}

I realized a day or two ago that the advice I gave Mowcius is needlessly complex. The 40x4 display can be thought of as two 40x2 displays each with its own hd44780 controller chip and with all the pins in common except the enable line.

Yeah. I had not had time to look into it in more detail so you saved me some time :slight_smile:

I will try that code later if my 40x4 wants to play ball.

Mowcius

Way back in my first post on this thread, under "Disadvantages" I wrote:

"The possibility that someone with a little 16x2 LCD is using the scrollDisplayLeft() or scrollDisplayRight() instructions to move data across the screen, but wants to write the data 40 characters at a time with a print statement. This version really does not let the user write data to the HD44780 DDRAM which is not visible. To accomplish a scrolling display with 40 characters per line, you would now need to write 16 characters, scroll the display, write a little more and so on."

Yesterday in the course of answering a very interesting question what came to me is that if you declare the little 16x2 LCD to the software as being 40 characters wide then you defeat the linewrap feature and can write to all of the DDRAM on the LCD. see:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1281666158/9#9

Thinking about my last 2 posts on this thread, both about ways to trick the software into doing something it really was not designed to do, reminds me of a famous story which all programmers should read and more users should know as well:

http://ifacethoughts.net/2007/12/15/levine-the-best-teacher-for-programmers/

enjoy.

Hi,

I'm using Arduino 18. I've successfully written to a 20x4 LCD and am trying to write to a 40x4 Powertip PC4004A. I've used the LiquidCrystal4bit and LiquidCrystal404 libraries (and a simple 'hello world' program) but always end up with the same thing on the screen, that is: all characters on the first and third lines are all blocks, while lines 2 and 4 are blank.

I've read through as many posts as possible but haven't found anything extra to help me. I'm confident my wiring is sound but wonder if there's a problem with the LCD itself? Has anyone had a similar issue?

Thanks for any input and ideas.

all characters on the first and third lines are all blocks, while lines 2 and 4 are blank.

This means that your LCD controller is not being initialized properly. Since the LiquidCrystal and LiquidCrystal440 libraries are correct this means that one or more of the six (or 7 for a 40x4) connections to your Arduino are bad. You did connect the LCD R/W pin (pin 5) to GND didn't you?

Don

when lines 1 and 3 are all blocks you know that the power, ground and contrast pins are OK. the LCD has not initialized, which could be a result of a bad connection/confused specification of pins on any of the other lines, as Don said.

I'll recheck all connections, thanks. It's good to be pointed in the right direction and to know where to look.

// WH4004A Test Program: WinStar 40x4 LCD 
// using Enhanced LiquidCrystal440.h
// Since the pinouts are different from Forum example 40x4 LCDs
// Available nkcelectronics.  Data sheet WH4004A-YYH-JT.pdf
// To adjust contract, 10K pot between GND and +5V, wiper W to lcd 12
// LCD Func Arduino Desc pins          Dan Magorian 10/19/2010
// 1    DB7  12      Data bus line
// 2    DB6  11      Data bus line
// 3    DB5  10      Data bus line
// 4    DB4   9      Data bus line
// 5    DB3     Data bus line
// 6    DB2     Data bus line
// 7    DB1     Data bus line
// 8    DB0     Data bus line
// 9    E1   4  Chip enable signal, lcd lines 1 & 3
// 10   RW   3      H: Read(MPU?Module) L: Write(MPU?Module)
// 11   RS   2  H: DATA, L: Instruction code
// 12   V0   W  Contrast, gnd = full
// 13   VSS GND Ground for logic
// 14   VDD +5V Supply Voltage for logic
// 15   E2   5      Chip enable signal, lcd lines 2 & 4
// 16      NC
// 17      LED+      Ext +5V Supply for fluor LED+ optional turn fluor on
// 18      LED-      Ext GND Supply for fluor LED- optional turn fluor on
//
// If char blocks show black but nothing prints, adjust contrast pot,
// and check lcd pins 13 and 14: display may not be initialized.  
// If alternate blocks and blank lines show, check E1 or E2. 

#include <LiquidCrystal440.h>
// LiquidCrystal lcd(rs,rw,enable1,enable2,d4,d5,d6,d7);
// Note: some Forum examples using LiquidCrystal440.h have wrong DB pins,
// eg DB0-DB3, or in wrong order.  The top 4 work, in this order.

LiquidCrystal lcd(2, 3, 4, 5, 9, 10, 11, 12);
void setup(){
  lcd.begin (40, 4);
  lcd.clear();
    for (int j=18; j<129; j++) {
      lcd.write(j);
  } // print English chars in rom lower 4 bits, upper 4 bits Japanese
}
void loop() {}

Dan:

Are we supposed to evaluate this code? Does it work or does it have problems?

// 9 E1 4 Chip enable signal, lcd lines 1 & 3
.
.
.
// 15 E2 5 Chip enable signal, lcd lines 2 & 4

I have never used a 40x4 device but I don't think that this is the way things work. The 40x4 is like two stacked 40x2 devices so one of the enables should deal with lines 1 and 2 and the other should deal with lines 3 and 4.

Don

The 40x4 is like two stacked 40x2 devices so one of the enables should deal with lines 1 and 2 and the other should deal with lines 3 and 4.

Most 40x4 HD44780 LCDs...

There is always the exception to the rule so I wouldn't be too sure :wink:

There is always the exception to the rule so I wouldn't be too sure

Anything is possible, but in this case not at all likely. This behavior is not a function of the interconnections between the LCD controller and the LCD PC board pins, it is a function of the internal structure of the HD44780 and the relationship between the two HD44780's on the 40x4 board. I don't think any LCD module manufacturer is going to add the necessary external circuitry to achieve the interlaced action so I stand by my statement.

Don

Dan:

Some more thoughts:

If you look at the end of the section labeled '8. Contour Drawing & Block Diagram' in the data sheet you referenced you will see that my interpretation of the Enable pin operation is correct. It is still not clear to me how to interpret 'E1=High' and 'E2=High' on that diagram since the enable pin does it's work on the transition between high and low. It will be easier to experiment and find out once you get your device functioning than to try and figure out what is meant by this translation.

// If alternate blocks and blank lines show, check E1 or E2.

When a two line LCD module is powered up but not properly initialized then the top line has blocks and the bottom line is blank. So this is an indication that neither of the controllers is properly initialized. This can be caused by a problem with any of the connections between the LCD module and the Arduino, not just E1 or E2. The usual culprit is the failure to deal with RW properly.

Don

You guys are, of course, correct (as well as fast), thanks for catching that comment labelling error of mine. It came from when I wasn't hitting E2 and saw black blocks on the 1st and 3rd lines, and neglected to correct it after I read the datasheet and saw it wasn't interlaced.

Other than that, the sketch works and I put it out there b/c not only are the pinouts different, but there was some confusion about which databus pins work with that 440 lib version, and (after trying them all) these worked in this order. I would have put it in the example playground instead of this thread but as a newbie I don't seem to have permissions to do that yet.

Dan

Here's a version with corrected comments (thanks guys!) for other newbies
fishing around (like I was yesterday) for a working example 40x4 lcd sketch.
Hope it helps someone save some hours. Dan

// WH4004A Test Program: WinStar 40x4 LCD 
// using Enhanced LiquidCrystal440.h
// Since the pinouts are different from Forum sample 40x4 LCDs
// Available nkcelectronics.com. Data sheet WH4004A-YYH-JT.pdf
// To adjust contrast, 10K pot between GND and +5V, wiper W to lcd 12
// LCD Func Arduino Desc pins               Dan Magorian 10/19/2010
// 1    DB7  12    Data bus line
// 2    DB6  11    Data bus line
// 3    DB5  10    Data bus line
// 4    DB4   9    Data bus line
// 5    DB3        Data bus line
// 6    DB2        Data bus line
// 7    DB1        Data bus line
// 8    DB0        Data bus line
// 9    E1   4     Chip enable signal, lcd lines 1 & 2
// 10   RW   3     H: Read L: Write
// 11   RS   2     H: DATA, L: Instruction code
// 12   V0   W     Contrast, gnd = full, too dark
// 13   VSS GND    Ground for logic
// 14   VDD +5V    Supply Voltage for logic
// 15   E2   5     Chip enable signal, lcd lines 3 & 4
// 16    NC
// 17    LED+      Ext +5V Supply for fluor LED+ optional turn fluor on
// 18    LED-      Ext GND Supply for fluor LED- optional turn fluor on
//
// If char blocks show black but nothing prints, adjust contrast pot,
// and check lcd pins 13 and 14: display may not be initialized.  
// If alternate blocks and blank lines show, then neither of the controllers
// is properly initialized, check RW, E1, E2, or any of the connections 

#include <LiquidCrystal440.h>
// LiquidCrystal lcd(rs,rw,enable1,enable2,d4,d5,d6,d7);
// Note: some Forum examples using LiquidCrystal440.h have wrong DB pins,
// eg DB0-DB3, or in wrong order.  The top 4 work, in this order.

LiquidCrystal lcd(2, 3, 4, 5, 9, 10, 11, 12);
void setup(){
  lcd.begin (40, 4);
  lcd.clear();
    for (int j=18; j<129; j++) {
      lcd.write(j);
  } // print English chars in rom lower 4 bits, upper 4 bits Japanese
}
void loop() {}

This last piece of code from Dan works for me and my Powertip PC4004A 40x4 LCD -- the pinouts are the same too. Thanks for putting the code here!
Ollie.