Low contrast if LCD is initialized

Hi all,

I’m using a 16x2 lcd for my projects. Currently (I’m building a simple alarm, starting simple) I have the common 16 pins LCD connected to the UNO via digital pins, using a 10K potentiometer to control the contrast.

I noticed that in normal conditions (meaning lcd initialized using lcd.begin(16,2) in setup() ), I have to rotate the potentiometer almost to its end in order to see something.

If I decide to NOT initialize the lcd (directly printing without lcd.begin() ), I can obviously print only on the first line, but the contrast is great.

Eg: a code like this prints “Hi” but the contrast is terrible. There is no way to make it clearly visible.

#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void setup()
{
  lcd.begin(16, 2);
}
void loop()
{
lcd.setCursor(0,0);
lcd.print("Hi");
}

This code does the same job (in the wrong way) but the contrast is correct.

#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void setup()
{
// nothing here!
}
void loop()
{
lcd.setCursor(0,0);
lcd.print("Hi");
}

I can’t see the reason for such a behavior.

Any idea?

thanks,
Nicola

Here’s the explanation:

I noticed that in normal conditions (meaning lcd initialized using lcd.begin(16,2) in setup() ), I have to rotate the potentiometer almost to its end in order to see something.

Most consumer grade LCDs have good contrast with the voltage at pin 3 approximately 4.5v less than the voltage at pin 1. This means that the pin 3 voltage is at about +0.5v with respect to GND so the potentiometer will be very close to one end of it’s range.

If I decide to NOT initialize the lcd (directly printing without lcd.begin() ), I can obviously print only on the first line, but the contrast is great.

The LiquidCrystal library will default to working as if a 16x1 display had been specified. The second number refers to the number of lines of memory in use by the display controller. The devices that use 1 line of memory use a different multiplex (look it up) rate than those that use 2 lines of memory, hence the contrast adjustments are different as well. That’s about as good an explanation as I can give in simple terms.

Don

Actually, your explanation is extremely good. It means I'm not making stuff up or going crazy over some minor difficulties.

However, I remember some weeks ago that I had almost the same sketch but the potentiometer was at about 2/3. It seems to me as it changed over a short period. Is this possible?

Also, is there any easy way to adjust contrast, without using PWN/code? Maybe a bigger potentiometer, or some resistors? I was in love with those little knobs...

Thank you again Don

It seems to me as it changed over a short period. Is this possible?

The contrast is dependent on the supply voltage and the temperature so if either of those changed drastically then there could have been a change in the contrast.

Also, is there any easy way to adjust contrast, without using PWN/code?

Typically there's not much need to adjust the contrast so most applications make no provisions to do so. I just connect pin 3 to GND and my displays work quite well.

Maybe a bigger potentiometer,

The size of the potentiometer (within reason) will affect the power drawn from the supply but will have little or no effect on the range of adjustment of the contrast.

or some resistors?

Resistors between pin 3 and GND will usually work. Start with 1000 ohms or so and work down.

Don

Nicola_Fu:
If I decide to NOT initialize the lcd (directly printing without lcd.begin() ), I can obviously print only on the first line, but the contrast is great.

Your constructor indicates that you are using the LCD in 4 bit mode.
Given you are using the LCD in 4bit mode, it is simply not possible to use the lcd without calling lcd.begin() as lcd.begin() is where the LCD will be initialized to be in 4 bit mode.
You cannot use a LCD in 4 bit mode before initializing the lcd to 4 bit mode as the default mode is 8 bit mode…
You are not doing proper testing to verify what you think are you seeing.
In other words, you have not started your testing from a common clean initial starting point.
You have run some code that did not initialize the LCD without first powering off the LCD. The problem with that is that you are using an LCD that has been previously initialized since you previously ran some code that initialized the device into 4 bit mode.

Try your testing without using lcd.begin() after a full/clean powerup.
i.e. remove the lcd.begin() from your code, upload the code, then turn off the power to arduino & LCD.

When it powers up again, it won’t work.

— bill

@bill

I tried unplugging the usb, the power, resetting, removing the lcd uploading another code with no lcd involved, uploading an empty code, etc.

whenever I lcd.print() without lcd.begin(), the lcd actually prints with a strong contrast (too strong).

Even if the lcd hasn't been initialized.

I know it makes no sense (apart from Don's explanation up here).

I went back and looked at the LiquidCrystal library. That library initializes the LCD in the constructor, so the LCD will be put into 4 bit mode even if you don't explicitly call begin(). (Most other LCD libraries don't work this way) However, it is bad practice to do things like that in a constructor since many parts of a system are not available at this time. For example i2c LCD libraries cannot use the Wire library in their constructor since the Wire library is not available for use at that point in time.

In terms of what is happening, the LiquidCrystal library is initializing the LCD to 4 bit mode in the constructor; however, this default initialization initializes the LCD to 1 line mode. The call to begin(2,16) is initializing the LCD to "more than 1 line" mode - which is what you need.

Don may have more information, but from what I've seen, if you initialize an LCD to 1 line mode vs more than 1 line mode, the contrast on the display will be significantly different.

I'd say you need to call begin() to properly initialize the LCD, and then simply adjust the contrast as desired by adjusting an attached potentiometer on the contrast input signal.

--- bill

The call to begin(2,16) . . .

This looks like a throwback to an ancient example program where they had the argument backwards. Have you been using the 'Wayback Machine' again?

Don may have more information. . .

Virtually all of the displays commonly available have the controller memory configured in 2 lines. Some of the 16x1 displays are configured as 1 line and some (all ??) of those can be configured with either a 5x8 or a 5x10 character matrix.

As a result each of these use a different multiplexing technique resulting in three different possible multiplex rates or duty factors. This information is summarized in Table 9 of the HD44780 datasheet.

Looking at the two 5x8 examples you can see that the devices configured to use 1 line of memory have a duty factor of 1/8 whereas the devices using 2 lines of memory have a duty factor of 1/16. Since they are 'on' only half as long the contrast has to be cranked up for the devices with the 1/16 duty factor.

After about eight years the college that hosts my LCD info pages has cleverly decided to restructure their website thus breaking all of the links to those pages and losing my 1st place Google ranking. The stuff that used to be at [u]http://web.alfredstate.edu/weimandn[/u] is now at http://web.alfredstate.edu/faculty/weimandn. Hopefully they can put in the redirect that I requested. The material relating to the memory structure is found at the [u]LCD Addressing[/u] link.

Don

floresta: This looks like a throwback to an ancient example program where they had the argument backwards. Have you been using the 'Wayback Machine' again?

oops... :blush: It was a typo on my part. It should have been begin(16,2)

Looking at the two 5x8 examples you can see that the devices configured to use 1 line of memory have a duty factor of 1/8 whereas the devices using 2 lines of memory have a duty factor of 1/16. Since they are 'on' only half as long the contrast has to be cranked up for the devices with the 1/16 duty factor.

And there is the answer to the OP's question. When the sketch does not call begin(16,2), the library initializes the display to 1 line mode and in 1 line mode the pixels get twice the duty cycle so they are darker.

Since the display being used is 2 line, the library needs to be told to put the LCD in more than 1 line mode, by using begin(16,2) which will lower contrast so it will need to be adjusted with the pot.

--- bill