Wednesday, July 28, 2021
Home » How To's » Using a Graphical LCD – A simple hack for drawing what you want on an affordable robot display

Using a Graphical LCD – A simple hack for drawing what you want on an affordable robot display

Coauthor Rick Swan, like his father, Dick Swan, creator of the RobotC programming environment, takes pleasure in sharing technical knowledge in the exploration of robotics.
This article shows how to easily connect a 48 x 84 pixel graphical LCD display to your robot controller and draw text to it. The presentation is geared to the entryto intermediate-level hobbyist or student who already has an understanding of basic concepts of bytes and protocols. It s also for any beginner looking for direction in taking on the rewarding challenge of learning LCD basics. Drawing text to your graphical LCD display requires only five signal leads (wires) on your controller. And with the widespread availability of small LCDs originally designed for cell phones these displays are almost as inexpensive as smaller text-only displays. For example, the display used in this article was designed for the first generation Nokia 3310 cell phone; it is available for under $20; it s made by INEX and sold by


Interfacing a graphics LC is very straightforward. An industry standard SPI (Serial Peripheral Interface) uses just three wires to connect the LC to your CPU i.e. a clock, data and ground line. Two additional wires provide a reset signal and a flag to indicate whether the data transferred contains pixels or commands or a commands display. Finally, a sixth wire provides power. Internally the display has a six-row x 84-column array of bytes containing the display pixels. Each row of the array is one of six horizontal stripes on the display. Each stripe contains eight rows of pixels. Serial data is sent to the display one byte at a time. Each byte represents the eight vertical pixels in one column of a stripe.

Most of the time pixels are transferred to the display. However, occasionally you need to send a command like setting the X and Y coordinates for the current write location. The display automatically increments these coordinates after every pixel byte received so that writing a complete stripe only requires two control bytes to set the address followed by 84 data bytes to completely rewrite all the pixels in the stripe.

Inexpensive Nokia display available from

Arudino Mega bottom viewa compact board.
The techniques discussed in this article will work with nearly all graphical LCDs since they usually use the SPI interface standard and have a similar command and data protocol. Many embedded CPUs operate at 5V and the graphics LCD operates at 3.3V. Fortunately, I used an Arduino Mega, provided by, as the CPU, which also has an internal 3.3V supply to power the LCD. Otherwise, I could have used a 5V to 3.3V converter, which is available from many sources like The signal leads also have to be reduced from 5V to 3.3V logic levels. Using two resistors (50K and 100K) connected in series on each I/O line provides the appropriate adjustment; you can see these on the breadboard and the schematic is downloadable from the web and from HERE.


Sample software that writes text characters to the display is available for download. For implementation ease, it uses a font size that fits within the eight rows of an LCD stripe and it aligns the vertical position of the text with one of the six stripes.

A single text character is represented by an array of pixels five wide by seven high on the LCD. Writing six consecutive bytes updates 6 x 8 pixels on the LCD; the first five bytes contain the character map and the sixth byte is zero to ensure that there is a blank column between characters. Since the characters are only seven pixels high, the last row of pixels is also blank to leave a space between lines of text. Eight bytes are needed to update one character on the LCD. Two command bytes at the start specify the X and Y location within the display and the six bytes contain the character. The code for this is shown below.

void writeChar(ubyte nRow, ubyte nColumn, char theChar)
ubyte *pPixelMap;
sendCommandChar(0x20 + nRow); // Set row address into LCD
sendCommandChar(0x40 + nColumn); // Set Column address into

// Get the address of data containing 5 x 7 pixel map for the char
pPixelMap = &pixelMap[theChar * 5];
for (i = 0; i < 5; ++i)
sendDataChar(0); // Blank column after the character

Writing a multi-character string is another common utility function that is easily created by extending the above function.


An SPI link provides a simple way to transfer data between devices using only two signal lines for clock and data. To transfer a byte of data, the master device (i.e. our CPU) sets the clock line to its low value. Then it sets the data line to a high or low value depending on the value of the bit being set. The clock line is changed to the high value. The slave device (i.e. the LCD) recognizes the transition of the clock line and uses this as a signal to get the value of the data line. A single bit has now been sent. Repeat seven more times for transfer of a complete byte.

An SPI link can be bi-directional; transmitting and receiving data using a common clock line. Only one direction is used for the LCD application but the receiving direction, if used, operates in a similar way. It requires an additional I/O line for the received direction.

Many embedded CPUs contain one or more integrated SPI peripherals where you can simply write a byte to the peripheral and it looks after transmitting the byte over the clock and data lines. It is also easy to write a bit banged solution in software that uses any two I/O lines on your CPU. The downloadable source code at contains code for both implementations.

The LCD has an additional input used to perform an initial reset on the LCD. Another I/O line is used to indicate whether the transferred byte is pixel data or a command to the LCD.

Arduino Mega microcontroller top view.

Arduino breadboard useful in limitless experimentation and research.

Mapping the image pixels to memory.


Writing lines of text to the LCD barely scratches the surface on its display capabilities. Further enhancements include functionalities like drawing individual pixels, straight lines, circles and ovals, use of different sized fonts, etc. These are straightforward to implement but require a different implementation strategy. In the provided example, text characters were written directly to the LCD without intermediate buffering.

For the advanced functions, you will need to store a shadow image of the pixels in a RAM buffer. The LCD only allows you to write complete bytes within a stripe. If you only want to redraw a single pixel within this byte then the other seven pixels need to be the same as the current value.

When you perform a drawing command, the appropriate bits in the RAM buffer are modified. Periodically the complete RAM buffer is sent to the LCD; typically by a low priority background task driven by a timer that fires five to 10 times a second. If you don t want to write your own library functions, then an internet search will find several open source libraries with many of these expanded functions


Using the sample code, schematic and pictures available for download you should be able to easily interface a graphics LCD to your robot controller. It s far cooler than the more common technique of using a smaller size 2 x 16 display. The cost for a graphics LCD is comparable to a text LCD.


RobotShop,, (866) 627-3178

Spark Fun Electronics,

Words by Rick Swan