Hello,
when I connected a 16x4 LCD display, I noticed that the position of the cursor with setCursor is not correct on line 2 and 3. When I call setCursor(0, 2), the position is at column 4, not 0.
I found out how this problem can be fixed easily. The lcd.begin function has a parameter for the cols, but it is never used. Although this information is necessary for a correct addressing of the screen. I changed the files as follows and it worked fine with my display. It should also work with a 20-column display, because it does the same as the previous version.
In LiquidCrystal.h, add a private variable _numcols (last lines in the file):
uint8_t _numlines,_numcols,_currline;
In LiquidCrystal.cpp, I made the following changes:
void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
if (lines > 1) {
_displayfunction |= LCD_2LINE;
}
_numlines = lines;
_numcols = cols; // this is new
Last thing: I changed setCursor:
void LiquidCrystal::setCursor(uint8_t col, uint8_t row)
{
int row_offsets[] = { 0x00, 0x40 };
if ( row >= _numlines ) {
row = _numlines-1; // we count rows starting w/0
}
if ( col >= _numcols ) {
row = _numcols-1; // we count cols starting w/0
}
command(LCD_SETDDRAMADDR | (col + row_offsets[row % 2]+_numcols * (row / 2)));
}
Explanation: the offset for line 0 and 1 is always (?) 0x40, and the offset for line 2 and 3 seems as if it depends to the columns. Line 2 is handled as an extension to line 0, and line 3 as an extension to line 1. You notice that when you scroll the content of the display; the characters of line 0 and 1 move to line 2 and 3. Line 0 and 1 always have an offset of 0x00 and 0x40, and line 2 and 3 have an offset of 0x00+_numcols and 0x40+_numcols.
I would suggest to change the official code, so it will work without changing the library for 2x16, 4x16 (tested by me), and all other previous displays with 20 colums. All you have to do is to pass the correct number of colums to lcd.begin, e.g. lcd.begin(16, 2) in my case.
Best regards, Kosmas