Skip to main content

Using Character LCDs

Drive A Liquid Crystal Display From Your Connected Product

Character LCDs provide a project with a compact, easy-to-read display for basic textual information. The most common type of character LCD available to developers ship on a circuit board which also contains a Hitachi HD44780 controller chip or one of a number of controllers that are compatible with the Hitachi device, such as the Seiko-Epson SED1278. The HD44780 is now the de facto standard for character LCD controllers.

A typical character LCD

Hitachi HD44780

The HD44780 connects to the outside world across a standard 14-pin interface. Most LCDs come with 16 pins — the extra two, usually marked A and K, are used to access the display’s backlight anode and cathode connections, and are optional. The full set of 16 pins is:

Pin Name Description Role
1 GND Ground Power
2 VCC LCD Voltage Power
3 VLCD LCD Display Bias (contrast control) Power
4 RS Register Select Input
5 RW Read/Write Select Input
6 E Enable Input
7 D0 Ground I/O
8 D1 Ground I/O
9 D2 Ground I/O
10 D3 Ground I/O
11 D4 Ground I/O
12 D5 Ground I/O
13 D6 Ground I/O
14 D7 Ground I/O
15 A Backlight Anode (Optional) I/O
16 K Backlight Cathode (Optional) I/O

These are the the most common names, but you may see the power pins labelled differently, for example: VSS, VDD, V0 for the first three pins.

The HD44780 supports displays ranging from one line of eight characters (8 x 1) to four lines of 40 characters (40 x 4), and you can easily find displays of these dimensions and any in between, including the very commonplace 16 x 2 and 20 x 4 sizes. Each HD44780 is designed to support up to 8 x 2, ie. 16 characters, so displays with greater dimensions use two, three or four controllers, all connected through a single 14-pin bus. Each HD44780 is smart enough to co-operate with the others so that you don’t have to worry about which particular one your imp is talking to.

Depending on their size, LCDs may need more than one HD44780 controller,
usually mounted under black plastic domes


Fourteen pins can present something of a challenge when it comes to hooking up a character LCD to imps with a low number of GPIO pins, such as the imp001. The HD44780 has a 4-bit mode which means you can dispense with four of the eight data pins, but that still leaves seven pins required for data and an eighth if you want to set the display contrast dynamically.

Fortunately, you can use one of the various backpack boards designed to bridge the HD44780’s 14-pin bus (and the two backlight pins) to either I²C or SPI. I²C is particularly good for imp applications because it requires only two pins at the imp end of the bus.

Adafruit’s I²C/SPI backpack is a good choice. It can handle character LCDs with display dimensions from 8 x 1 to 20 x 4 and only adds around $10 to the price of a project. It is sold separately from the LCD itself, giving you scope to choose exactly the display you prefer, and it includes circuitry to manage the display contrast, which is controlled from a variable resistor on the board itself.

Adafruit’s I²C/SPI backpack

Display Choice

There is one criterion when it comes to choosing a character LCD: its operating voltage. This has to be correct for imp operation, which means the display must operate at 3 or 3.3V. Most of the character LCDs on the market are designed to operate at 5V and these are not suitable for connecting directly to an imp without some form of level adjustment. Though the selection of said screens isn’t as broad as it is for 5V devices, you should be able to find a 3.3V display that meets your needs.

Beyond operating voltage, displays come in a variety of sizes, in various colors and with backlights designed for dark-on-light characters or for light-on-dark. Prices are low and availability is good.

Make sure you choose a 3.3V LCD for imp-based projects


Writing to the HD44780 — and thus the LCD — involves choosing one of the chip’s two registers, Command and Data, which is done by setting the RS pin high or low, respectively. Next set the RW pin low to indicate a write, put the data byte’s bit values on the data pins, and set E to high to tell the chip to process the data. When the HD44780 has had time to do so, you end the process by setting E low. The HD44780 datasheet tells you how long all key tasks take to complete so you know how long to wait before setting E low.

Before you can start presenting characters on the display, you need to initialize the display. This involves sending the Function Set command, followed by Entry Mode Set, Display Control and Clear Display. These are all set codes which, again, the datasheet provides. You’ll find them included in the sample code, below.

These processes need to be followed whether you connect the display directly or via an I²C or SPI bridge.

Character Sets

The HD44780 is pre-programmed with all the standard Ascii characters. It also provides eight user-definable characters that you can use to add symbols that are either absent from the controller’s characters — the degrees sign, for instance — or which are unique to your application, such as weather icons. The HD44780 reserves a block of RAM for the user-definable characters, so they won’t be preserved when the controller is power-cycled. However, it does mean you can change any of the characters on the fly, giving you an effectively infinite set of characters to work with.

The user-definable characters are drawn on a 5 x 8 pixel matrix and allotted to Ascii values 0 through 7. You send the RAM address of the character you want (the base address OR’d with the chosen Ascii value) as a command and then write the eight bytes of character matrix row data. Bits 5 through 7 of each row are ignored, leaving bits 0 through 4 as the character matrix values.

You can use this grid to design characters:

Sample Code

Electric Imp’s GitHub repo contains a Squirrel class for working with character LCDs connected via Adafruit’s I²C/SPI backpack. The class, CHARLCD, is instantiated with the imp I²C bus to which the display is connected and the backpack’s I²C address, which defaults to 0x20 but can be changed by bridging a series of pads on the back of the board. The new CHARLCD object must then be initialized, using the init() function, with the dimensions of the LCD: the number of characters and the number of rows. For example:

display <- CHARLCD(hardware.i2c89);  // Instantiate LCD on i2c189 (default address: 0x20)
display.init(20, 4);                 // Initialize LCD to 20 x 4

The class provides functions to print characters and strings, set the print position to a chosen row and column, to center text on the screen, to switch the backlight on or off, and to define characters. The HD44780 supports broader functionality: to set a static or blinking cursor, to set the type of cursor (underline or block) and to handle scrolling, for example. Details of these and other features can be found in the controller’s datasheet.