PAReX Home

Phoenix Area Robotics eXperimenters

Home Club Info Web Log Meetings Events Rules Articles Links

June 28, 2002

Using an LCD Display with your Robot Part 1

Having a display in your robot can very helpful in developing and debugging the hardware and software of the robot. My first Maze Runner used a 16 character 2 line display to debug the range sensors, calibrate the servos, wheel encoders, and floor sensors. You could do a similar operation with a serial port and a PC, but you are limited to the location of the PC and your cable length (unless you have a laptop). Another use for the display is a menu system that selected the operating mode you wish to run, i.e. "Left wall follow", "Right wall follow", as well as enabling different turn algorithms and sensors.

An LCD display can be very inexpensive and use very little current, no need to worry about the battery life. I've seen serial display modules go for $49 (text) or $99 (graphic)which is a big dent in the wallet. A better approach is to buy the displays from surplus centers such as B.G. Micro or All-Electronics, where a 2x16 display with backlight will cost you $5. Then either connect it directly to your micro or you could even use a 2nd micro just to control the display. Now with a little software development you have the equivalent to that $49 serial display, for under $10.

The majority of these LCD displays use the Hitachi HD44780 or equivalent controller, so the rest of this article will be based on the use of this type of display. One thing to watch out for is the contrast circuit on the display. Some of the display units you can get are "temperature compensating" or "Extended temperature". These units require a negative voltage for the contrast input, so unless you have multiple power supplies on your robot, make sure you don't get this type of display. The regular display unit will work by simply grounding the contrast input (pin 3).

Hardware Interface

Ok, now you have a display module, let's see how to use it. The typical interface is a 14-pin connector with the following pinout:

 1 = GND
 2 = VCC  (typically 5 volts)
 3 = VEE  (contrast voltage)
 4 = RS   register select - H = data input, L = instruction input
 5 = R/W  Read/Write - H = read data from display, L = write data to display
 6 = CE   Chip Enable - H = interface enabled, L = interface disabled
 7 = DB0  data bit 0
 8 = DB1  data bit 1
 9 = DB2  data bit 2
10 = DB3  data bit 3
11 = DB4  data bit 4
12 = DB5  data bit 5
13 = DB6  data bit 6
14 = DB7  data bit 7
The display interface can support either a 4-bit or 8-bit mode. In 8-bit mode you send one byte at a time to the display and require a minimum of 10 I/O bits. The 4-bit mode uses only 6 I/O bits, but runs a little slower since it takes 2 write cycles to send each byte to the display (sends a 4-bit nibble each time).

display1 Here's the minimum hookup you can do, which uses 4 data bits, the CE, and the RS lines. I show all 6 bits connected to port D of a microcontroller, but you can use whatever ports you have available. Note that in 4-bit mode you will actually use the upper data bits of the display interface, while the lower 4 are grounded. By tying the R/W line to ground, the display is always in write mode and you save one more I/O line. The only drawback to this approach is you can't read back the status to see if the display is busy, but must rely on a blind delay to determine when you can send more data to the display. Not a big deal for most applications.

If you can afford the extra I/O pins and want to write as fast as you can, then 8-bit mode is the way to go. Now you hook up all 8 data bits, plus the CE, RS, and R/W lines. Now you write 1 whole byte at a time and can monitor the status register to determine when the display is not busy. I/O

Some microprocessor use an external bus for all I/O instead of port pins. This is a typical method for using the display on a databus. Note that the R/W mode is determined by the processor WR line, and that CE and RS are mapped into various memory locations. display3.jpg (56163 bytes)

Software Interface

Ok now your display is wired up and ready to go. If you apply power to it, nothing will happen because we need to initialize it. The initialize sequence will vary slightly depending on whether you use 4 or 8 bit access. Note that during the initialization routine the Busy Flag is not available for readback, so delays must be used between write operations. You don't need to use the minimum delay shown, you could use 15ms for each of the delays if it makes the code writing simpler. Also note that newer display designs may have faster chips and don't require the same delays as the HD44780 chipset. Please consult the specs for your display to determine the actual delays required.

8-bit Initialization
        Display powers up
        Wait at least 15ms for display startup
        write 0x30 with RS=0
        Wait at least 4.1ms
        write 0x30 with RS=0
        Wait at least 100us
        write 0x30 with RS=0
        Wait at least 40us
        write 0x30 with RS=0    ;8-bit mode
        Wait at least 40us
        write 0x38 with RS=0    ;5x7 font, 2 line mode
        Wait at least 40us
        write 0x0C with RS=0    ;display on, cursor off
        Wait at least 40us
        write 0x06 with RS=0    ;cursor moves right, no shift
        Wait at least 40us

4-bit Initialization
        Display powers up
        Wait at least 15ms for display startup
        write 0x3 with RS=0
        Wait at least 4.1ms
        write 0x3 with RS=0
        Wait at least 100us
        write 0x3 with RS=0
        Wait at least 40us

        ;after the first 3 writes all commands
        ;must now be 8-bits sent as 2 4-bit nibbles.

        write 0x2 with RS=0     ;4-bit mode
        write 0x0 with RS=0
        Wait at least 40us
        write 0x2 with RS=0     ;5x7 font, 2 line mode
        write 0x8 with RS=0
        Wait at least 40us
        write 0x0 with RS=0     ;display on, cursor off
        write 0xC with RS=0
        Wait at least 40us
        write 0x0 with RS=0     ;cursor moves right, no shift
        write 0x6 with RS=0
        Wait at least 40us

At this point the display should be active and you can send ASCII characters to it (RS=1), or commands that clear the display or move the cursor around (RS=0). One thing to keep in mind is the display's memory map. The same controller is used for all displays, regardless of whether you have a 1x12 character display, or a 4x40 character display. So when you write characters to the display, it won't know when you've reached the end of a line and wrap to the next line for you. Instead your software must keep track of where the cursor is and when you need to move to a new line. The memory map for 4 lines of display is as follows:

        Line 1 offset = 0
        Line 2 offset = 0x40
        Line 3 offset = 0x14
        Line 4 offset = 0x54
So if you wanted to move the cursor to the beginning of line 2 you would write the value 0xC0 to the display with RS=0. If you break down this command, we set bit 7 which means we're doing a DDRAM address set and 0x40 is the value we want to set the address to (or the cursor location). Here's the command format used to send commands to the display and read back status.

Instruction RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Description Executed
Time
Clear Display 0 0 0 0 0 0 0 0 0 1 Clears display and returns cursor to the home position. 1.64ms
Home Cursor 0 0 0 0 0 0 0 0 1 * Returns the cursor to home position (address 0) 1.64ms
Entry Mode Set 0 0 0 0 0 0 0 1 I/D S Sets the cursor move direction and display shift option. 40us
Display On/Off 0 0 0 0 0 0 1 D C B Sets the display on/off (D), Cursor on/off (C), Blink on/off (B) 40us
Cursor Shift Display Shift 0 0 0 0 0 1 S/C R/L * * Moves the cursor and shifts the display 40us
function set 0 0 0 0 1 DL N F * * Sets the interface data length (DL), number of display lines (N), and character font (F) 40us
cgram address set 0 0 0 1 CGRAM Address Sets the CGRAM address 40us
DDRAM address set 0 0 1 DDRAM Address Sets the DDRAM address (cursor position) 40us
Busy Flag Address Read 0 1 BF Address Counter Reads the busy flag (BF) and address counter contents 0us
CGRAM/DDRAM Data Write 1 0 write data Writes data into DDRAM or CCRAM 40us
CGRAM/DDRAM Data Read 1 1 Read Data Reads data from DDRAM or CCRAM 40us

The datasheet for the display will cover all the bit-mapped commands that you can perform, as well as the timing diagrams, font table, and electrical specs. Here's a typical datasheet for a DMC16205 display .

Direct Display Control

Now that you've seen how you can use an LCD display with your robot or other projects, you need to decide how to implement one. If you have the required I/O pins, you could connect the display directly to your processor. Keep in mind that writing to the display is slow and requires some though as to how to support the display without bogging down other tasks. If you don't plan to write to the display while the robot is actually running, then you don't have any real issues. If you do plan to write to the display while running, you might consider using a background task to handle the display, so you don't bog things down. Controllers like the BX24 are well suited to the task since it features a multi-tasking environment. For other platforms you could make use of the on-board timers and use an interrupt service routine to move data to the display.

Indirect Display Control

If you're short on I/O pins or don't want to mess with fancy background routines, then consider using a 2nd processor dedicated to running the display. This is exactly what those $49 serial display modules do. A small processor like an AT90S2313 or various PIC controllers are well suited to receiving data from a master processor via a serial interface and writing the data to the display using it's own port pins. The interface between the 2 micros can use 2-wire for bi-directional communication, or 1-wire if you just want to send data to the display micro without any type of feedback. Most micro-controllers have an internal UART which can be used to connect the 2 micros together. Using the fastest supported speed i.e. 115K insures that the master processor doesn't get bogged down sending data to the display processor. The display processor must be able to receive this fast data stream, buffer it, and send it to the display, without losing any incoming data (buffer overrun). In a future article I'll discuss my development of a serial based display module using an Atmel AT90S2313 and a 4x20 HD44780 based display module.

Go to Part 2

Posted by Kelly Small at 03:44 AM | Comments (0)

June 27, 2002

Using an LCD on your Robot

Added new article by Kelly Small about using an LCD on your robot
Posted by Kelly Small at 07:14 PM