Text LCD

A driver code library for Text LCD panels using the 4-bit HD44780 lcd display driver.

/media/uploads/simon/textlcd-helloworld.jpg

Hello World!

» Import this program

00001 // Hello World! for the TextLCD
00002 
00003 #include "mbed.h"
00004 #include "TextLCD.h"
00005 
00006 TextLCD lcd(p15, p16, p17, p18, p19, p20); // rs, e, d4-d7
00007 
00008 int main() {
00009     lcd.printf("Hello World!\n");
00010 }
Pin numberTextLCD pinsmbed pins
1GND0V
2VCC3.3V
3VO0V, via 1k resistor
4RSp15
5RW0V
6Ep16
7D0not connected
8D1not connected
9D2not connected
10D3not connected
11D4p17
12D5p18
13D6p19
14D7p20

Warning

The contrast VO pin seems to have different behaviour on different displays, so you may need to experiment for your display to see anything. I think I've seen some work tied to 0V, some to 3.3V, or with a different resistor.

Adjustable contrast can be achieved with a 10k trim-pot in a voltage divider configuration: one side to Vcc, other side to GND, wiper to VO. Adjust until you see a line of solid squares, then back off until they just disappear.

Some displays need a negative voltage at VO. One side of the trimpot is connected to the negative voltage instead of GND in that case. F.i. a Maxim MAX1044 can be used to generate the negative voltage.

Text LCD Library

» Import this library into a program

Public Types

enum   LCDType { LCD16x2 , LCD16x2B , LCD20x2 , LCD20x4 }
 

LCD panel format.

More...

Public Member Functions

  TextLCD (PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7, LCDType type=LCD16x2)
  Create a TextLCD interface.
int  putc (int c)
  Write a character to the LCD.
int  printf (const char *format,...)
  Write a formated string to the LCD.
void  locate (int column, int row)
  Locate to a screen column and row.
void  cls ()
  Clear the screen and locate to 0,0.

Different LCD Panel Sizes

Setting the type field in the TextLCD constructor allows configuration for the different display panel sizes:

TextLCD::LCD16x2     16x2 LCD panel (default) 
TextLCD::LCD16x2B    16x2 LCD panel alternate addressing 
TextLCD::LCD20x2     20x2 LCD panel 
TextLCD::LCD20x4     20x4 LCD panel 

Note: There is now also support for

TextLCD::LCD8x1    8x1 LCD panel
TextLCD::LCD8x2    8x2 LCD panel
TextLCD::LCD16x1  16x1 LCD panel
TextLCD::LCD16x4  16x4 LCD panel
TextLCD::LCD24x2  24x2 LCD panel
TextLCD::LCD24x4  24x4 LCD panel (for KS0078 controller)
TextLCD::LCD40x2  40x2 LCD panel
TextLCD::LCD40x4  40x4 LCD panel (two controllers)

You can find the new lib here

For example:

#include "mbed.h"
#include "TextLCD.h"

TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD20x4); // rs, e, d4-d7

int main() {
    lcd.printf("Hello World!\n");
}

Enhanced Version of Text LCD

An enhanced forked version of the original Text LCD is here

Reference

The underlying HD44780 chip is a driver used in many LCD character displays. It might sometimes be referred to as Hitachi HD44780U. There are also several compatible clones of this chip in use (eg Samsung KS0066).




2 related questions:


48 comments:

12 Sep 2010

Photo shows different mbed pins hooked to LCD than example code and wiring table. Use wiring table!

12 Sep 2010

Here is another code example using other LCD functions (clear screen and locate) and a timer to display elapsed time:

  1. include "mbed.h"
  2. include "TextLCD.h"

TextLCD lcd(p10, p12, p15, p16, p29, p30); rs, e, d0-d3 Timer t;

int main() { Start timer t.start(); Clear LCD Screen lcd.cls(); wait(1); Print to LCD on first line lcd.printf("Hello LCD World!\n"); while (1) { Move cursor to start of second display line lcd.locate(0,1); Print elapsed time from timer on LCD lcd.printf("%e sec", t.read()); wait(.2); } }

12 Sep 2010

Sorry about the mess in last comment - looked OK in edit window. Preview does not seem to work right in my browser

#include "mbed.h"
#include "TextLCD.h"

TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d0-d3
Timer t;

int main() {
// Start timer
    t.start();
// Clear LCD Screen
    lcd.cls();
    wait(1);
// Print to LCD on first line
    lcd.printf("Hello LCD World!\n");
    while (1) {
// Move cursor to start of second display line
        lcd.locate(0,1);
// Print elapsed time from timer on LCD
        lcd.printf("%e sec", t.read());
        wait(.2);
    }
}
17 Sep 2010

It is also possible to download eight custom character designs to the HD44780 LCD controller chip. There are numerous articles on the web and even web applications to draw characters and generate the character data. One such character design application is http://www.quinapalus.com/hd44780udg.html. The data sheet describes the download process to define new characters.

Update: Here is some mbed code to load new characters: http://mbed.org/users/DimiterK/notebook/custom-characters-on-hd44780/

22 Sep 2010

Just wondering if there's any reason that the specific pins used in the wiring diagram example are used? Can any pins be used for any of the lines. E.g. just use pins 15 to 20 for example?

27 Sep 2010

Having problems with an LCD? Notes from my first time use with a 16x2 unit.

My LCD needs 5V supply (Mbed pin 39)others might be 3.3V The LED backlight needs no current limiting resistor when run from the rated voltage. The contrast potentiometer resistor is required. The SIL connector type of display mates with a breadboard well. The DIL type needs an adapter or cable. The SIL connector pin numbering is weird. 14,13,12,11,10,9,8,7,6,5,4,3,2,1,16,15 (L to R display side) The connections used by this software are E,RS,D4,D6,D7 with R/-W permanently connected to VSS. Where the LCD software documentation mentions signal D0 it really connects to LCD pin D4, D1->D5,D2->D6 and D3->D7 Diagnostic check: If you have power connected correctly to the LCD and a Contrast pot set at one of the extremes, The LCD should show a display of 7 x 5 pixel blocks on the first line. If you don't get this the software cannot display anything.

02 Oct 2010

I had tuff time to make this working as I connected 3.3V vcc later I realized it needs to be +5 V dc (pin 39) !!!!!

04 Oct 2010

Some LCDs are 3.3V and some are 5V. The older ones tend to be 5V. The datasheet for the exact LCD module can be hard to find if you have an old one. If you buy a new one, they typically have the info on the power supply needed available in the data provided at the website. They all have the same controller chip and you can find that datasheet, but it can be 3.3V or 5V. If you hook up a 5V module to 3.3V, the LCD display will just be blank. And if you hook up the backlight - some need the resistor!

05 Oct 2010

Having great problems with this.

I have compiled and run the code, rewired and replaced both the MBED and my LCD controller.

For some reason am unable to get any Hello World appearing and I really do not even know what to try anymore.

Any suggestions would be great.

Thanks!

05 Oct 2010

So. Apparently my pot for contrast was bad. Make sure you check that!! The code does work.

07 Oct 2010

Is it possible to run a 40x4 LCD with the TextLCD.h? I don't see it mentioned. Thanks.

25 Oct 2010

I just uploaded a modified version of the TextLCD library to be able to support ST7036 based displays (like, for example, the DOGM162x-A). I know that a better solution would be to merge this into the original library, but haven't got the time to do this right now.

Please do a search for ST7036 or see http://mbed.org/users/leliep/libraries/TextLCD_ST7036/lgsmve

28 Oct 2010

user Oliver Ryan wrote:

Is it possible to run a 40x4 LCD with the TextLCD.h? I don't see it mentioned. Thanks.

a 40x4 is infact a dual 40x2 display it contains two enable lines: E1 and E2. the datasheet of eg. the everboquet MC4004A is on this page: http://www.farnell.com/datasheets/302399.pdf. You have to adapt the progamm code! I'm using this display and i'm adapting the code. When its finished i will post it!

17 Nov 2010

Hello,

i'm trying to make reading back from the display work, but am having a hard time figuring this out, i know how it works, and doing it manually(manual enable after putting whole display full with text and then putting it in read mode) does work, but when i try to let the mBed doe it, it doesn't work. anyone has any idea?

19 Nov 2010

user Jelmer Bruggink wrote:

i'm trying to make reading back from the display work, but am having a hard time figuring this out, i know how it works, and doing it manually(manual enable after putting whole display full with text and then putting it in read mode) does work, but when i try to let the mBed doe it, it doesn't work.

Perhaps you should tell what you have done so far. People might be able to help you easier that way.

22 Nov 2010

i've got a Optrex LCD (DMC20481 NY-LY-ABE) with a different timing. The enable puls has to be at least 75us instead of 40us and the clear screen command takes 3ms instead of 1.64ms. So i alter the TextLCD libary files on those points into a new OptrexLCD libary. I shall post this libary soon.

23 Nov 2010

Your wiring diagram contradicts the comments in your code!

23 Nov 2010

Thanks! Fixed.

23 Nov 2010

Hi Simon,

I am using this TextLCD library for an LCD20x4 type : the AV2040 of ANAG VISION (found @ Conrad). I have found the following problems and respective solutions that may help for a future release if it's OK for you :

1) the LCDType (enum in line 48 of TextLCD.h) is not used in the "Hello world" example of the Cookbook page : this example works only for the default LCD16x2 type !

2) when using the LCD20x4 type when calling the TextLCD class, a compilation error is : Identifier "LCD20x4" is undefined (E20).

3) consequently, I have modified the default LCDType = LCD20x4 in the TextLCD.h file only (nothing in the TextLCD.ccp file)

The code is : TextLCD lcd(p24, p26, p27, p28, p29, p30); /* rs,e,d0,d1,d2,d3,20 char's x 4 lines */

and the compilation is now OK and my LCD works very properly (I have written an interrupt driven frequencemeter with a fast partial LCD update which never failed).

I have not yet understood why the enum LCDType is "undefined". If this is fixed, I will use finally your library without change.

Thanks in advance !

23 Nov 2010

user Dominique Bultez wrote:

I am using this TextLCD library for an LCD20x4 type : the AV2040 of ANAG VISION (found @ Conrad). I have found the following problems and respective solutions that may help for a future release if it's OK for you : 1) the LCDType (enum in line 48 of TextLCD.h) is not used in the "Hello world" example of the Cookbook page : this example works only for the default LCD16x2 type ! 2) when using the LCD20x4 type when calling the TextLCD class, a compilation error is : Identifier "LCD20x4" is undefined (E20).

You should use the identifier as follows:

TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD20x4); rs, e, d0-d3

This works excellent for me.

23 Nov 2010

Thanks a lot : Now this works excellent also for me with your original library !

05 Dec 2010

The writeByte routine can be speeded up by about a factor of 4 just by knowing that while commands take about 40usec, 'tickling the enable pin' can be done in 1/2 usec, so:

void TextLCD::writeByte(int value) {

wait(0.000040f); most instructions take 40us

_d = value >> 4;

wait_us(1);

_e = 0;

wait_us(1);

_e = 1;

_d = value >> 0;

wait_us(1);

_e = 0;

wait_us(1);

_e = 1; } works well and much faster.

A simple, but kind of kludgy, way to implement 40x4 support is to make some very simple changes to support a 40x2 display in the code around LCDtype and then to declare the upper two lines with something like:

TextLCD lcdupper(p10, p12, p15, p16, p17, p18, TextLCD::LCD20x4);

and the lower two lines with:

TextLCD lcdlower(p10, p13, p15, p16, p17, p18, TextLCD::LCD20x4); assuming enable2 is on pin 13.

05 Dec 2010

The 16x2B option you 'support' is, I think, a completely mythical device. If you know of an actual source for such a device, please let me know where I can purchase one. It would be something I would add support for in the Arduino LiquidCrystal library if it were real. see

http://web.alfredstate.edu/weimandn/lcd/lcd_addressing/lcd_addressing_index.html

05 Dec 2010

user john raines wrote:

The 16x2B option you 'support' is, I think, a completely mythical device. If you know of an actual source for such a device, please let me know where I can purchase one.

AFAIK this is used for displays using the HD66712 or equivalent chip.

08 Dec 2010

Hello, did anybody try out the 20x4 LCD interfacing with SPI ? If so how does the identifier look like? Thank you Juergen Hausmann

08 Dec 2010

Hello, my 4x20 Display with a KS066 controller was not running with the TextLCD lib. I changed the delays and the init bytes - no change. I then add the RW signal to read from the display to poll the busy flag. It speed up the communication, but I only had access to the first and third line. Then i changed the E signal to be low between two commands. This is shown in the Samsung datasheet for the KS0066u. Bingo the display is working.

I have also add a writeCGRAM function to define user chars 0-7.

http://mbed.org/users/dreschpe/libraries/TextLCD/liznsz

28 Dec 2010

Having trouble compiling with "TextLCD.h" even with the above examples I get the following error message:

" Cannot open source input file "TextLCD.h": No such file or directory (E5)" in file "/main.cpp" "

Can someone point out what I'm missing. Scrpt as entered

#include "mbed.h"
#include "TextLCD.h"

TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD8x2); // rs, e, d4-d7

int main() {
    lcd.printf("Hello!\n");
}
28 Dec 2010

Sorted thanks. Just needed to import it

04 Jan 2011

hi! I have a question, how can I to import this library?

03 Jul 2011

guyz i have a question?

are the connection same for NHD‐0420E2Z‐FL‐YBW ???

07 Jul 2011

Hi Jim. Thanks for posting this. I tried to compile your program, but I couldn't get it to work. At first it said that TextLCD.h was missing. I copied that file from another library, and then it gave me error 289, "types of my input values do not match the types expected in the declaration of my function." I'm new to this stuff, so could you please explain what I need to do? Do I need to modify the header file, or is there something else that needs to be done. Thanks.

user jim hamblen wrote:

Sorry about the mess in last comment - looked OK in edit window. Preview does not seem to work right in my browser

#include "mbed.h"
#include "TextLCD.h"

TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d0-d3
Timer t;

int main() {
// Start timer
    t.start();
// Clear LCD Screen
    lcd.cls();
    wait(1);
// Print to LCD on first line
    lcd.printf("Hello LCD World!\n");
    while (1) {
// Move cursor to start of second display line
        lcd.locate(0,1);
// Print elapsed time from timer on LCD
        lcd.printf("%e sec", t.read());
        wait(.2);
    }
}

07 Jul 2011

user khalil Ahmed wrote:

are the connection same for NHD‐0420E2Z‐FL‐YBW ???

See Spec: <http://www.newhavendisplay.com/specs/NHD-0420E2Z-FL-YBW.pdf>

08 Jul 2011

Eric: try importing my entire demo project using this

» Import this programHelloLCD

Text LCD demo

My guess is that the library files were not imported correctly for your project setup (or perhaps have changed recently). Don't have an LCD with me to try it, but my version still compiles OK. You need to use "Import library" or sometimes "files" to get the library code - Note the gear logo with the library in the compiler left column when you expand the project files.

10 Aug 2011

Hi:

I make use of TextLCD as follow:

#include <mbed.h>
#include <TextLCD.h>

TextLCD lcd(p10, p11, p12, p13, p14, p15, TextLCD::LCD20x2); // RS, EN, D4, D5, D6, D7

int main() {
  lcd.cls();
           // 123456789 123456
  lcd.printf("Hello World n\n");
  lcd.printf("Hello World 2\n");
  wait(3);
  lcd.cls(); // Clear screen, locate(c0, r0)
  lcd.printf("World 1 ");
  lcd.printf("and World 2");
}

When I tried it on a 20x4 LCD (without backlight), it works perfectly. However, if I tried it on a 20X2 LCD (with backlight), it does not work. (BTW, I did change the last parameters in TextLCD contructor). The diagram /media/uploads/yoonghm/lcd.jpg

For the LCD with backlight, the symptoms: a) The backlight LCD is working b) The contrast on the LCD is working as I can vary the resistance on the pot. c) No text appear.

It seems to be that there is a time issue.

Any idea? Thank.

10 Aug 2011

user HM Yoong wrote:

For the LCD with backlight, the symptoms: a) The backlight LCD is working b) The contrast on the LCD is working as I can vary the resistance on the pot. c) No text appear.

Assume you mean, that you can vary the voltage (not only the resistance) with the pot.

Do black squares show up when you turn the pot?

If not, you might have a display, that needs a negative contrast voltage.

What type of display? What controller?

mbed signals are 3.3V. Most 5V displays will function though.

10 Aug 2011

Hi Arwin:

I also varied the resistance for the backlight using a pot but I did not updated the diagram here. So I have pots for contrast and backlight.

I tried both of the LCDs on a PIC18F 3.3V development board, they were working properly too.

Black squares showed up when I turned the pot for the contrast. The controller is HD44780.

03 Sep 2011

With HD44780 or ST7066U controllers ... Pin5 Read\Write enable should be strapped to 0v (pin1) for Write enable ... or you'll just get black squares !

04 Sep 2011

user Lionel Bousfield wrote:

With HD44780 or ST7066U controllers ... Pin5 Read\Write enable should be strapped to 0v (pin1) for Write enable ... or you'll just get black squares !

Warning!

With READ/nWRITE high you will have an IO conflict as the LCD is in 'output' mode (read) and your mbed is sending data also (output) this can damage the IO ports of the mbed and/or display.

26 Sep 2011

To HM Yoong (post dd 10 Aug): try to disconnect D0..3 from ground. Just leave the pins not connected to anything. I had the same problem and this worked for me.

14 Oct 2011

For everyone want to show cursor on LCD Display, you may add followings statement on your files.

All Cursor On/Off procedure

#define CURSOR_ON  1
#define CURSOR_OFF 2

int TextLCD::cursor(int show) { 
int cur = _cursor;
    switch (show) {
    default : return cur;
              break;
    case CURSOR_ON  : writeCommand(0x0F);
                      wait_us(40);  
                      _cursor = show;
                      break;
    case CURSOR_OFF : writeCommand(0x0C);
                      wait_us(40);
                      _cursor = show;
                      break;
    }
    return cur;
}
16 Oct 2011

Can i write as following code?? TextLCD lcd(p5, p6, p7, p8, p9, p10); rs, e, d4-d7 Can i connect like this??

07 Dec 2011

I was getting artifacts and my LCD was not initialising correctly. After some investigation, it transpires that my 16x2 LCD (A Varitronix branded MDLS16265-SS-LV-LED04-16PIN) needs at least 16mS after an 0x01 (cls) according to the datasheet.

I edited the library, and now it works fine every time.

23 Dec 2011

I've tested with a Winstar WH1602-YGH-CT -> KS0066 (http://www.datasheetcatalog.org/datasheets2/30/303671_1.pdf) Display and it works :)!!! Connect VSS, K and RW of the Display and GND of the mbed. External 5V to VDD of the display -> (current for driving the back light is required). Use 1k fix and 15..25k adjustable between VDD and Vo. 80..100Ohms between VDD and A/Vee. p15->RS p16->E p17->DB4 p18->DB5 p19->DB6 p20->DB7 other DBs are floating in 4-Bit mode. Programm the sample and see a "Hello world!" with back light.

04 May 2012

I got 5.0V LCD. Did everything given above. But all I get is a line of underscores... something like this: _ _ _ _ _ _ _ _ _ _ _ _ _ _

Help please

08 May 2012

Mine work fine with 5.0V. Rest everything the same and pin 3 grounded.

03 Dec 2012

Thanks very much for code example. We're sending real time text across a room (as a start to a text messaging project) from a PC through xbees to an LCD screen using mbeds. Your code is superb. We had to change the int putc ( int c ) cmd in the header file to char to deliver the individual letters one at a time.

Regards.

31 Jan 2013

I fixed the address issues with different LCD types by updating the TextLCD lib.

There is now support for

  • LCD8x1, /< 8x1 LCD panel */
  • LCD8x2, /< 8x2 LCD panel */
  • LCD16x1, /< 16x1 LCD panel (Is in fact a 8x2 in different layout) */
  • LCD16x2, /< 16x2 LCD panel (default) */
  • LCD16x2B, /< 16x2 LCD panel alternate addressing */
  • LCD16x4, /< 16x4 LCD panel */
  • LCD20x2, /< 20x2 LCD panel */
  • LCD20x4, /< 20x4 LCD panel */
  • LCD24x2, /< 24x2 LCD panel */
  • LCD24x4, /< 24x4 LCD panel (for KS0078 controller)*/
  • LCD40x2 /< 40x2 LCD panel */
  • LCD40x4 /< 40x4 LCD panel (two controllers)*/

Also added is a new method getAddress(column,row) that will return the correct memoryaddress.

The new library also supports an I2C PCF8574 portexpander or a SPI expander as alternate serial interfaces.

An updated forked version of Text LCD is discussed here.

You can find the new lib here.

Some background discussions on the problem and examples of the new code are here.

12 Feb 2013

At least a couple of the new 5V LCDs coming now from Sparkfun need a different contrast resistor. We had one that was all black squares and the characters were not quite visible (could only be detected at an extreme angle). Used a 2K resistor instead of the 1K and that fixed it.