20x4 LCD Screen only prints to line 0 and 2...

I purchased a couple AMC2004A 20x4 lcd screens, I just hooked one up to test it and it works except that lcd.SetCursor only positions the column, and not the row, any number given for the row argument always prints on the top line. I tried forcing it to print on all lines by just giving it a string longer then 20 characters, and instead of wrapping to line 1 as would be expected, it jumped to line 2, and line 3 remains blanked. Any ideas on why this could be?

#include <LiquidCrystal.h>

/* LiquidCrystal display with:
LCD 4 (RS) to arduino pin 12
LCD 5 (R/W) to ground (non-existent pin 14 okay?)
LCD 6 (E) to arduino pin 11
d4, d5, d6, d7 on arduino pins 7, 8, 9, 10
*/
LiquidCrystal lcd(12, 14, 11, 7, 8, 9, 10);

void setup()
{
lcd.setCursor(3,0);
// Print a message to the LCD.
lcd.print("hello, world!       hello, world 2!  Hello, World 3!");

}

void loop()
{
}

Don't you need to call lcd.begin() to tell the library what size of display you have?

Doh! That's what I get for copy and pasting someone elses code without really looking at it :). Now it works howover row 0 is row 0, row 1 is row 2, row 2 is row 1, and row 3 is 3... I don't quite understand how that works, note in the code I am not calling setcursor to specify the row, just letting it wrap... quite odd...

#include <LiquidCrystal.h>

/* LiquidCrystal display with:
LCD 4 (RS) to arduino pin 12
LCD 5 (R/W) to ground (non-existent pin 14 okay?)
LCD 6 (E) to arduino pin 11
d4, d5, d6, d7 on arduino pins 7, 8, 9, 10
*/
LiquidCrystal lcd(12, 14, 11, 7, 8, 9, 10);

void setup()
{
lcd.begin(20,4);
lcd.setCursor(3,0);
// Print a message to the LCD.
lcd.print("hello, world!       hello, world 2!     Hello, World 3!     Hello, World 4!");

}

void loop()
{
}

I believe this is because a 4-line LCD display is really two 2-line display controllers connected together. For some reason, the designers used one controller for lines 1 and 3, and the second controller for lines 2 and 4. Maybe there's a legitimate electrical engineering reason to do it that way, or maybe someone was just crazy.

Whatever the reason it's an easy thing to get around, thanks!

http://web.alfredstate.edu/weimandn/lcd/lcd_addressing/lcd_addressing_index.html

The above reference tells you how the memory on board the LCD maps into screen positions.

There are two ways to get around the 1324 problem:

  1. Only print short messages that you carefully plan so they don't ever go on to the next line. Use setCursor to move among lines, which always work.
  2. Write a routine to treat a long message so it splits the long message into 20-character pieces and print then setCursor and then print.

Awesome thanks for the link, it really cleared up what is going on.

I believe this is because a 4-line LCD display is really two 2-line display controllers connected together. For some reason, the designers used one controller for lines 1 and 3, and the second controller for lines 2 and 4.

This is all wrong for the displays in question, but that is essentially how the 40x4 displays work (except that the rows are grouped as 1-2 and 3-4).

In general almost all of the LCD modules require that the controller be configured as having two lines of memory. This includes all of the displays with four rows of characters, all of the displays with two rows of characters, and most of the single row (16x1) displays as well. One line of memory deals with rows one and three and the other line deals with rows two and four.

Some rare 16x1 displays require that the controller memory be treated as having only one line of memory. If your controller is programmed this way and you attach one of the other displays you cannot display anything on rows two and four (and you also mess up the contrast).

Quiz: Guess which configuration is the default if you omit the lcd.begin() statement, the one that works with the majority of the displays that seem to be out there or the one that works with the few others?

Maybe there's a legitimate electrical engineering reason to do it that way, or maybe someone was just crazy.

It's legitimate when you understand the technical constraints that the engineers were under when they designed this chip more than three decades ago.

In my opinion there's no excuse for the choice of the default configuration if you omit the led.begin() statement, especially since it was not a part of the first 16 versions of the LiquidCrystal library and is therefore missing from all of the old example sketches.

Don

There are two ways to get around the 1324 problem:

Actually there is another that I know of. The LiquidCrystal1.0 library, which started life as the LiquidCrystal440 library handles this inherently.

To get a copy start here:--> Google Code Archive - Long-term storage for Google Code Project Hosting. and follow the Downloads link to get to the latest version.

Don