LCD I2C display problem

I have tried all day with different libraries and different code, on a Nano and a Mega using a 4x40 that has a PCF8574. A scan of the bus tells me its address is 27. No matter what I try to display, it only displays the first character of my string. Anywhere I set the cursor to, it will display a single character. I have two of these displays and both do the same thing. With or without 4.7K pullups on SDA and SCL running on 5vdc. I can print to any location but only a single character at a time.

Any help would be appreciated. I have spent the better part on the day on this.

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

LiquidCrystal_I2C lcd(0x27,40,4);  // set the LCD address to 0x27 for a 40 chars and 4 line display

void setup()
{
  lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.print("Hello, world!");
}

void loop()
{
}

Help!! :confused:

Hi.

The problem isn't in the hardware, it's in software.
You are using a recent version of the IDE, and that has a bug in it.

It has been discussed here in this part of the forum, so take a bit of time and scan the pages of threads.
You will find that there are multiple solutions, the best of which (to my taste) is the altered library that solves it.
Probably the easiest to do, is to use an older version of IDE.

Is it fixed in 1.6.8?

I don't think so, but i'm not sure

also, look here.

You are using a recent version of the IDE, and that has a bug in it.

No - it is the library that has a bug in it.

Explanation and solution is here: --> 5V IIC/I2C/TWI LCD Module Adapter For Arduino from eBay - #3 by bperrybap - Displays - Arduino Forum

Don

The problem was actually fixed about 5 months ago - nearly immediately after it showed up.
It isn't related to the IDE version so updating to a newer IDE won't help since the IDE does not include this library.
The problem was that marco forgot to tag the library in his git repo so although the library had been fixed and the code was available, since it wasn't tagged, the IDE library manager didn't see it.
I got marco to fix it a few days ago.
Use the library manager in the IDE.
You can update the LiquidCrystal_I2C library to version 1.1.2 which has the correct code in write() and fixes the issue.

--- bill

GitHub - mrkaleArduinoLib/LiquidCrystal_I2C: A reimplementation of the standard Arduino LCD library, configured to work with parallel HD44780 compatible LCDs, and interfaced via a Chinese PCF8574 I2C serial extender. is the best lib I could find but it still has a problem if you write past the end of the row it advances 2 rows.

That is not a "problem" in any shape or form.

It is not the library's business to know whether you write past the end of the row.

People tend to mistake these LCD displays for a VDU.


It isn't.

GitHub - mrkaleArduinoLib/LiquidCrystal_I2C: A reimplementation of the standard Arduino LCD library, configured to work with parallel HD44780 compatible LCDs, and interfaced via a Chinese PCF8574 I2C serial extender. is the best lib I could find but it still has a problem if you write past the end of the row it advances 2 rows.

The normal LiquidCrystal library and its variant LiquidCrystal_I2C (any and all of them) just implement the HD44780U command set in a supposedly user friendly manner.

The HD44780U controller is designed to display short messages such as "Check Toner" or "Pizza Ready" on a simple LCD display. As implied previously these displays are not designed to substitute for the display portion of a dumb (or smart) terminal and hence do not correctly deal with the non-printable ASCII 'control character' codes such as and .

The controller treats those codes as it does the printable ones and use them to address specific locations in the HD44780U RAM or ROM which in most cases do not contain any predefined characters.

Don

And it most certainly does not provide in any form for the vertical scroll most people would expect for a true VDU.

I have worked on VDU's since they were in existence. Even before when I used a teletype and got away from having to fat finger my code. It would be nice though to handle an EOL. Someone probably did but to code is bad. Why else do you need to show how many rows? Is that not a valid question or is it only for the programmers to remember how many rows they have to work with?

I can work with what I have. Knowing that I cannot exced the length of a line when I send a string.

If I were wanting a VDT, I would just use a serial feed to a USB or Com port and use a terminal emulator.

Paul__B:
It is not the library's business to know whether you write past the end of the row.

Well.....
I wouldn't go that far.
It is all in what feature set that the library defines and chooses to implement.
While nearly all hd44780 libraries didn't bother to implement end of line processing, it isn't difficult to do.
The "LiquidCrystalFast" is a hd44780 library handles line wrapping:
https://www.pjrc.com/teensy/td_libs_LiquidCrystal.html

My openGLCD library also handles line wrapping as well as scrolling in user defined screen areas for glcd displays.

So I'd say that end of line processing and vertical line scrolling is a useful feature that almost none of the current hd44780 libraries have bothered to implement.

All this craziness over pcf8574 based backpack hd44780 lcd libraries is maddening.
At some point I'm going to add my hd44780 lcd libraries to the IDE library manager.
My goal is provide as close to a "it just works" solution for hd44780 based displays used with a variety of interfaces. (i2c, shift registers, direct pin control, etc...)
In addition to providing end of line processing, it can also automatically reliably correctly identify nearly all the pcf8574 based i2c backpacks so that most users will be able to get a nice out of the box experience with a pcf8574 i2c backpack without having to know the i2c address of the expander chip or know anything about how the expander i/o pins are wired up to the hd44780 pins.

I say "nearly all" because there are two pcf8574 based backpacks, which that I can not automatically identify in the library. In all the the threads with issues with i2c lcd backpacks I've seen on the forum, I have not seen either of these two backpacks being used. These two are not very common. They can be used my library but would require manual configuration in the lcd constructor.
The vast majority of users could simply let the library figure it out.

note: for all those familiar with my i2c lcd guesser sketch, the auto detection code is much more advanced than what is in the guesser sketch as it can actually figure out the backpack i/o expander pin wiring without user interaction.

--- bill

Nasa:
Why else do you need to show how many rows? Is that not a valid question or is it only for the programmers to remember how many rows they have to work with?

You have to understand how the display memory is mapped to the physical character positions on the physical display.
In order to do cursor positioning, the library has to know the geometry in order to know how to program the display memory location in the hd44780 chip when the user does something like: lcd.setCursor(col, row)
cursor positioning is not part of the hd44780 commands, and is implemented in the library.
The library has to translate a col, row to a memory location and in order to do that is must know the geometry and beyond that how that memory is mapped to character positions on the display.

The memory to screen mapping also explains why you may see characters jump to what appears to be a non contiguous location on the display when writing beyond the end of line, when the library does not support line wrapping or end of line processing.

Both Don and I mentioned the memory mapping in the other thread where you were asking about why the characters were jumping to a discontinuous line.

--- bill

Well, it still begs the question of what "end of line processing" could possibly mean on a 1602 display and a 2004 is barely more versatile.

If you run over the end of the line, should it scroll horizontally, fold over onto the next line or clear the line and start again?

If it is the second line, should it scroll vertically to the first and start on a blank new line?

What should CR do? Which of the above should LF do?

You certainly might offer a library which has these as options, but by no means does it make sense for any be the default (or we will suffer all the same questions in reverse - "where did my text go?" when it strikes the "println()"). It remains - what happens in each of these situations is the coder's business, not a library default.

Because - these displays are not a miniature VDU. As previously explained; their function is to display status messages in a specific arrangement for instant recognition. Having them display several lines of text per second (because they are really short lines) simply makes no sense.

Using lcd.autoscroll on this 20x4, will do auto scroll wherever I want it to but at the same time it writes to the third row last character at the same time. Having a lot of information to display, this causes a lot of unnecessary coding to have a clean display and wastes resources.

It is not the speed that I am after but the status of sensors and conditions and menu selections for a more friendly HMI.

I previously use a 20x2 without problems and just thought 20x4 I could have a more comprehensive display.

I can still do this, it will mean a little messier code than I like.

I previously use a 20x2 without problems and just thought 20x4 I could have a more comprehensive display.

Have you followed the link that I provided in your other thread? It explains why the 20x4 display does not natively perform the way you might expect.

Although not explicitly covered that link should also let you easily figure out why the scrolling (properly called shifting) moves both (or all four) rows simultaneously.

Don

The Codevision LCD C library handles linefeeds.
The Fleury LCD C library handles linefeeds.

I see little point in this for a 16x2 or even a 20x4 LCD.
You normally position the cursor. And send a small number of chars to the available visible space.
You position the cursor again for the next word or number.

If you really want the Arduino libraries to handle linefeeds, you can just extend the regular class.

David.

The value of handling end of line processing and scrolling is when wanting to use the lcd as a message output device.
Without end of line processing, sending a message string longer than a lcd line creates issues on the display.
If the LCD library handled it, then the sketch/application code becomes much simpler since it can simply send the message strings.

To me it is case of why make every application writer have to write his own end of line processing code when it could easily be handled in the library and used by anyone that needs this functionality?

IMO, a feature rich LCD library should have the ability to do this and the application should be able to enable/disable this functionality.
Consider this, the existing LiquidCrystal libraries do not make the application writer have to deal with calculating display memory addresses when setting the cursor position. The library offers a convenience function setCursor(col, row) which does it for the application.
The library code could (and should IMO) also provide the functionality of handling line wrapping and end of line processing. (most arduino hd44780 libraries do not provide end of line processing or line wrapping)

I have seen a few Arduino lcd libraries that handle and processing and line wrapping but most of them do not handle vertical scrolling. Most just wrap back to the 0,0 position when they get beyond the bottom line.

Having spent more than a decade writing terminal emulation s/w (back in the 80's) and having implemented code to do end of line processing and wrapping in arduino lcd libraries, here are some of my notes/observations:

When doing end of line processing on these types of displays where the number of lines is quite small, one thing that dramatically helps, is handling line wraps and linefeeds just a bit differently than the way people would think a terminal handles it.

What is needed is to defer any end of line processing or scroll operations until the next character after the needed line processing event is received.
i.e. if you get a or need to wrap, or scroll, you do not do this until you receive another printable character.
For the most part it is not noticeable but when dealing with a display with small number of lines it can make a big and noticeable difference.

If the library doesn't defer the processing, then you can never fill the entire display with characters since the LF on the last line or the act of sending the very last character on a full display causes the display to scroll leaving the bottom line empty.

i.e. if you were do something like this on a 16x2 display:

lcd.println("hello")
lcd.println("good bye");

And the library were to process linefeeds as it received them and scroll the display, you end up with a display that has "good bye" on the top line and a blank line on the bottom line.
While it could be argued that is technically correct, it is often not what is desired.
If the library were to defer the line feed processing, then both lines would be on the display and the scroll would be done as the next message is sent to the library.

Anyway, I believe that end of line processing including handling line wraps and vertical scrolling is useful functionality even on small displays.
That is why I implemented it in my openGLCD library and would provide the functionality in any future arduino lcd library that I released.

--- bill

This is totally off topic but your explanation of processing reminds me of the time we discovered that our multi-user (MP/M) system was capable of sending messages between users.

My colleague was busily working away on something that was probably important when I sent him a message consisting solely of 24 characters. He wasn't amused.

Don

floresta:
My colleague was busily working away on something that was probably important when I sent him a message consisting solely of 24 characters. He wasn't amused.

Even funnier is to send a message with LOTS of ^G in them..... :grinning: