Papirrruqui:
What happens is, I’m writing only in the first row (row number 0) and, as soon as the autoscroll() function is called, everything goes right in the first line, but at the same time a ghost lines appears on the 3tr line (row 2), doing the same thing that happens in the first line.
I have another screen (LCD 1602), and everything works fine but the screen only has two lines and the ghost characters does not appears.
While you have not shown this in your photos, I assume that by "ghost lines" you mean that the same characters show up on line 2 that are showing up on line 0.
What you are seeing is the correct behavior on a 20x4 display given how the hd44780 chip set display memory works and the code you have written.
It obviously doesn't work the way you think it does.
In your example code, you are not getting "ghosts", you are seeing what you previous printed on line 0 show up on line 2 of the display as the display memory is shifted.
It isn't obvious since you printed the same 10 digits twice. Print something different each time and you will see what is really happening.
Had you printed enough characters, you would have also seen a similar effect on the 16x2 display as well.
i.e. the "duplication" was still happening on the 16x2 from the shifting, you just were not seeing it because the screen isn't showing all the internal display ram. print enough and the characters will start to spill over into the visible portion of the display memory.
You need to understand a bit more about how the hd44780 display works and what autoscroll() does and doesn't do.
First, the hd44780 chipset memory layout is hard coded internally.
It can be configured internally to be two 40 character lines or one 80 character line.
This is fixed and cannot be changed. ALL hd44780 displays work this way.
When the physical display is not two 40 character lines or one 80 character line, the physical LCD displays only a portion of the internal lines.
See this for more on how the internal memory is mapped to the physical display of the LCD for various geometries:
The LiquidCrystal API function autoscroll() turns on the S bit of the Entry Mode Set instruction.
From the data sheet:
S: Shifts the entire display either to the right (I/D = 0) or to the left (I/D = 1) when S is 1.
The display doesnot shift if S is 0.If S is 1, it will seem as if the cursor does not move but the display does.
The display does not shift when reading from DDRAM. Also, writing into or reading out from CGRAM does not shift the display.
What you need to understand is that whenever a shift is done, what is really happening is that the entire display of what is shown is shifted. Not just an individual line/row.
The physical LCD displays what is in display ram. it is like a window into that memory.
Normally display memory location 0 is the upper left corner of the physical display.
If you do a shift, the physical display will start showing characters at a different location as the starting point is shifted.
This will cause ALL the characters on the physical to shift.
Where this can look odd is on a 20x4 display since it shows all the display and given how the display memory is mapped to the physical display since line 2 on the physical display is contiguous with line 0 and line 3 is contiguous with line 1.
Many people assume that the 20x4 memory is mapped linearly from upper left to bottom right of the display.
i.e. if you start on line 0 and print characters then when the characters get to the end of line 0 that they will start printing on line 1.
But this is not the case. If you overrun line 0 it will start printing on line 2.
After line 2 it will go back to line 1 and after line 1 it will go to line 3.
Because of all the display mapping, things can get confusing when doing shifts, particularly on a 20x4 display.
BTW, your code is also attempting to address an invalid column on the display:
// Set the cursor to the last column of the demo row and turn on autoscroll
lcd.setCursor(lcdCols, lcdScrollRow);
While your comment suggests setting to the last column on the row, lcdCols is 20 which is beyond the end of the row.
The library that you are using does not check to see if you are attempting to go beyond the end of the last column.
With that library attempting to set the cursor position to 20,0 on the 20x4 display will be addressing LCD display memory location 20
Display memory location 20 maps to beginning of line 2 on the physical Display.
When combined with auto shift, things can get quite confusing.
Here is you code modified so you can better see the actual effects of the shifting:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD address and geometry and library initialization
/*
const byte lcdAddr = 0x27; // Address of I2C backpack
const byte lcdCols = 16; // Number of character in a row
const byte lcdRows = 2; // Number of lines
*/
const byte lcdAddr = 0x27; // Address of I2C backpack
const byte lcdCols = 20; // Number of character in a row
const byte lcdRows = 4; // Number of lines
LiquidCrystal_I2C lcd(lcdAddr, lcdCols, lcdRows);
// Demo parameters
const byte lcdScrollRow = 0; // Number of a demo row counting from 0
const unsigned int digitDelay = 500; // Miliseconds before displaying next digit
// Function for displaying demo digits
void printDigits() {
for (byte thisChar = 0; thisChar < 10; thisChar++) {
lcd.print(thisChar);
delay(digitDelay);
}
}
// Function for displaying demo chars
void printChars()
{
char thisChar = 'A';
for (int i = 0; i < 10; i++)
{
lcd.print((char) (thisChar+i));
delay(digitDelay);
}
}
void setup() {
lcd.init();
lcd.backlight();
}
void loop() {
lcd.setCursor(0, lcdScrollRow);
printChars();
// Set the cursor to the last column of the demo row and turn on autoscroll
lcd.setCursor(lcdCols, lcdScrollRow);
lcd.autoscroll();
printDigits();
lcd.noAutoscroll();
lcd.clear();
}
The shift mode capabilities on the hd44780 chipset are not very useful on multi line displays.
It tends to work ok on single line displays. It can be used on 2 line displays for some situations if you don't shift too much and are ok with shifting both lines at the same time.
It is all but useless on a 20x4 display since all display memory is shown and since any shift causes all lines to shift around and it can look really odd given the display memory to physical screen mapping is not linearly contiguous.
First, take a step back and consider what you want to do in terms of shifting.
In many cases it is not possible to use the hd44780 chipset shifting capabilities given the way it works.
And I would still suggest that you consider switching to the hd44780 library.
Not only is it simpler to configure, faster and have some added capabilities.
But it also is actively being maintained which is currently not the case for the LiquidCrystal_I2C library.
The hd44780 library has a long line wrapping capability that can be be enabled that can straighten out some of the memory mapping issues like when printing long lines so that wrapping works correctly on line boundaries.
The library you are using nor the LiquidCrystal library have this capability.
--- bill