16x1 LCD second half not displaying (tried the usual solutions)

SOLUTION:
I fixed the problem by readjusting my potentiometer to set the contrast voltage to be appropriate for when the LCD was initialized as an 8x2 display.

The ideal potentiometer value for the backlight contrast of an LCD may be different when the display is initialized to have 1 line as opposed to when it is initialized to have 2 lines because the duty cycle of each active pixel is higher when initialized as a 1 line display, which makes complete sense. Read this reply by bperrybap in a different thread for more information.


ORIGINAL POST:

I have done a lot of research to try to get my 16x1 LCD working but I haven't been able to. I am able to print characters on only the first half of the display.

I am aware of the very helpful work that has been done by Donald "Floresta" Weiman in this area. I believe I have read all of the relevant content on their website but sadly I have still not solved this problem.

After looking at countless threads, I'm also aware of the usual answers these posts get which have unfortunately not helped me. I've listed below the proposed solutions that I have already tried:

  • "16x1 displays are actually 8x2 internally so you need to configure the LiquidCrystal library as such and move the cursor to the second line to display text on the second half of the display."
  • "Check your wiring."
  • "Try printing a bunch of characters across the entire RAM range to see if characters show up on the second half."
  • "Try the hd44780 library and use their LineWrap example sketch." (result was the same, only displaying on the first half)

None of these proposed solutions have worked for me despite them seeming to work for literally everyone else. I'm thinking my LCD might be an oddball and I should just buy a different one, but I wanted to make a post as a last ditch effort to see if I can still use this one as it fits my project perfectly and I've already bought two of them.

Finally, here are the useful details of the scenario:

LCD details:
Digikey link: Digikey
Datasheet: PDF
Controller type: ST7066U
Controller datasheet: PDF
Module DDRAM map:

Schematic:

Relevant code:

#include "Adafruit_LiquidCrystal.h"

Adafruit_LiquidCrystal LCD(4, 3, 5, 6, 7, 8, 9, 10, 14, 15);

void setup() {
  // LCD screen configuration
  LCD.begin(16, 1);
  for (int i = 0; i < 200; i++) {
    LCD.print("e");
  }
}

Results of the above code:

Observations I have made:

  • I have tried the following code, which is what everyone's first suggestion will be:
Code and result
#include "Adafruit_LiquidCrystal.h"

Adafruit_LiquidCrystal LCD(4, 3, 5, 6, 7, 8, 9, 10, 14, 15);

void setup() {
  // LCD screen configuration
  LCD.begin(8, 2);
  LCD.print("First8ch");
  LCD.setCursor(0, 1);
  LCD.print("Last8ch.");
}

  • When using both Adafruit_LiquidCrystal.h and hd44780.h, configuring the display with more than one line results in a blank display. 16x1 and 8x1 = first half working. 16x2, 8x2 = blank screen.
  • I have a "type 1 module" (according to Donald Weiman) meaning it has 1 black circular IC on the back. This means the second half of the display has addresses 40-47, just like the datasheet says. This information seems to all line up but hasn't helped me find a solution unfortunately.
  • Using the full constructor and passing in all 8 data pins does not solve the problem. I initially tried just passing 4 data pins so I have tried that as well.
  • Adding a delay to the for loop test does not help both when configured as 16x1 and when configured as 8x2.
  • I bought two of these displays and have tried swapping in the fresh one with the same results.

This seems to be a tough one but I'm sure there's something I'm overlooking as usual. Thank you in advance for any responses.

40 - 47 or 0x40 - 0x47?

Decimal 40-47. At least it seems to me according to both the LCD's datasheet and this website.

It is an 8 col by 2 line display. Try

#include "Adafruit_LiquidCrystal.h"

Adafruit_LiquidCrystal LCD(4, 3, 5, 6, 7, 8, 9, 10, 14, 15);

void setup() {
  // LCD screen configuration
  LCD.begin(8,2);   // 8 col X 2 line display
  for (int i = 0; i < 8; i++) {
    LCD.print("e");
  }
  LCD.setCursor(0,1);  // set to col 0 line 2 (line numbers are zero origin)
  for (int i = 0; i < 8; i++) {
    LCD.print("x");
  }
}

I know my post was long so it sort of makes sense that you didn't read through it. This is the first point I covered in the " Observations I have made" section. Just because I'm desperate, I did try your code and got the same result as I show in the post.

I desperately wish the solution was this simple. I would've been done with this after my first Google search.

Bummer, it definitely is an 8X2 device. I'm not sure what LCD.print() does. Try LCD.write() instead - it at least is in the library .cpp file and actually writes the data to the LCD.

When numbers start with 0, I assume hex, because no one, but I, zero-pads a decimal... and the website you linked has this...
LCD-16x2-lines(b)

0x15 NAK

That's a good thought. I tried using LCD.write() in both configurations.

As a 16x1, the "e" spam showed up as "EEEEEEEE". Still nothing on the second half.

As a 8x2, the screen was blank as is the case any time I use the library to configure it as 2 lines.

So no progress there, but it was an interesting thought.

I found the solution, finally. Somehow I dug up a thread that I hadn't seen during my extensive searching.

The creator of the hd44780 library replies and mentions that the ideal potentiometer value for the backlight contrast may be different when the display is configured to have 1 line as opposed to when it is configured to have 2 lines because the duty cycle of each active pixel is higher when configured as a 1 line display, which makes complete sense.

Sure enough, I uploaded the below code configuring the display as 8x2, gave the pot a fraction of a turn, and the display lit up showing text on both lines.

Code
#include "Adafruit_LiquidCrystal.h"

Adafruit_LiquidCrystal LCD(4, 3, 5, 6, 7, 8, 9, 10, 14, 15);

void setup() {
  LCD.begin(8, 2);
  LCD.print("first");
  LCD.setCursor(0, 1);
  LCD.print("second");
}

void loop() {

}
Result

This is a cautionary tale that tells of the dangers of assuming that your contrast is not the problem, even if your LCD works in certain circumstances.

Major hallelujah moment. I'm off to go run into the next brick wall!

The contrast pot adjust has no influence on this 8x2 vs 16x1 printing issue.
Contrast adjustment has no effect on where characters are stored in DDRAM or how they are displayed on the physical display.
The contrast pot controls, well, the contrast of the pixels on the display.
So while the ideal/necessary pot setting can be different for a 1 line vs a two line LCD,
the pot setting does not control anything related to printing characters on the left vs right side of the LCD.

A Vo voltage (contrast pot setting) that is severely out of proper adjustment will either cause all the pixels to be off or all the pixels to be on.
i.e. it affects ALL the pixels on the display.

In terms of write() vs print() using either will produce the same results.
This is because the print() function in the Print class calls the write() function for each character.

When using the hd44780 library,
this does not seem possible if things are configured properly.

When using a 16x1 display that is really an 8x2 display (like the one you have)
If you use the hd44780 library, configure LCD for 8x2, and use LineWrap()
then the sketch should be able to treat the display as if it were a 16x1 display
i.e. clear the display or set the cursor to 0,0 and print 16 characters.

Your second code is different from your first code.
The first code was attempting to write 16 characters at DDRAM address 0.
This will not work since the right side of the display starts at DDRAM address 0x40
The second code writes 8 characters at DDRAM address 0
and then 8 characters at DDRAM address 0x40 by setting cursor position.
i.e. original sketch treats the LCD as 16x1 and second sketch treats the LCD as 8x2
That is a big difference.

The hd44780 library allows you to configure the library and LCD to be a 8x2 display but then allow the sketch to treat it as if it were a 16x1 LCD.

Did you try the included LineWrap example.
Note:
For your "16x1" display (which is really a 8x2 display) you will need to edit and modify the LineWrap example sketch.
You will need to change the LCD_COLS to 8 to ensure that the library & display is configured as an 8x2 display.
But after that, the sketch can talk to the LCD as if it were a 16x1 display.

One thing you won't be able to do is use the shifting functions.
Those will not work properly when using this mode.

--- bill

2 Likes

I appreciate you sharing your knowledge and adding additional context to this thread, but I'm a little confused about some aspects of your reply and I think anyone finding this thread later may also be confused by some of what you typed.

Regarding you refuting that the contrast adjustment had any effect on the addressing of the display, I don't believe I ever implied that and I certainly don't think that. Discussing that idea seems like it just adds unnecessary confusion to this post. Perhaps I'm just not seeing where this may be a point of confusion for readers, though. The big takeaway from the post should be that the ideal potentiometer value for the backlight contrast may be different when the display is configured to have 1 line as opposed to when it is configured to have 2 lines.

I would like to attempt to clarify what you typed here. I believe when you say, "this 8x2 vs 16x1 printing issue" you mean the greater issue of 16x1 LCDs being internally structured as 8x2 and you don't mean the specific scenario my post is about. Because in my scenario, the potentiometer value was critical to the problem I was having and definitely did affect how the characters were displayed on the physical display. But you are trying to highlight that the contrast setting isn't relevant to the unique addressing of 16x1 LCDs, which is the understanding I believe most people would have.

As for the rest of your reply, it is all very valuable knowledge for anyone finding this thread later. Your library seems a little easier to use when trying to use a 16x1 display than the LiquidCrystal library. I wish I would have used your library because it may have reduced a little bit of the complexity of my program, but unfortunately my code is already written.

I think we both suffered from using some ambiguous language that may have created some confusion.

It appeared to me that you did.

Which is why I did the followup up clarification.

What reinforced my belief that you were implying contrast affects addressing is in what was said and shown in the first post.
This is what lead me to this conclusion.
In your OP (post #1 of this thread)
you showed a photo of a LCD that DOES NOT have a contrast issue and seems to be working normally.

You also stated that you tried running the hd44780 library using the linewrap capability and it produced the same 1/2 display output.

(result was the same, only displaying on the first half)

That simply is not possible - so now, I'm trying to guess what was actually done.
Then a bit lower in the original post there is mention of blank display when two rows are used.

So I was not sure what you were doing/seeing or what issue you were chasing.
i.e. were you trying to understand the DDRAM addressing or trying to understand a contrast duty cycle issue, or perhaps thinking that changing contrast was moving the characters off the display to some other DDRAM address.

Combine that with this comment:

This is a cautionary tale that tells of the dangers of assuming that your contrast is not the problem, even if your LCD works in certain circumstances.

So that is why I added the clarification as there seem to be confusion over what was happening and why.

In terms of your comment:

Perhaps this is due to some language ambiguity on my part.
When I said
"how they are displayed on the physical display."
I meant how they are mapped or where they physically show up on the display
not how the pixels look.
So I was trying to say contrast controls the intensity of all the individual the pixels not where characters are placed on the display.
i.e. the characters might be invisible because of a bad contrast setting but they are still there.

But really, in the bigger picture, one should always keep in mind that if there are no pixels, when printing to the display, that is a contrast issue.

One thing I will do in a future release of the hd44780 is put a few comments in all the LineWrap example sketches, that mentions that the contrast adjustment and hence the pot setting will be different when the display is configured for 2 lines vs for 1 line.

--- bill

I at least somewhat understand the miscommunications that happened now. I was concerned about the archival value of this post being a little obfuscated after your first reply but I think it's in pretty good shape now.

That is a very succinct way to summarize the main takeaway, I like it.

Thank you for spending the time to provide your knowledge in this thread!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.