20x4 Display with I2C not working

Hello,

i got some problems with 20x4 display with I2C. It´s not working good. When is it connected to arduino uno, there is a contrast only at two lines, 2 and 4, sometimes showing something on first line, 0 with _.
One time he shows DDDDDD on 4 lines. I think there is a problem with I2C adress, can someone help me?

Code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x20,20,4);

void setup()
{
lcd.init();
lcd.begin(20,4);
lcd.backlight();
}

void loop()
{
lcd.setCursor( 0, 0 );
lcd.print("Marty");
}

Thanks,

Marty

I think there is a problem with I2C adress, can someone help me?

Check the address for the IO Extender as per diagram of this link. (Mine I2C LCD has address 0x27, and it is working fine.)

Just getting the i2c address may not be enough. This is because there is no standard for how the PCF8574 is wired up to the LCD or how to control the backlight. As a result different backpack manufacturers wire them up in different ways and use different backlight control circuits.
This means that even if the Arduino library is given the correct i2c address it still may not work if the library also does not know how the PCF8574 output port pins are wired up to the hd44780 LCD interface pins.

Adding to the confusion is there are multiple LiquidCrystal_I2C libraries.
They don't all work the same and they have different capabilities.
The sample code shown in the original post is using a LiquidCrystal_I2C library that assumes a particular pin wiring between the PCF8574 and the LCD. It appears to be using/expecting the LiquidCrystal_I2C library available through the IDE library manager.
If the backpack uses the specific wiring that the library assumes, then all that is necessary is to get the I2C address correct. If the wiring used on the backpack is different than what the library assumes, it will not work even if the correct i2c address is used.

The newLiquidCrystal library by fm, has the ability to configure the pin wiring.
It uses a different constructor, which contains the pin mapping information.
This is nice because it allows the library work with any backpack. However, the user must correctly enter the pin mapping information. If the pin mapping information is incorrect, then it will not work.

The information in the other forum post by GolamMostafa from the link above makes reference to a library that uses a configurable pin mapping.

For ease of use, I'd recommend using my hd44780 library package.
The included hd44780_I2Cexp i/o class can auto locate the i2c address and auto configure the pin mapping so it should "just work" with your backpack.

Install the hd44780 library package using the IDE library manager. Let the IDE manager do the install rather than using a zip file.
Once you install hd44780, run the included diagnostic sketch I2CexpDiag to verify that the library and LCD are working.
Then you can look at the other hd44780_I2Cexp i/o class examples like HelloWorld, to see what files need to be included and how to declare your lcd object.

You can read more about it on the github repo: GitHub - duinoWitchery/hd44780: Extensible hd44780 LCD library
And wiki: Home · duinoWitchery/hd44780 Wiki · GitHub

--- bill

This means that even if the Arduino library is given the correct i2c address it still may not work if the library also does not know how the PCF8574 output port pins are wired up to the hd44780 LCD interface pins.

Now, I realize why the I2C LCD that works with UNO is not working with DUE. Certainly, I have added Library File which is not compatible with the LCD.

Thanks with +1 for accommodating valuable information in your post.

GolamMostafa:
Now, I realize why the I2C LCD that works with UNO is not working with DUE. Certainly, I have added Library File which is not compatible with the LCD.

Thanks with +1 for accommodating valuable information in your post.

Wait, you never said you were having issues on a DUE.
Can you take a moment to fully describe your h/w setup?

If the library is the same i2c lcd library on the Uno and the DUE, and it is working on the Uno, and it compiles for DUE, then the library is likely not the reason.

The AVR used on the Uno is 5v and the ARM used on DUE is 3v and NOT 5v tolerant. There are several issues that this voltage difference can create including potentially damaging the DUE chip when the DUE is connected to 5v outputs since the DUE is not 5v tolerant - which is one of the reasons I don't like that board.
There are ways to connect 3v and 5v parts but when the 3v part is not 5v tolerant you must take special precautions as you can't just hook them together. With i2c, a bi-directional logic level voltage is typically used to convert the voltages to what is needed.
While there are some other ways to cheat when connecting 3v to 5v parts to avoid using a logic leveler, it requires paying very close attention to the wiring and circuit designs and often requires doing a few modifications to the circuitry.

Another difference between the AVR and the ARM chip used on DUE is that the AVR has internal pullup resistors that can be enabled when the pins are initialized for I2C. The ARM chip does not.
i2c is an open drain bus. This means that the entities on the bus can drive the signals low but never high.
The high signals are created from pullup resistors on SDA and SCL. The pullup resistors are required.
While the AVR Wire library will enable the internal pullups, the DUE has none.
So i2c won't work on a DUE unless there are external pullups.
Many i2c slaves have pullups on the device, but some don't. This includes i2c LCD backpacks.
Some backpacks have them and some don't.
But keep in mind that while the internal pullups used on the AVR will often allow communication with an i2c slave, the resistors are too weak (too large of a resistance) and are way out of spec. So if there are no other pullup resistors on the i2c bus signals, there can and often are issues that can arise.

--- bill

1. My DUE-I2CLCD does not (did not) work with this Library File.

2. My DUE-I2CLCD is working with this Library File.

GolamMostafa,
For completeness, I am curious how you have wired up your DUE to the i2c backpack
as the h/w electrical connections must be resolved before moving on to the library s/w.

Did you use a level shifter on the i2c signals between the DUE pins and the backpack?


Those two LiquidCrystal_I2C libraries you mentioned are slightly different from each other, and both are different from the LiquidCrystal_I2C library that is available in the IDE library manager. Both those libraries are also different from library mentioned the original post of thread you linked to in response #1.
They both use the same pin mapping but have slightly different API functions and work slightly differently.
This very clearly demonstrates what I brought in my previous #2 post about there being multiple i2c LCD libraries with a LiquidCrystal_I2C class that have different functionality and different APIs.
This is one of the reasons I wrote the hd44780 library package.
hd44780 does not interfere with any other library and uses a class name not used by other Arduino libraries so it is not confused with other libraries.

hd44780 offers an easier to use solution that can be installed using the IDE library manager that "just works" for PCF8574 based backpacks.

--- bill

Bill,

I have detailed in the following schematic what the wiring connection I have made between the DUE and the I2C 16x2 LCD.

My reasoning for not using level sifter (5V ---> 3.3V):
1. DUE is the driver. There is no scope for any signal to arrive from the IO EXtender/LCD to the DUE.
2. VIH specification for PCF8574 : 0.7x5 = 3.5V. DUE provides 3.3V (anyway it works!).

BTW: The LCD does not work (does not show message) with Vcc = 3.3V. Contrast does not help!

I have gone through the scholastic write up you have made on the relative characteristic features of various Libraries prepared by the respective authors. I, time to time, read the .h and .cpp files of the libraries and appreciate with my utmost astonishment the hard labors of the authors for well management of high level declarations/definitions of those low level timing activities that are experienced in assembly language programming.

Go on. The Due is 3.3V. Your I2C backpack needs 5V to provide any contrast.

Remove any pullups that may or may not be mounted on the backpack.
Then replace with pullups to 3.3V

I suspect that the Due will be unhappy with pullups to 5V.

Since any I2C bus requires two real resistors as pullups your Due will cost you an extra $0.02 but these serve every Slave on the bus.

You don't need any bus extender or level shifter. Just two resistors.

David.

We have drifted a off topic since it appears that the OP is using an UNO.
But I wanted to address a few things as we get back to helping the OP.

GolamMostafa:
My reasoning for not using level sifter (5V ---> 3.3V):
1. DUE is the driver. There is no scope for any signal to arrive from the IO EXtender/LCD to the DUE.
2. VIH specification for PCF8574 : 0.7x5 = 3.5V. DUE provides 3.3V (anyway it works!).

Your reasoning not fully correct. No entity actually drives the I2C signals high. Not the master not the slaves. That isn't how I2C works. It is an open drain bus and any/all devices, master or slaves, can only pull the signals down to ground and can never drive the signals high.
The pullup resistors create the high signals
The issue is that most of the i2c backpacks have pullups on them to VCC and if VCC is 5V then the backpack can provide 5v i2c signals.

And just like I commented in post #4, and david_prentice mentions in post #8 that is possible to hook a 3v master to 5v slaves without a level shifter, but you have pay very close attention the pullup resistors as you don't want any pulling up to 5v to create 5v i2c signals.

The issue is what david and I pointed out in that you still have to worry about the pullups on the i2c backpack.
As david and I pointed out, some backpacks have them and some don't. If the backpack has them they will connect to VCC which in this case is 5v and you don't want 5v level signals reaching the DUE processor.

I had a look at the DUE V3 schematic and it does have pullups to 3v on the actual Arduino board just like the Atmega2560 so there is no need to add any additional i2c pullups to 3v since they are already there - at least on that version of the board.
Although the DUE uses 1k5 resistors vs 10k resistors.
It appears that the 1500 ohm resistor is saving the DUE from the 5v signals coming from the backpack as they are probably sinking enough current to pull the signals down to 3v by acting as a voltage divider against any on board backpack resistors - which on most of the backpacks are 4.7k

--- bill

The DUE-I2CLCD of Post#7 (my post) works(!) in the demonstration session. The connection has been made without doing any electrical calculation as to their compliance of the minimum requirements of the electrical specifications. The following calculation may lead to taking decision as to the acceptance of the connection of Post#7 in the 'field application'.

1. DUE has on-board 1.5k resistors on the TWI Bus.
2. IO Extender has on-board 10k resistors on the TWI Bus with 5V operating voltage.
3. Minimum VIH for the IO Extender: 0.7x5V = 3.5V (as per data sheet).
4. DUE can modulate the SDA line between 0V and 3.3V. This does not comply with 3..
5. IO Exteneder modulates SDA line to 0V during ACK.
6. Minimum VIH for the DUE IO: 0.7x3.3 = 2.3V (as per data sheet).
7. The Idle State of the SDA line of the TWI Bus is 1.5V ((5-3.3/(1k5+10k))*10k). This also does not comply with 6.

If the above calculation makes sense, then the network of Post#7 is not a reliable operation of the IO system though there is nothing harmful neither for the DUE nor for the IO Extender/LCD.

The required electrical specifications could be met to some extents by the following arrangements:
//------------------------------------------------------------
1(a). Operate IO Extender at 3.3V. This gives logic level of SDA line (at Bus Free State) 3.3V. This is fine.
1(b). However, the equivalent pull-up resistor will be < 1.5K. This is not fine! . This is fine as per Post#11.
1(c). LCD must be operated at 5V as it does not give contrast at 3.3V. This is fine.
1(d). Minimum VIH becomes 2.3V. DUE will pump maximum 3.3V. This is fine.

//----------------------------------------------------------
2(a). Removal of the pull-up resistors from IO Extender (as per Post#8) and keeping the operating voltage at 5V. This will bring 3.3V at the SDA line (at Bus Free State). This is fine.
2(b). Minimum VIH will become 3.5V. DUE will pump maximum 3.3V. This is, though not fine, can be accepted.
//----------------------------------------------------------

2(b). Minimum VIH will become 3.5V. DUE will pump maximum 3.3V. This is not fine.

We obviously have a language problem. What do you mean by "pump"?
I2C is an open-drain bus. The Due can only sink current i.e. LOW typically < 0.2V.
If the Due releases the line, it rises to a HIGH level via the pullup resistor. e.g. 3.3V

Since the pullup resistor is 1k5 it will take longer to rise to HIGH because it has to charge the bus capacitance.
When the Due sinks LOW the capacitance is discharged quickly by the low impedance of the active output. This is why you get the characteristic Shark fin shape on a scope trace.

You can use a level shifter or an I2C bus extender if you want. It will not be necessary if the 5V pullups are removed.

As Bill has said. the 1k5 pullup to 3.3V with a 4k7 pullup to 5V will create a HIGH level of 3.7V which is 411mV above the Due's 3.3V VCC substrate level.
This 411mV should not produce any current in the substrate diodes.
But the SAM3X datasheet specifies a maximum VDDIO + 300mV
So the 411mV is violating the max VIH Input High-level Voltage

I don't see your objection in (1b). The Due is not a low power board. 1k5 is a reasonable pullup value. And the pullups only source current when the I2C bus is active.

This thread is probably too technical for an Arduino Forum.
In simple terms:

  1. Remove 4k7 pullups from the I2C backpack.
  2. Connect to 0V, 5V, SDA, SCL on the Due.

David.

In simple terms:

  1. Remove 4k7 pullups from the I2C backpack.
  2. Connect to 0V, 5V, SDA, SCL on the Due.

Based on the criticisms/suggestions of Post#11, option 1(a-d) and option 2(a-b) of Post#10 are equally acceptable.

The above quoted option is preferable as it requires just removing two resistors.

Thanks to both Bill and David with +1s.

BTW: Pump has actually got set in my mindset from Diode Pump -- the compound noun I encountered about 30 years ago while I was working with Schlumberger Wire Line Ltd in their Flow Meter Sensor where a diode pump circuit was delivering constant current to the sensor as excitation. There, in the Post#10, pump may kindly be taken for assert. Sorry, for the inconvenience!

We have drifted off topic long enough.

Marty,
Are you still there?

Sorry for our off topic discussion.
I assume you are using an UNO board, which won't have any of this 3v issue.
I'm also assuming that you have an i2c backpack attached to your 20x4 LCD.

Did you get a chance to try the I2CexpDiag sketch in the hd44780 library?
That diagnostic sketch will find the i2c address and then perform tests on the backpack and LCD.

--- bill