How to fix all LCD problems - read this!

Many times people ask questions about how to fix their LCDs that don't display or displays wrong/random stuff. The following information, when supplied with your thread, will get your problem solved the quickest way. Fixing these problems ends up being mostly a frustrating experience unless the following are provided upfront without any "BUT"s. I believe several other helpers here would agree with me.

  1. Provide what display or display shield you are using, with a link to the product page or spec sheet. 99% chance no one else on this forum has your exact display but having a spec sheet will be the closest to having that display in hand.

  2. Provide what code you used, copy from your arduino IDE and paste it properly with the code tag, press #. Again no one will have your exact code even if you think it's THE standard code. There is a lack of standard here so everyone needs to have what you have to help.

  3. Provide clear high-resolution pictures of your connection between arduino and LCD, giving enough angles/shots to allow someone to physically trace every wire from point A to point B. Your "My circuit is correct and beautiful" argument stands better if you accompany your argument with a few clear pictures. If you drive a car, you wouldn't want an online mechanic to fix your car without even seeing the picture of your beautiful car, would you?

  4. In case your display is not behaving the way you want it to be, say it displays xyz when you tell it to do abc, provide some pictures of the wrong info and tell us whether the display always does this wrong in the same way or random wrong way.

  5. Be polite to critiques. I rarely see helpers does nothing but ridiculing the help seekers. But too often the help seekers were too arrogant/ignorant to accept any critique. If you want to be applauded, hire someone of buy a magic mirror that can lie to you.

  6. Return the favor by posting "yes, ... was exactly the problem. Now I did ... and it's fixed!". Create a proper closure.

  7. Fill up your location information could get you more help sometimes. Say you're asking about suppliers of certain LCD and with your location people can suggest you local or regional suppliers.

Now happy solving problems :wink:

A list of frequently committed mistakes:

Hardware problems

H-1) Didn't connect ground from arduino to breadboard

H-2) Didn't use a potentiometer with the contrast pin

H-3) Didn't solder headers to the LCD but just rest the LCD on the headers instead

H-4) Shorts due to soldering

H-5) Didn't have a current-limiting resistor with the back light

H-6) Read the pin numbers backward thus thinking pin 1 is pin 16 etc.

H-7) Broken LCD, against all our hopes you have a broken LCD to start with, no fixes. Get a new one.

H-8) Didn't deal with R/W (LCD pin 5) correctly. You should tie this pin to GND.

Software problems

S-1) Used the wrong pin number in your sketch

S-2) Tried to use lcd.println. There is no such function so you will see two strange characters with your text

S-3) Did not have lcd.begin(col,row); in setup

S-4) Had lcd.begin in loop (could cause LCD to flicker due to resetting the display too often)

S-5) Used old or wrong library, such as given on irresponsible eBay sellers. If you are using an I2C backpack, stick to the seller's library!!!

GLCD specific problems, written by bperrybap:
G-1) not hooking up the RESET pin (works on some glcds but not all of them)

G-2) Confusing RESET and RS signals.

G-3) hooking up the glcd contrast pot to +5v and gnd (like a hd44780 pot) vs +5v and Vee (besides the gnd vs VEE issue, bad pot wiring is very common and happens all the time even when there are instructions in multiple places and diagrams for how to properly wire up the contrast pot)

G-4) hooking up the pins incorrectly because of wrong documentation. (hd44780's for the most part all have the same pinout) Users often assume there is a single "ks0108" pinout - yet I've seen over 11 different pinout combinations.

G-5) hooking up the pins incorrectly because of the wrong part (people often buy a "glcd" and assume it is say a ks0108 when it isn't)

G-6) using multiple wires for a single connection and twisting wires together. (This one creates all kinds of weird problems)

G-7) miscounting/interpreting pin #s on the mega board. I see this quite a bit. People sometimes start at the top for pin 22 and forget the +5 pins along the top or get the left/right pins backwards or get the pins skewed or off by 1 because of a visual parallax error when picking the pins.

G-8) getting all the LCD pins backwards. Look at the data sheet and then wire everything backwards because the view was upside down which flips the order of the pins.

G-9) Powering the display and Arduino from different power supplies and getting ground loops that crater everything.

Tutorials:

http://www.ladyada.net/learn/lcd/charlcd.html

Hi liudr

Good posting. You could remove "character" from the topic. It applies to graphic LCDs also.
In fact, it also applies to OLEDs.

Where is the sticky button? :wink:

Oliver

Now we need a numbered list of answers so we can just reply with something like "number 5".

This reminds me about the old joke about numbered jokes. Try a Google search for "Joke about numbered jokes" if you don't know what I am talking about.

Don

Numbers added and character word removed.

Any suggestions please post here and I can add to the list. Right now I have hardware and software categories so you can yell H-6!

You left out any reference to grounding the R/W pin.

Also we need a reference to the missing comments here:

//LiquidCrystal lcd(RS, E, D4, D5, D6, D7);
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);      // put your pin numbers here

And the fact that this will work for almost any display:

 lcd.begin(16, 2);                          // this will work for all displays except some rare 16x1's

And the fact that this is a horrible thing to attempt when you are troubleshooting a display that doesn't work:

void loop() {
  lcd.setCursor(0, 1);
  lcd.print(millis()/1000);
}

Don

1 Like

add also, please, library misalignment issue.... too many chinese lcds come without libraries advices or, even worse, with custom ones named as "standard " libs

add also, please, library misalignment issue.... too many chinese lcds come without libraries advices or, even worse, with custom ones named as "standard " libs

And all that these custom libraries frequently do is reassign the LCD pins, something that the recent LiquidCrystal libraries can do inherently.

Don

actually there is a println() function. It is just that in most cases it doesn't do what is probably expected.
However, this hd44780 LCD library actually does support handling wraps and newlines:
http://www.pjrc.com/teensy/td_libs_LiquidCrystal.html
So that can create some confusion.

The #1 problem I see is that people don't/won't read instructions or pay close attention
to the tiny details. I think this comes from people that are not used to things
having to be very exact vs "close enough".

I think many issues on glcds that I see are often unique to glcds and don't occur
on hd44780 type interfaces so not sure if it makes sense to really combine them all.
For example here are some of the more common errors on GLCDs that I see, some
exist on hd44780 display but some wont.

  • not hooking up the RESET pin (works on some glcds but not all of them)

  • Confusing RESET and RS signals.

  • hooking up the glcd contrast pot to +5v and gnd (like a hd44780 pot) vs +5v and Vee
    (besides the gnd vs VEE issue, bad pot wiring is very common and happens all the time
    even when there are instructions in multiple places and diagrams for how to properly wire up the contrast pot)

  • hooking up the pins incorrectly because of wrong documentation. (hd44780's for the most part all have the same pinout)
    Users often assume there is a single "ks0108" pinout - yet I've seen over 11 different pinout combinations.

  • hooking up the pins incorrectly because of the wrong part
    (people often buy a "glcd" and assume it is say a ks0108 when it isn't)

  • using multiple wires for a single connection and twisting wires together.
    (This one creates all kinds of weird problems)

  • miscounting/interpreting pin #s on the mega board. I see this quite a bit.
    People sometimes start at the top for pin 22 and forget the +5 pins along the top or get the left/right pins backwards
    or get the pins skewed or off by 1 because of a visual parallax error when picking the pins.

  • getting all the LCD pins backwards. Look at the data sheet and then wire everything backwards
    because the view was upside down which flips the order of the pins.

  • Powering the display and Arduino from different power supplies and getting ground
    loops that crater everything.

--- bill

actually there is a println() function. It is just that in most cases it doesn't do what is probably expected.

I can't find one in the documentation for the LiquidCrystal library.

I looked here:

Where did I miss it?

Don

floresta:
I can't find one in the documentation for the LiquidCrystal library.

Where did I miss it?

Don
[/quote]

The new LiquidCrystal library now inherits from Print class so it has all the Print class functions including print, println with all the possible data types such as int, char etc. and the headache producer virtual write(uint9_t).

I believe we are discussing how to help those new to LCDs get them to function using the Arduino IDE.

The fact is that there is no documented lcd.println() function provided by that IDE. This stems from the fact that the LCD controller itself does not inherently support the function and in fact treats the ASCII codes for and as displayable characters instead of control codes.

The LiquidCrystal library collects the information needed to implement such a function but currently doesn't use that information. It doesn't even use that information to correctly position the cursor on 16x4 displays.

The fact that the LiquidCrystal library inherits from Print class and thus permits the use of println() essentially makes things worse. Instead of barfing and spitting out an error message it just happily displays two unrelated characters on the screen and the uninitiated have no idea of the cause.

In my opinion the basic LiquidCrystal library should concentrate on implementing all of the capabilities of the LCD controller and no more. If people want a library that more closely emulates a CRT (or LCD) terminal that is fine, but I think it should be done in a different library. We should concentrate or efforts in this thread on getting the basic LCD functions working.

I believe your choice of thread heading is a bit 'tongue in cheek' and I am not advocating a change, but it shouldn't be taken literally.

Don

@liudr

Good tread ! That should be a "sticky" tread. When I started to learn about LCD's. I came across this web site : Arduino Tutorial - connecting a parallel LCD. So I began to wired up an LCD display I bought at Active Surplus. I test the LCD using the examples codes from the IDE examples folder. And I lean about the LCD codes intructions at LiquidCrystal - Arduino Reference. And do a little at a time.

These two sites should be mention so it help the newbies.

floresta:
I believe we are discussing how to help those new to LCDs get them to function using the Arduino IDE.

The fact is that there is no documented lcd.println() function provided by that IDE.
[/quote]
println() is in the Print class which comes with the IDE. It is inherited by the LiquidCrystal library.
The Print class is a bit of weird one. It is used by things like HardwareSerial, Softserial, LiquidCrystal,
yet it itself is not really documented.
In the documentation for the LiquidCrystal library the print class function println() was left
out since it wasn't supported by the supplied LiquidCrystal library.
But you will notice that it shows up in the HardwareSerial documentation.

This stems from the fact that the LCD controller itself does not inherently support the function and in fact treats the ASCII codes for and as displayable characters instead of control codes.

The LiquidCrystal library collects the information needed to implement such a function but currently doesn't use that information.

Kind of. While the LiquidCrystal library does receive the and codes, it does not have any context as to what they mean.
The Print class got a println() call. It "knows" that there is a newline sequence.
But the and codes are handed down 1 byte at time to the LiquidCrystal Library.
They might be a newline sequence or they might be a character is desirable to print.

The fact that the LiquidCrystal library inherits from Print class and thus permits the use of println() essentially makes things worse. Instead of barfing and spitting out an error message it just happily displays two unrelated characters on the screen and the uninitiated have no idea of the cause.

It isn't really an error. println() works and does call the lcd library.
The library isn't handling it as many people assume it might.

This is a more difficult thing to deal with and solve than would it would seem to be at first glance.
The problem is that you need to have both "raw" and "cooked" modes like real operating system drivers.
This allows the code to know if the characters are to be interpreted as potential commands or as literal simple characters to be
displayed. The Arduino environment never considered such needs so now things are stuck in the middle,
where the low level "driver" type libraries don't have modes but get handed these types of characters.
They can either interpret them as commands "cooked" mode (which is what the library on the Teensy site does),
or they can display them (which most do), or they could drop and .
The problem is there is no 1 single correct answer for what to do.
There are cases where any of those 3 options make sense.
i.e. sometimes you may really want to display character 0x0d on the display, an others
you may want a to wrap the location.

In my opinion the basic LiquidCrystal library should concentrate on implementing all of the capabilities of the LCD controller and no more. If people want a library that more closely emulates a CRT (or LCD) terminal that is fine, but I think it should be done in a different library.

That would be a bit limiting for most users.
Many users want to use the lcd display for displaying information, like strings and variables, etc....
The wimpy build model used in by the IDE makes it very difficult to have one library call another.
Even if the build model were done better, it would be more difficult for users to declare the needed
classes and objects to get one library to call another library or reference its objects.
As it is today and has been for several releases,
the LiquidCrystal Library (just like the HardwareSerial library) inherits the Print class.
This makes it much simpler to be able to do things like print a string or the value of a variable.
An unfortunate side effect is the newline issue on lcd displays when println() is called
because of the way the println() function is currently being handled (or not handled)
by the LiquidCrystal library.

We should concentrate or efforts in this thread on getting the basic LCD functions working.

I totally agree.
This thread should be how to get the LCD working with the LiquidCrystal library
and not try to solve the other software implementation issues.

We should concentrate or efforts in this thread on getting the basic LCD functions working.

I totally agree.
This thread should be how to get the LCD working with the LiquidCrystal library
and not try to solve the other software implementation issues.

Bill: So, in terms of this thread, how do you think we should handle the lcd.println() issue?

Don

floresta:

We should concentrate or efforts in this thread on getting the basic LCD functions working.

I totally agree.
This thread should be how to get the LCD working with the LiquidCrystal library
and not try to solve the other software implementation issues.

Bill: So, in terms of this thread, how do you think we should handle the lcd.println() issue?

Don

Since people seem to be trying to use it, and expecting a behavior they
are not getting, I think it deserves a response by having an item in the s/w list.
S-2 is already there, but I'd change the language from:
"There is no such function" which is incorrect to
"It is not supported by most of the lcd libraries including the LiquidCrystal library that ships with the IDE".

Then if more detail is wanted, then mention, that:
With the LiquidCrystal library that ships with the IDE,
the sketch must control the display cursor position by using lcd.setCursor(x,y)
In order to scroll up all the text on the display, a buffer as large as
the size of the display is needed.
Once the buffer is scrolled, it can be used to re-write the full display.

This is more accurate since newlines are supported by at least one
3rd party lcd library and is probably supported by many of async serial
lcd devices out there.

---- bill

Now I am really pissed off (not at you Bill). I had a carefully thought out reply to the println topic completed, along with another possible topic, and the whole thing was lost with some sort of error with the forum server when I tried to post it. I'll have to remember to save everything to a text file before I try to submit it in the future.

Don

ironically, the exact same thing happened to me.
Normally, what I do is highlight all the text then do a right click copy to save it away just in case,
but my mouse went psycho on me and the web page went back in history rather than
copying the text, which means the text was lost.
I feel for you. Nothing is more frustrating to me than losing a response.

(Maybe the universe is trying to tell us something.... I'm just too dense to understand it)

--- bill

Here's my reconstructed reply.

I thought we totally agreed but I guess we don't.

I still maintain that there is no **lcd.**println() function. The fact that you can include such an undocumented function in a sketch and not trigger an error message is due to the interaction between the various libraries. The compiler does the best that it can with the information that it has, but the net result is not a 'new line'. What you wind up with is the classic case of an undocumented function resulting in an undesired result.

I'm not sure how 'scrolling' got into the discussion but this does bring up another topic that we might want to address. Your use of the term 'scroll', my interpretation of the term 'scroll', and the use of the term 'scroll lock' on most keyboards all refer to the vertical movement of characters on a display.

The LiquidCrystal documentation, however, uses the term with respect to horizontal movement of the characters on the display which probably confuses at least some people. I prefer to use the term 'shift' which coincidently is how the action is described in all of the LCD controller datasheets.

Even the 24 hour TV news people, the ones who manage to reduce our wide screen TV displays to the size of a 1950's 7" set, call this movement a 'crawl' rather than a 'scroll'.

Don

floresta:
Here's my reconstructed reply.

I still maintain that there is no **lcd.**println() function. The fact that you can include such an undocumented function in a sketch and not trigger an error message is due to the interaction between the various libraries. The compiler does the best that it can with the information that it has, but the net result is not a 'new line'. What you wind up with is the classic case of an undocumented function resulting in an undesired result.
[/quote]
In reality there is no lcd.print() function either.
Both print() and println() are implemented in the Print class which is inherited by the LiquidCrystal class.
The LiquidCrystal class only implements a write() function that can display a single character which
is what the Print class calls.
The Print class is how things actually get printed on the lcd.

There is no compiler issue here. The compiler is doing exactly what it should and that is
honoring the LiquidCrystal class request to inherit the Print class.

The issue is that the LiquidCrystal class that is supplied with the IDE does not handle
and in a way that can allow println() to work as most people would expect.
But this is really a short coming of the LiquidCrystal class not the compiler or the Print class.
It can be made to work as expected and that is what the LiquidCrystalFast library
over on the Teensy site does.
While LiquidCrystalFast currently does not do vertical scrolling, it merely wraps back to the top,
the line wrapping and newline processing is more in line to what some people would expect.

Keep in mind println() is not the only way to send a new line.
A user might also do something like:
lcd.print("line1\nline2");
This would work with LiquidCrystalFast library but would not work with LiquidCrystal
shipped with the IDE because it does not do any newline processing.
Why would somebody do this? Perhaps they are tossing out a banner screen
and want store it in flash.
i..e
lcd.print(F("line1 xxxx\nline2 yyyy"));

It isn't just a println() issue, it is a newline processing issue.

I'm not sure how 'scrolling' got into the discussion but this does bring up another topic that we might want to address. Your use of the term 'scroll', my interpretation of the term 'scroll', and the use of the term 'scroll lock' on most keyboards all refer to the vertical movement of characters on a display.

The LiquidCrystal documentation, however, uses the term with respect to horizontal movement of the characters on the display which probably confuses at least some people. I prefer to use the term 'shift' which coincidently is how the action is described in all of the LCD controller datasheets.

Even the 24 hour TV news people, the ones who manage to reduce our wide screen TV displays to the size of a 1950's 7" set, call this movement a 'crawl' rather than a 'scroll'.[/color]

I'm totally with you on the term "scroll".
It is very unfortunate the the LiquidCrystal library use the term "scroll" instead of "shift"
in the api.
The reason I brought up scrolling is that vertical scrolling often goes hand in hand with newline processing.
i.e. people often expect a display to scroll vertically when a new line is sent on the bottom line.

But this does probably indicate a need to add an item in the SW list to perhaps remind
people that autoscroll() does not turn on newline processing and vertical scrolling.

--- bill

In reality there is no lcd.print() function either.

That function is real enough for the Arduino IDE. We aren't talking about K&R, we are talking about the Arduino LiquidCrystal library and the functions associated with it.

(source: LiquidCrystal - Arduino Reference )
Function
LiquidCrystal()
begin()
clear()
home()
setCursor()
write()
print()
cursor()
noCursor()
blink()
noBlink()
display()
noDisplay()
scrollDisplayLeft()
scrollDisplayRight()
autoscroll()
noAutoscroll()
leftToRight()
rightToLeft()
createChar()

These are the documented functions that the LiquidCrystal library uses to control the HD74480U LCD controller and I feel that these are the functions that we should be supporting and explaining with respect to the use of that library. The print() function most certainly appears in that list and the println() function does not.

Anyone who cannot inherently figure out where the funny characters come from when using lcd.println() probably doesn't know or care about classes and the fact that the print class is how things actually get displayed on the LCD.

It may be true that println() can be made to work as expected with other LCD libraries but the fact remains that at the present time it is not implemented in the LiquidCrystal library. Therefore it's use in a sketch that incorporates the LiquidCrystal library is incorrect.

Don