LCD row/column limits management

Hi,

In one of my programs, I have to calculate the position (line and column) where a character is displayed.

I use a LCD with (for ex) 2 lines and 24 characters.

So the line can be 0 or 1, and the column can be 1 to 24.

I need to know if every LCD library (I2C) automatically manages the limits.

I mean, if my program increases the line number over 1 and reaches 2, does the library automatically changes 2 in line 0, or do the program will crash and consequently I have to perform a test similar to:

if line >1 then line = 0;

Thank you,

More likely 0 to 23

My advice would be not to rely on a library doing what you suggest unless you have examined the library code and tested it

Having said that, I would be surprised if any LCD library did what you suggest

1 Like

My LCD library does check the column and row when sending bytes for performance.
(a byte not sent is fastest)

However the library does not wrap line 2 (or 4) to line 0.
Would create a mess imho.

No. On a 20x4, if your lcd.print(0); 200 times, you would see printing on the first line, and eventually on the third line. I think at "41" you start to see printing on the "next" row.

I like ising row * colsPerRow + col for cursor placement.

20x4 LCD displays line wrap line 0 > line 2 > line 1 > line 3. There is at least one library (hd44780 by Bill Perry) that can adjust that to line 0 > line 1 > line 2 > line 3, but the majority do not.

1 Like

20x4 LCD displays line wrap line 0 > line 2 > line 1 > line 3. There is at least one library (hd44780 by Bill Perry) that can adjust that to line 0 > line 1 > line 2 > line 3, but the majority do not.

Sorry but I do not clearly understand what you mean… do you mean that with other libraries than hd44780, such as LiquidCrystal_I2C for ex, the program crashes if the line number gets the value 5 ?

Do you mean that with the hd44780 library, the line number automatically takes the value 0, if the program tries to increment the value from 4 ?

Thank you

It does not crash, it writes out-of-bounds... this could cause a crash... but usually you just don't see the printing until your matrix writes "in-bounds" of the screen.

OK I understand.

So contrarily, if I use hd44780, I do not have to care about the “row value” and “line value”: let’s say that if my program increases the row value up to 5, the library will automatically consider that it is a 1.

Am I right ?

You say in your first post

How will you do this if the library automatically adjust the positions for you to enable the text to be printed within the screen limits ?

The problem with trying to print what's nominally outside the display boundaries is that you have to decide where to print it. If it's past the end of a line, do you go to the next line, or do you go back and overwrite the beginning of the current line, or do you scroll the whole line to the left to make room?

I don't know what the libraries do, but it seems your code should make those decisions. Actually, the best solution is probably not to print anything at all that falls outside the display boundaries. I think that's what I would want a library to do.

Unknown, but probably not.

I sadly believe the same, and we will know only by testing in real conditions.

The problem is that I may have to manage by the software the image of what the LCD should display, if this does not work…

I will test it in a few days and come back here if necessary.

Thank you very much

No, if you write to line 0 on a 20x4 LCD with text that is longer than the 20-character line, the 21st character will be on line 2, skipping over line 1.

I truly have no idea how any library handles a line number beyond the limits of the display, it is pretty much assumed that positioning on the display is the responsibility of your code.

1 Like

You can test code on Woki.com

#include <LiquidCrystal_I2C.h>
#define I2C_ADDR    0x27
#define LCD_COLUMNS 20
#define LCD_LINES   4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("12345....10...15...20...25...30...35...ab");
}

void loop() {
}

First line will be "12345....10...15...2"
Second line will be"b"
Third line will be "0...25...30...35...a"

If I were you I would not even bother to test the library but would go straight to having the sketch control the positioning directly.

Doing it that way you will know exactly where each character is being printed

when you already do a tracking of lines, add that if and jump between the lines.

use...

for cursor placement.

@grizzli06 maybe if you told us a bit more about why are you doing the location tracking calculations and why you might be attempting to write beyond the bounds of LCD geometry, we could offer some solutions.

There are several things related to attempting to tell the library to use out bounds cursor positions.
From what I’ve seen (and I’ve looked at pretty much all the arduino LiquidCrystal/hd44780 LCD libraries out there) none of them will crash when you provide out of bounds parameters to functions like setCursor() , but they likely can create unexpected results.
What they tend to do is if the setCursor() row parameter is larger than the maximum value, they set silently the parameter to the maximum value but don’t check for the column parameter. So if the column parameter is beyond the display geometry, it will create a DDRAM address that may produce unexpected results.

But lets take a step back.
The hd44780 is a simple chipset. There is a block of memory inside the chips and that memory is mapped to the display where 1 byte is 1 character on the display.
That said how that mapping is done is different depending on the LCD geometry.
And the memory for each row is not linear. i.e. memory storage for what you see as row 1 on the LCD display is not directly after row 0 on the LCD display.

Where this creates issues is that the LiquidCrystal API does not map directly to the LCD instruction set. i.e. the actual hd44780 chipset LCD instruction set are not based on col/row but rather display memory locations. 0 to 80

What this all means is that “funny” things can happen when you attempt to write beyond the visible LCD display boundaries.
This is because if you write beyond the visible column, the write will write the character to display memory, you just can’t see it.
There are valid reasons to do this, but I won’t get into that.

The “hd44780” library has a special linewrap mode that can be enabled through the API.
When linewrap is enabled, library will take into consideration the LCD geometry and LCD display memory to LCD display mapping to make things easier for the user.
i.e. when linewrap mode is enabled, if the user writes beyond the end of a row, the character will automatically show up on the next row and the row/col is adjusted accordingly.
Write beyond the end of the bottom row and the text will show up on the top row (row 0).
In linewrap mode, It makes output to the LCD work kind of like TTY terminal. As you write to it, the characters advance then wrap to the line below, and if on the lowest line, it wraps up to the top line.
The hd44780 library setCursor() behaves differently in linewrap mode.
In regular mode, the hd44780 behaves as pretty much all other LiquidCrystal API type libraries. If the row is too large, it gets set to the maximum row, and it blindly accepts the col parameter which will likely not do what most people would expect given the resulting DDRAM address.
In linewrap mode, the hd44780 library still truncates the row parameter to ensure it isn’t too large, but for column, it ripples the math through the the rows to make it land where the cursor would be if you printed that many character.
example, on a 4x20 display. if you set the cursor position to (0,30) the position is set to 1,10

The hd44780 github page and wiki documents this API capability and
the hd44780 library comes with an example for each i/o class that demonstrates the linewrap capability.

– bill

1 Like