From 138bcb17c39aa662166a74abab76e9a9023d416e 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. --- src/LiquidCrystal.cpp | 15 ++++++++++++--- src/LiquidCrystal.h | 2 ++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/LiquidCrystal.cpp b/src/LiquidCrystal.cpp index 0653487..5dbb830 100644 --- a/src/LiquidCrystal.cpp +++ b/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/src/LiquidCrystal.h b/src/LiquidCrystal.h index 24ec5af..1c0fa4f 100644 --- a/src/LiquidCrystal.h +++ b/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 cb0c50909fcfaa39a1830d3c8f6c662cfaf22bf1 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. --- src/LiquidCrystal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LiquidCrystal.h b/src/LiquidCrystal.h index 1c0fa4f..684a65f 100644 --- a/src/LiquidCrystal.h +++ b/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 beed8515f711ccb541642ac1f6e2f7ef4393f67b 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. --- src/LiquidCrystal.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/LiquidCrystal.cpp b/src/LiquidCrystal.cpp index 5dbb830..27b5377 100644 --- a/src/LiquidCrystal.cpp +++ b/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 596e305a4d115ee53132e99ac3d9a07ab752f837 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 --- src/LiquidCrystal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LiquidCrystal.cpp b/src/LiquidCrystal.cpp index 27b5377..5825945 100644 --- a/src/LiquidCrystal.cpp +++ b/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 c2a0d844b605bad78fa032aa1bd2f3c635ed232a 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 --- src/LiquidCrystal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LiquidCrystal.cpp b/src/LiquidCrystal.cpp index 5825945..9579c01 100644 --- a/src/LiquidCrystal.cpp +++ b/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 dbb718a53e767737815616ab682b62794b40febb 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 --- src/LiquidCrystal.cpp | 1 - src/LiquidCrystal.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/LiquidCrystal.cpp b/src/LiquidCrystal.cpp index 9579c01..58120e8 100644 --- a/src/LiquidCrystal.cpp +++ b/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/src/LiquidCrystal.h b/src/LiquidCrystal.h index 684a65f..da950ce 100644 --- a/src/LiquidCrystal.h +++ b/src/LiquidCrystal.h @@ -101,7 +101,7 @@ private: uint8_t _initialized; - uint8_t _numlines,_currline; + uint8_t _numlines; uint8_t _row_offsets[4]; };