20x4 lcd not working in 2 line mode

I've got a 20x4 display, and I'm using it with the LiquidCrystal library. When the library initializes the LCD as a one line display (e.g., begin(20,1)), everything works except I can only print on the first and third lines.
When the library initializes the display in 2 line mode (e.g., begin (20,4)), the display stays blank no matter where I write on it.
I'd like to be able to use all four lines.
In case it matters, I'm using it with an ESP32. I've tried the display in both 4 and 8 bit modes.

We need to see exactly how it is wired and the code you use to test.

Make sure that you readjust the contrast after changing modes.

Don

Does the contrast change so radically between 1- and 2-line modes? That would be interesting. I am using a fixed resistor but I may try that.

Here’s some sample code:

#include <LiquidCrystalARP.h>

const int rs = 12, en = 14, d4 = 27, d5 = 26, d6 = 25, d7 = 33;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  lcd.begin(20, 1);  // goes blank when you change 1 to 4
}

void loop() {
  for (int i=0; i<0x7F; i++) {
    lcd.setCursor(i,0); // The memory locations on [color=#4d5156]HD44780[/color][color=#4d5156] range from 0 to 0x7F, and lcd.setCursor(i,0) sets the memory location to i, disregarding the row[/color]
    lcd.print((char)(i+32));
  }
  delay(1000);
}

The connections were as indicated in the code, with rw, vss and backlight cathode pulled to ground, vdd to 3.3V and backlight anode at 5V.

Normally these are run with 5V devices. So maybe the problem is that in 2-line mode it can’t handle 3.3V data, but in 1-line mode it can?

I think that you are right that it is a 5V display. I am surprised that it works at all at 3.3V.

If you want to use that particular display I suggest that you get an I2C backpack for it and a level shifter for the i2C lines. That way you power the display with 5V and level shift SDA and SCL from the LCD 5V to the ESP 3.3V. That is how I have done with the 2004 display and ESP8266. If you go that way, I recommend the hd44780 library for I2C displays. It is available through the IDE library manager. It makes using an I2C display nearly plug and play.

An alternative is that there are many TFT displays that work at 3.3V and use the SPI bus.

I think I have an Arduino micro clone somewhere in a parts box. That's a 5V device, right? That would let me check if the issue is the voltage. I may also have an I2C backpack that I ripped from another display some years back. (I have $2 remaining in the project budget. :frowning: I may just need to live with only two lines on the display working.)

Yes, it looks like the Micro is 5V (I have never used one).

Here is a level shifter that I use if you stay with the ESP and I2C backpack.

arpruss:
Does the contrast change so radically between 1- and 2-line modes? That would be interesting. I am using a fixed resistor but I may try that.
. . .

Yes, the contrast changes considerably due to the different duty factor, 1/16 for 2-line vs 1/8 for 1-line.

Just short out your resistor (connect LCD pin 3 to GND) for a quick check.

Don

arpruss:
. . .
The connections were as indicated in the code, with rw, vss and backlight cathode pulled to ground, vdd to 3.3V and backlight anode at 5V.

Normally these are run with 5V devices. So maybe the problem is that in 2-line mode it can’t handle 3.3V data, but in 1-line mode it can?

Running with VDD = 3.3v introduces another problem. The contrast voltage (pin 3) must typically be about 4 to 5 volts below VDD for a readable display. This means that you mey need a negative voltage at pin 3.

Don

Run the LCD at 5v
The 3v signals from the processor should be able to control the LCD when the LCD is operating at 5v.

Make sure to never read from the LCD by always strapping R/W to gnd.

--- bill

bperrybap:
Run the LCD at 5v
The 3v signals from the processor should be able to control the LCD when the LCD is operating at 5v.

Make sure to never read from the LCD by always strapping R/W to gnd.

That’s exactly what I’m doing, and everything works great in 1 line mode, but then I can’t print on lines 2 and 4 on the display. And then when I switch to 2 line mode, everything disappears. It’s not such a big deal–I managed to format my data so it fits on two lines, but it’s a bit annoying.

bperrybap:
Run the LCD at 5v
The 3v signals from the processor should be able to control the LCD when the LCD is operating at 5v.

Make sure to never read from the LCD by always strapping R/W to gnd.

--- bill

arpruss:
That's exactly what I'm doing,

That isn't what you said in post #3

The connections were as indicated in the code, with rw, vss and backlight cathode pulled to ground, vdd to 3.3V and backlight anode at 5V.

Accuracy for this type of detail really matters.
When running a 5v LCD at 3v, there very often is contrast issues.

and everything works great in 1 line mode, but then I can't print on lines 2 and 4 on the display.

Sure, because the library was told it is a 1 line display and you are trying to position beyond the largest row.

And then when I switch to 2 line mode, everything disappears. It's not such a big deal--I managed to format my data so it fits on two lines, but it's a bit annoying.

This doesn't make sense. You said everything disappears when you run in 2 line mode.
Now you say you have everything fitting on two lines ?

The display should work fine.
Make sure to:

  • tell the library the LCD is 20x4 (no matter how many of those 4 lines you are actually using)
  • run the LCD at 5v
  • set the contrast voltage appropriately for a good contrast
    I would use a pot as that will let you vary it since the needed voltage for the ideal contrast can vary a bit depending on the LCD supply voltage.

--- bill

To set the contrast, you need a potentiometer - you can use a 10k but a 1k or 2k will work better - connected between pin 3 (wiper) and ground (one end). Do not connect the pot to 5 V.


Expand

Noting that the contrast resistors - R1 to R5, "222" = 2k2 - are the same for the 2004 as the 1602.

R9 is duplicated as R10, 100 Ohms on this board for double the backlight current as the 1602.

bperrybap:
This doesn't make sense. You said everything disappears when you run in 2 line mode.
Now you say you have everything fitting on two lines ?

Yes, that's exactly correct: when I run the controller in "2 line mode", nothing shows up on the screen; when I run the controller in "1 line mode", I can put text on lines one and three.
I realize that sounds confusing. My description earlier in the thread presupposed reading the datasheet for the LCD controller as well as looking at the library code. Here's a quick summary of the datasheet.
Let me try to explain the issue more clearly.
I have a 20x4 LCD. The HD44780-compatible controller has something called "2 line mode". It's the 0x08 bit in the display function register (labeled N in the above datasheet summary). When you call lcd.begin(cols,lines) with a lines argument bigger than 1, the LiquidCrystal library sets the 0x08 bit in the display function register. This is confusing, since "2 line mode" on the controller is normally used BOTH for 2 line and 4 line LCDs.
Anyway, for me, I can draw text on lines 1 and 3 of the display when the "2 line mode" 0x08 bit is not set (e.g., by calling lcd.mode(20,1)) but when the 0x08 bit is set (calling lcd.mode(20,4)) nothing shows up on any display lines. It may seem surprising that I can actually draw text on two of the lines of the display when I working in 1 line mode, but it actually makes sense when you know how the display works.
My understanding from the Internet is that a 20x4 display is wired up to the display controller in such a way that the controller treats it like a 40x2 display with the physical lines 1 and 3 being treated as a single 40 column line and the physical lines 2 and 4 being treated as a second 40 column line, when the 0x08 bit is set. When the 0x08 bit is not set, however, the controller treats it like a 40x1 display, with physical lines 1 and 3 being treated as a single 40 column line.
Because of this, although I don't get any display when I call lcd.begin(20,4), when I call lcd.begin(20,1), I can draw text on line 3 by placing the cursor on columns 20-39. Thus,

lcd.mode(20,1);
lcd.setCursor(4,0);
lcd.write('X');
lcd.setCursor(24,0);
lcd.write('Y');

will draw an X in the fifth column of line one, and a Y in the fifth column of line three. But there is no way of drawing any text on lines two and four.
On the other hand, if I change mode(20,1) to mode(20,4), then regardless of what coordinates I put into setCursor(), nothing shows up on any display line: I just have a blank lit-up screen.

arpruss ,
how hd44780 displays work, including the various modes and internal DDRAM addressing is well understood to the posters in this thread as they have been involved with these displays for MANY years and some, including myself, have been involved with and written hd44780 LCD libraries, including for Arduino.

In your case, as we suspected you are running the display in 1 line mode and putting all your characters on that one line.
The 20x4 LCD just happens to have all the lcd pixels for that one row of characters on 2 rows of the physical glass display.

What is confusing is being giving incomplete and inconsistent information.
i.e. in post #3 you say you are running the LCD at 3v but then in post #10 you say you are running the LCD at 5v.

Like we have been saying when running a 5v LCD at 3v there can be contrast issues that can not be resolved with using a resistor or even a pot being used to control the contrast voltage to the Vo signal.

These types of LCD modules are fairly simple devices and well understood since they have been around a long time.
IMO, if you were to follow the guidance being offered by everyone in this thread, you could quickly have it up and running properly.
I even simplified down what you need to do in post #11 to 3 simple steps.

You came to the forum for some help / guidance, and have managed to attract the attention of some of the most knowledgeable people about hd44780 LCDs and Arduino LCD libraries, now all that is necessary is to listen to their input and take their advice to get your stuff up and working.

--- bill

Sorry about the 5V confusion in Post #10. I don’t remember what happened there, but I probably misread what you said. I was running the backlight at 5V, but the LCD at 3.3V. I’ve tried running the LCD at 5V, but the one time I managed to get the contrast to show a display at that setting, the display was garbled, suggesting to me that when I run the LCD at 5V, the 3.3V signals wouldn’t get picked up correctly.
When I run the LCD at 3.3V, everything works fine, but only in one-line mode, and when I switch to two-line mode the display disappears. And I don’t think the disappearance of the display in two-line mode is a contrast issue, because when I set maximum contrast by grounding the contrast pin, the display is still gone in two-line mode (but looks great in one-line mode).
Sadly, I haven’t found a pot of the right value (all I found were some 100K pots, and they don’t work in this context), so I have just been experimenting with fixed resistors.

arpruss:
Sorry about the 5V confusion in Post #10. I don't remember what happened there, but I probably misread what you said. I was running the backlight at 5V, but the LCD at 3.3V.

And as we said, you are likely to have contrast issues when doing that.
It may require using a negative voltage which you don't have.

I've tried running the LCD at 5V, but the one time I managed to get the contrast to show a display at that setting, the display was garbled, suggesting to me that when I run the LCD at 5V, the 3.3V signals wouldn't get picked up correctly.

I just tested a 16x2 LCD using an espduino32 board.
The LCD running at 5v and using a pot for contrast control.
This should be similar to your setup. (other than using a pot instead of a resistor for contrast voltage control)
The main thing being a 3v esp32 connected to a hd4470 LCD running at 5v.
Even with only 2 lines (16x2), the hd44780 chipset will be initialized and in the same mode as it would be if the LCD library were initialized for a 20x4 display.

No issues seeing pixels when using either the LiquidCrystal library or the hd44780 library using the hd44780_pinIO i/o class.

When I run the LCD at 3.3V, everything works fine, but only in one-line mode, and when I switch to two-line mode the display disappears.

I would not call that working "fine".

And I don't think the disappearance of the display in two-line mode is a contrast issue, because when I set maximum contrast by grounding the contrast pin, the display is still gone in two-line mode (but looks great in one-line mode).

I believe that it is a contrast issue.
When using 3v for the LCD you may need a negative voltage to get the contrast voltage you need to see pixels.
If that is the case (which is likely), then even grounding the Vo pin will not create a voltage that will show pixels as the voltage even at 0v will still be too high.

Again, I would recommend doing things as recommend in post #11

--- bill

bperrybap:
I just tested a 16x2 LCD using an espduino32 board.
The LCD running at 5v and using a pot for contrast control.

Thanks for the testing! Are you using 4-bit or 8-bit communication?

arpruss:
Thanks for the testing! Are you using 4-bit or 8-bit communication?

4 bit.
The LCD data mode (8 bit vs 4 bit will) should have no effect on the contrast of the LCD.

If you use the hd44780 library, it will be faster in 4 bit mode than the LiquidCrystal library in 8 bit mode.

--- bill

Thanks, Bill.

I've experimented some more, varying resistors by hand with the LCD at 5V.

In 1-line mode, sometimes I get garbled text on lines 1 and 3. Sometimes I get all black rectangles on lines 1 and 3 (and, no, it's not a contrast issue, as I can dim them by changing resistors until they are barely visible, and text never shows up). Once or twice I got text looking right (though of course only on lines 1 and 3). And of course there is nothing on lines 2 and 4, but that's to be expected.

In 2-line mode, usually I just get all black rectangles on lines 1 and 3 (again, I can dim them until they are barely visible, and text never shows up, so I don't think it's a contrast issue) and nothing on lines 2 and 4. But I have also seen garbled text on lines 1 and 3. And once I think (unless I had the wrong version of the code in the device) I actually got correct text on lines 1 and 3. But the only time I ever saw anything on lines 2 and 4 was when I was doing some hotplugging and things glitched and I got weird flashing garbled text on all four lines.

It's also a lot more sensitive to the power supply with LCD connected to 5V. It works more often when plugged into a standalone charger rather than the laptop. At 3.3V, it works reliably almost all of the time, but of course only in 1-line mode.