Customizable TextLCD

26 May 2009 . Edited: 26 May 2009

Hi,

I've got a few changes to the TextLCD library that could make supporting other LCDs a little bit easier.  Following is diff against current head:

 

Index: TextLCD.cpp
===================================================================
--- TextLCD.cpp    (revision 290)
+++ TextLCD.cpp    (working copy)
@@ -36,18 +36,11 @@
* _rw is kept 0 (write) apart from actions that uyse it differently
* _rs is set by the data/command writes
*/
+
+TextLCD::TextLCD(int rs, int rw, int e, int d0, int d1, int d2, int d3) :
+        _row(0), _column(0),
+        _rw(rw), _rs(rs), _e(e), _d(d0, d1, d2, d3) {

-TextLCD::TextLCD(int rs, int rw, int e, int d0, int d1, int d2, int d3) : _rw(rw), _rs(rs), _e(e), _d(d0, d1, d2, d3) {
-
-    _rows = 2;
-    _columns = 16;
-    // Mon, 27 Apr 2009 23:32:34 +0200
-    // Kevin Konradt:
-    // When using a LCD with 1 row x 16 characters
-    // instead of 2x16, try changing _columns to 8.
-    // (display seems to split the 16 characters into
-    // 2 virtual rows with 8 characters each.)
-
_rw = 0;
_e  = 1;
_rs = 0; // command mode
@@ -87,21 +80,21 @@
void TextLCD::newline() {
_column = 0;
_row++;
-    if(_row >= _rows) {
+    if(_row >= rows()) {
_row = 0;
}
locate(_column, _row);
}

void TextLCD::locate(int column, int row) {
-    if(column < 0 || column >= _columns || row < 0 || row >= _rows) {
-        ERROR("locate(%d,%d) out of range on %dx%d display", column, row, _columns, _rows);
+    if(column < 0 || column >= columns() || row < 0 || row >= rows()) {
+        ERROR("locate(%d,%d) out of range on %dx%d display", column, row, columns(), rows());
return;
}

_row = row;
_column = column;
-      int address = 0x80 + (_row * 40) + _column; // memory starts at 0x80, and is 40 chars long per row
+      int address = baseAddress() + (_row * bytesPerRow()) + _column;
writeCommand(address);           
}

@@ -141,7 +134,7 @@
_rs = 1;
writeByte(data);
_column++;
-    if(_column >= _columns) {
+    if(_column >= columns()) {
newline();
}
}
Index: TextLCD.h
===================================================================
--- TextLCD.h    (revision 290)
+++ TextLCD.h    (working copy)
@@ -16,7 +16,7 @@
public:

TextLCD(int rs, int rw, int e, int d0, int d1, int d2, int d3);
-           
+
virtual void locate(int column, int row);
virtual void cls();   
virtual void reset();
@@ -32,8 +32,20 @@
virtual int _getc();
virtual void newline();               

-    int _rows;
-    int _columns;
+    // Mon, 27 Apr 2009 23:32:34 +0200
+    // Kevin Konradt:
+    // When using a LCD with 1 row x 16 characters
+    // instead of 2x16, try changing columns() to 8.
+    // (display seems to split the 16 characters into
+    // 2 virtual rows with 8 characters each.)
+
+    // The folloing defaults are good for the AC162B LCD
+    // Module, but may need adjusting for others...
+    virtual int rows() const { return 2; }
+    virtual int columns() const { return 16; }
+    virtual int baseAddress() const { return 0x80; }
+    virtual int bytesPerRow() const { return 40; }
+   
int _row;
int _column;   
DigitalOut _rw, _rs, _e;

I believe the default behaviour for the library is unchanged.  ie. Should still work with the LCD it was designed for with no changes to code using the library. After this patch, TextLCD could be used with a DEM16217 as follows, and locate() will now select column on the 2nd row perfectly. :-)

 

class TextLCD_DEM16217 : public TextLCD {
public:
	TextLCD_DEM16217(int rs, int rw, int e, int d0, int d1, int d2, int d3) : TextLCD(rs, rw, e, d0, d1, d2, d3) {}
protected:
	virtual int bytesPerRow() const { return 0x40; }
};

TextLCD_DEM16217 lcd(24, 25, 26, 27, 28, 29, 30);

 

Would there be any interest in adding these changes to the library?  Thanks.

Regards,

Bhaveet

26 May 2009

Hi, 

Great idea! Perhaps fork it in to an experimental TextLCD branch? I suspect we can make this work with a whole bunch of text lcds which would be excellent. 

Simon

 

28 May 2009

Hi,

Will try creating fork and checking in over weekend.  Thanks.

Regards,

Bhaveet

31 May 2009

Created the CustomizableTextLCD library at: http://mbed.co.uk/projects/cookbook/svn/CustomizableTextLCD/trunk

The sources were svn copy'ed from TextLCD, so history is preserved and should be possible to merge changes between them if necessary.  Wasn't sure whether to create the branch within TextLCD (e.g. TextLCD/branches/customizable maybe - what are your rules/guidelines on this?) or as a separate library...  Figured this would be the least controversial, but I expect it will be easy to move the code into a different place if we wish.  :-)

I'll expand the above example into a more complete program and stick it into an examples directory at some point.  Otherwise, have fun...