From 03a6b2c54a2547e9012376a3c2e1d8cb090b081b Mon Sep 17 00:00:00 2001 From: Mark Sproul Date: Sun, 4 Dec 2011 16:54:32 -0500 Subject: [PATCH 1/6] Added setRowOffsets to LiquidCrystal library Original commit by Mark Sproul, but cleaned up by Matthijs Kooijman. --- libraries/LiquidCrystal/src/LiquidCrystal.cpp | 15 ++++++++++++--- libraries/LiquidCrystal/src/LiquidCrystal.h | 2 ++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/libraries/LiquidCrystal/src/LiquidCrystal.cpp b/libraries/LiquidCrystal/src/LiquidCrystal.cpp index 0653487d7..5dbb830f9 100644 --- a/libraries/LiquidCrystal/src/LiquidCrystal.cpp +++ b/libraries/LiquidCrystal/src/LiquidCrystal.cpp @@ -79,6 +79,8 @@ void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t en else _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; + setRowOffsets(0x00, 0x40, 0x14, 0x54); + begin(16, 1); } @@ -157,6 +159,14 @@ void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { } +void LiquidCrystal::setRowOffsets(int row0, int row1, int row2, int row3) +{ + _row_offsets[0] = row0; + _row_offsets[1] = row1; + _row_offsets[2] = row2; + _row_offsets[3] = row3; +} + /********** high level commands, for the user! */ void LiquidCrystal::clear() { @@ -172,12 +182,11 @@ void LiquidCrystal::home() void LiquidCrystal::setCursor(uint8_t col, uint8_t row) { - int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; if ( row >= _numlines ) { - row = _numlines-1; // we count rows starting w/0 + row = _numlines - 1; // we count rows starting w/0 } - command(LCD_SETDDRAMADDR | (col + row_offsets[row])); + command(LCD_SETDDRAMADDR | (col + _row_offsets[row])); } // Turn the display on/off (quickly) diff --git a/libraries/LiquidCrystal/src/LiquidCrystal.h b/libraries/LiquidCrystal/src/LiquidCrystal.h index 24ec5afdf..1c0fa4fb0 100644 --- a/libraries/LiquidCrystal/src/LiquidCrystal.h +++ b/libraries/LiquidCrystal/src/LiquidCrystal.h @@ -77,6 +77,7 @@ public: void autoscroll(); void noAutoscroll(); + void setRowOffsets(int row1, int row2, int row3, int row4); void createChar(uint8_t, uint8_t[]); void setCursor(uint8_t, uint8_t); virtual size_t write(uint8_t); @@ -101,6 +102,7 @@ private: uint8_t _initialized; uint8_t _numlines,_currline; + int _row_offsets[4]; }; #endif From 3fdda81a1ad2b10b924866645d7b7eee2398a122 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Wed, 18 Dec 2013 12:37:01 +0100 Subject: [PATCH 2/6] Make the LiquidCrystal row offsets uint8_t instead of int Since these are memory addresses, there is no need to make them signed. Furthermore, the HD44780 chip supports memory addresses up to 0x67, so uint8_t shouldbe sufficient. --- libraries/LiquidCrystal/src/LiquidCrystal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/LiquidCrystal/src/LiquidCrystal.h b/libraries/LiquidCrystal/src/LiquidCrystal.h index 1c0fa4fb0..684a65f11 100644 --- a/libraries/LiquidCrystal/src/LiquidCrystal.h +++ b/libraries/LiquidCrystal/src/LiquidCrystal.h @@ -102,7 +102,7 @@ private: uint8_t _initialized; uint8_t _numlines,_currline; - int _row_offsets[4]; + uint8_t _row_offsets[4]; }; #endif From 1786716a75c5d029cc7ee43478ff5506a5cfdf85 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Wed, 18 Dec 2013 12:34:44 +0100 Subject: [PATCH 3/6] In LiquidCrystal::setCursor(), check against length of _row_offsets as well Before, the row value was maximized against _numlines already, but the value from _numlines is not limited anywhere, so it could be longer than the length of _row_offsets. This check makes sure the array bounds is never exceeded. --- libraries/LiquidCrystal/src/LiquidCrystal.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/LiquidCrystal/src/LiquidCrystal.cpp b/libraries/LiquidCrystal/src/LiquidCrystal.cpp index 5dbb830f9..27b53772f 100644 --- a/libraries/LiquidCrystal/src/LiquidCrystal.cpp +++ b/libraries/LiquidCrystal/src/LiquidCrystal.cpp @@ -182,6 +182,10 @@ void LiquidCrystal::home() void LiquidCrystal::setCursor(uint8_t col, uint8_t row) { + const size_t max_lines = sizeof(_row_offsets) / sizeof(*_row_offsets); + if ( row >= max_lines ) { + row = max_lines - 1; // we count rows starting w/0 + } if ( row >= _numlines ) { row = _numlines - 1; // we count rows starting w/0 } From 265ac7b59eac643f8ef39990168f0cec2ef510d2 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Wed, 18 Dec 2013 12:54:53 +0100 Subject: [PATCH 4/6] Support more LiquidCrystal displays out of the box Previously, the row offsets were hardcoded to the ones used for 20x4 displays (which woudl also work for all 2-line displays). Now, the number of columns given is used to calculate the offsets most likely to apply. For 2-line displays and 20x4 displays, the (used) offsets are completel unchanged. With this change, common 16x4 displays and (if they even exist) other 4-line and 3-line displays might also work (depending on the hardware configuration used, of course). See this page for some info on common LCD sizes and configurations encountered in practice: http://web.alfredstate.edu/weimandn/lcd/lcd_addressing/lcd_addressing_index.html --- libraries/LiquidCrystal/src/LiquidCrystal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/LiquidCrystal/src/LiquidCrystal.cpp b/libraries/LiquidCrystal/src/LiquidCrystal.cpp index 27b53772f..582594520 100644 --- a/libraries/LiquidCrystal/src/LiquidCrystal.cpp +++ b/libraries/LiquidCrystal/src/LiquidCrystal.cpp @@ -79,8 +79,6 @@ void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t en else _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; - setRowOffsets(0x00, 0x40, 0x14, 0x54); - begin(16, 1); } @@ -91,6 +89,8 @@ void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { _numlines = lines; _currline = 0; + setRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols); + // for some 1 line displays you can select a 10 pixel high font if ((dotsize != 0) && (lines == 1)) { _displayfunction |= LCD_5x10DOTS; From 8c6bcf0c84123abab9e5f87bc1b9e017418c6a7b Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Wed, 18 Dec 2013 13:01:11 +0100 Subject: [PATCH 5/6] In LiquidCrystal::begin(), use a define instead of a hardcoded 0 --- libraries/LiquidCrystal/src/LiquidCrystal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/LiquidCrystal/src/LiquidCrystal.cpp b/libraries/LiquidCrystal/src/LiquidCrystal.cpp index 582594520..9579c0148 100644 --- a/libraries/LiquidCrystal/src/LiquidCrystal.cpp +++ b/libraries/LiquidCrystal/src/LiquidCrystal.cpp @@ -92,7 +92,7 @@ void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { setRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols); // for some 1 line displays you can select a 10 pixel high font - if ((dotsize != 0) && (lines == 1)) { + if ((dotsize != LCD_5x8DOTS) && (lines == 1)) { _displayfunction |= LCD_5x10DOTS; } From 9552db3fe4ce1ceebd4d475636416e907151b352 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Wed, 18 Dec 2013 13:02:05 +0100 Subject: [PATCH 6/6] In LiquidCrystal, remove an unused variable --- libraries/LiquidCrystal/src/LiquidCrystal.cpp | 1 - libraries/LiquidCrystal/src/LiquidCrystal.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/LiquidCrystal/src/LiquidCrystal.cpp b/libraries/LiquidCrystal/src/LiquidCrystal.cpp index 9579c0148..58120e82d 100644 --- a/libraries/LiquidCrystal/src/LiquidCrystal.cpp +++ b/libraries/LiquidCrystal/src/LiquidCrystal.cpp @@ -87,7 +87,6 @@ void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { _displayfunction |= LCD_2LINE; } _numlines = lines; - _currline = 0; setRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols); diff --git a/libraries/LiquidCrystal/src/LiquidCrystal.h b/libraries/LiquidCrystal/src/LiquidCrystal.h index 684a65f11..da950ce58 100644 --- a/libraries/LiquidCrystal/src/LiquidCrystal.h +++ b/libraries/LiquidCrystal/src/LiquidCrystal.h @@ -101,7 +101,7 @@ private: uint8_t _initialized; - uint8_t _numlines,_currline; + uint8_t _numlines; uint8_t _row_offsets[4]; };