2004A 20x4 with Backpack Skips line

This is the very same issue as this post:

4x20 LCD HD47780, skips line

I read everything and it was the consensus as far as I understood that the LCD and backpack is operating normally, but I cannot understand why anyone would do this. I would deem the I2C library covering this as BROKE and in need of fixing. Now if I am wrong, I would appreciate anyone with much better coding experience than me (virtually none) to help with some sort of workaround.

The issue is that word-wrap or sentence wrap goes from line one to line three, then back to line 2. I guess it forces people to control each line of text as separate, but seems to me that counting characters and ensuring they are displayed on the proper line for some of the more mundane tasks as arduous when all we need it to do is write line one, wrap to line 2, wrap to line 3, wrap to line 4 instead of what it is doing now, write to line one, wrap to line three, wrap to line two, wrap to line 4.

I am not dissing anyone on purpose and I am new to Arduino so maybe there is some grand plan that makes it better this way? Thanks everyone. My first post! Happy to provide more info if this is confusing anyone. I got the code at this URL: https://arduino-info.wikispaces.com/LCD-Blue-I2C#v1

The issue is that word-wrap or sentence wrap goes from line one to line three, then back to line 2.

This is normal operation for the display. It was not designed as a mini CRT replacement for applications that display large amounts of text. It was designed to show short messages on devices such as printers to tell you when the toner was low and things like that.

The LiquidCrystal library was designed to implement the instruction set of the LCD controller and, since the controller doesn't do line wrapping neither does the library.


Ok, I understand that enough, but wouldn't it be just as easy to have it NOT skip line 2? Maybe there is some issue that makes that hard or something. Wish I knew a way around it. All you have to do to cause the problem is say "Your Printer is Out of Ink!" Now you are beyond your 20 characters and wondering why would they not just make the LCD lines sequential. So seems to me the powers that be would fix that or give us the option to somehow re-code the library. Thanks for your time!

Deve, You appear to be viewing the world with a young set of eyes. Remember that the hd44780 display and its interface goes back about 30 years. h/w, memory and compute resources were much more limited and expensive back then. What you are seeing is an effect due to the way the h/w works. The h/w is fairly simplistic in these devices and it does not know the geometry of the actual LCD. The way the chip works allows it to be configured across a variety of lcd geometries by attaching external components. What you are seeing makes sense if you look at how the h/w works. The host s/w must deal with any / all geometry issues such as lines and line wrapping, if that is desired, to make the display look like and work like a display of lines/columns that matches the geometry of the physical LCD attached to the chip.

All that said yes, it could be dealt with in a better way in the Arduino s/w library that talks to the LCD h/w. The current set of LiquidCrystal type libraries are for the most part a thin shell layer on top of the h/w. They simply provide an API function to communicate with the display. There are a few functions like setCursor() that go beyond that and attempt to provide more than what the h/w provides, by providing a knowledge of rows/columns. But for the most part the library authors punted on doing much more. Keep in mind that even just 8-10 years ago when Arduino started, resources in the AVR chips used at that time were much more limited than they are today and adding more sophistication to the LiquidCrystal library would start to eat up all the precious resources available for user sketch code. i.e. what good would a very smart library do if it ate up nearly all the code and RAM available in the part? So I do cut them some slack for creating a library that has reduced functionality since it goes back to the early days of Arduino. Today with arduino boards with much larger resources, things could be done better.

What is missing in these libraries is end of line processing. While not that difficult, I have only seen 2 libraries that actually did it. One was LiquidCrystalFast found here: https://www.pjrc.com/teensy/td_libs_LiquidCrystal.html

And LiquidCrystal440. Some discussion about it here: http://forum.arduino.cc/index.php?topic=46845.0 And I found a version on github here: https://github.com/rzzmttzz/arduino/tree/master/libraries/LiquidCrystal440 Not sure if they are the same, but the time frame for them (5 years ago) is similar.

I have a library called hd44780 which eventually will support end of line processing, including line wrapping and display line scrolling. But as of now it is not yet implemented.

Implementing it correctly is not as simple as it sounds. There are some features that would break if end of line processing was always enabled. Also, the display can draw characters from right to left or left to right. End of line process and curssor positioning must take that into consideration as well. So it has to have modes to enable/disable end of line processing if the library is to continue to support all the existing chip set features. BTW, pretty much none of the current LiquidCrystal libraries will set the cursor position correctly for home(), clear() and setCursor() when using right to left scrolling. I do know that LiquidCrystalFast has code to deal with it and it mostly works. There are a few minor issues with it but they are not too difficult to fix.

--- bill

Thank you Bill for the detailed response. I will look these other libraries over to see if there is anything there that makes sense. Speaking of making sense, I come from a generation when common sense was the order of the day. In 1979 when the first Radio Shack and Atari and Commodore machines came out, I went the Atari route and in 1984 when the ST line came out with the GEM operating system, you could turn your computer on and the OS was instantly ready for input. I wonder how many gazillion hours of time has been wasted since then going backwards waiting for hard drives to spin up first. Just an example. Sometimes it just pays to look at things from the standpoint of the end user. What makes common sense? My example is not arguable since we have had non volatile ram since the first Smart Modem.

We all want Arduino and everything it embodies to succeed. My hope is that the gurus that be think of this project as an all inclusive endeavor where everyone is on the same page in listening to the end user. In this case, what would there be to listen to? Line one, then line two, then line three. I mean right? So, I know this bothers some of the more 'edumacated' programmers who are responsible for this, but this one just slipped right through the cracks. Hopefully someone who has the ability to fix one of only a few capabilities to display information, the LCD can make this oversight go away.

It is such an amazing platform and so many intelligent and really talented people are part of this. I can see the attraction and I am learning with great enthusiasm and I hope my words of wisdom is not taken as disrespect when in fact it is for the betterment of a great platform. Thanks again!

In this case, what would there be to listen to? Line one, then line two, then line three. I mean right?

In his first paragraph Bill said: "The h/w is fairly simplistic in these devices and it does not know the geometry of the actual LCD. The way the chip works allows it to be configured across a variety of lcd geometries by attaching external components."

In other words the LCD controller (which predates those Radio Shack, Atari, and Commodore computers that you mention) can control displays with varying geometry such as 8x2, 16x1, 20x2, 16x4, 20x4 etc. It can do all this in spite of the fact that there is no way of telling the controller what the geometry of the attached display actually is.

The LiquidCrystal library does require that you tell it the geometry of the attached display but all it currently does with that information is determine whether to deal with one or two lines of controller memory (sort of related to the number of rows of characters on the display) and some basic attempts at cursor positioning. Bill has pointed out some of the problems that crop up in that area.

If you want to know more about the gory details behind all this then follow the [u]LCD Addressing[/u] link at http://web.alfredstate.edu/weimandn.

I worked with John Raines as he was developing the LiquidCrystal440 library which was primarily developed to deal with 40x4 displays. His program notes state: "Linewrap When you declare the dimensions of the LCD in your begin call, the LiquidCrystal library remembers how long the lines are. Now when it reaches the end of line 1, text wraps onto line 2 (not line 3 as previously)."

To get a copy start here:--> http://code.google.com/p/liquidcrystal440/ and follow the [u]Downloads[/u] link to get to the latest version. The 'latest' version is more than 5 years old and is called LiquidCrystal1.0 . This is what you need for the current versions of the Arduino IDE.


EDIT: I just noticed the reference to 'backpack' in your thread title. I guess that precludes the use of LiquidCrystal1.0 . Perhaps you can peruse the code and get some ideas.

Deve, I don't think you read my post closely enough. Don mentioned some of this, but I'll add some additional comments.

The seemingly strange ordering of characters/lines on a 4x20 display is not something that the libraries have intentionally or unintentionally done in their s/w or was just an "oversight". See Don's LCD addressing link to see how the hd44780 memory is mapped to various lcd geometries.

Believe me many people know about the inconvenience the h/w memory addressing creates for certain usage cases for the end user. And this issue comes up about once a month or so.

To make the display work like a mini terminal takes additional library s/w and in the early days of Arduino, realistically, there was not enough to spare code and ram space for that code. Even today on the AVR platform, the m328 is still quite limited on resources and other smaller chips like the tiny series are much smaller and some of the LiquidCrystal type libraries are being used on those processors as well.

There are many tradeoffs involved. For example, should it require the ability to read LCD display RAM? That would make the code smaller and eliminate the need for a shadow RAM in the library but not all implementations have that capability. i.e. devices that use shift registers can't do reads and for pin implementations, users may not have a spare pin to control the r/w pin and some i2c based hd44780 type displays don't have the ability to read from the device. It could also be done using internal LCD memory offets to "scroll" the display without having to re-write any of the display. However, MANY arduino users are using home() to set the the cursor position to 0,0 but the current implementation of home() in the libraries uses a hd44780 command that also undoes some other internal hd44780 settings. That could be changed, but then it may break other existing code that works because of the way the home() works today.

Also there has be a way to enable/disable this capability since it can and will break other s/w written to use the existing hd44780 modes like, right to left mode, custom font characters, or horizontal panning.

There are a few libraries (2 that I know of) that did add support for this type of "terminal mode". I've used & tested both, and both have some issues and some things broke (didn’t' work correctly) with some of my test code.

Like I said before, it isn't as easy as one would think to add the s/w to make the hd44780 LCD work like mini terminal, especially if you want it to "just work" correctly across many devices and at the same time not break other existing code that uses other hd44780 capabilities or that is very resource limited/constrained.

At some point I'll be adding support for a "terminal mode" capability to my hd44780 library, which means it will exist on top of many different communication interfaces like pins, shift registers, i2c, etc... and will work for all the geometries, but I haven't yet figured out how to best to do that. I may do it with a wrapper class so that users that don't want/need the capability or don't have the extra room in their parts for it, don't have it consuming any resources in their build. A wrapper class implementation also has the potential to work on any existing library vs just with my hd44780 library. But even a wrapper class comes with some issues as it can potentially break other libraries that use wrapper classes like PrintEx to seamlessly extend Print class libraries like LiquidCrystal type libraries to add printf() support.

It is a difficult problem to solve so that it creates a "it just works" type of solution given all the devices and environments involved.

--- bill

You guys have been very gracious in taking the time to explain all this and hopefully the next person who asks you can point them to this thread. Very informative and more than enough information to satisfy even me! I am not a programmer but it has been a thorn in my side all these years to not have taken that head on. Now with my sincere interest in the Arduino platform, I very well may correct that!

I guess I was hoping that since you have to declare "20x4" in the code, it would be something that worked IF 20x4 then reroute the 3rd line to the second.... Since apparently it is not that easy, I will leave this one for hoping someday these small things get addressed. It is probably not that big of a deal in the scheme of things. I will be perusing your posts and checking out some of those links as I learn more about the LCD option, its limitations, and its successes. Thank You sincerely for taking the time to explain this in such detail!

Deve devestechnet.com

The main complexity in implementing something like this isn’t doing it for any single configuration.
The challenge is to make it work in a generic way that works for all or nearly all the possible configurations. That is what makes a “it just works” solution that is easy to use.
That is the direction that I’m going. I want users to be able to have the same functionality regardless of not only the geometry, but of the interface used to communicate with the LCD.
So it works on 8x2, 16x1 (both versions), 16x2, 20x4 (not sure I want to go down the path for 40x4) and it works with direct pins, i2c, shift registers or whatever other interface might be used.

In terms of the “IF 20x4 then reroute the 3rd line to the second”, that isn’t how this stuff works.
You may want to look over the h/w addressing stuff that Don linked to or have a look at a hd44780 datasheet.
The chips used in these displays are really dumb and don’t have any knowledge of lines or line boundaries.

In order to do what everyone wants (emulate a terminal), the library code has do all the work to track the cursor position and to check if the character being written is about go past the end of a line for the configured geometry.
If it does, the library also has to wrap the cursor position down to the memory location for next line/row and if on the bottom, scroll all the characters on the display. Scrolling the display characters means either having the ability to read the LCD RAM (which isn’t always possible) or creating and managing a mirror of the display in local RAM - which consumes resources.
Currently there aren’t very many libraries (only 2 that I know of) that do any of that.
The library would also have to examine every single character to see if they are or characters and act accordingly (line wrap and scroll when necessary).
Complicating matters and are character codes that can be used for custom characters vs line processing.
There are also issues about how to handle updating the display when writing to the very last position of the very last line as you don’t want to scroll until the next character is written (many implementations of this kind of stuff don’t handle it this way). If you don’t, people get upset that they can’t fully fill the display.

And then a bunch of this wrapping logic gets reversed and/or changes if doing right to left character drawing mode.

While writing all the code to handle all of this isn’t that difficult, and I have done full line processing code for a GLCD library which is much more complex than a hd44780 display, handling end of line processing isn’t’ as easy at it would seem to be given all the little details involved to make it really work and make it work on a large variety of displays geometries, and physical interfaces.

— bill