Driving text LCDs with the teensy 3.0

A few days ago I started exploring the teensy 3.0. I'm keen to see if we should consider using the teensy for C3Pi, so I want to get more familiar with the teensy hardware and the development environment.

When you install teensy's extensions to the Arduino IDE you are given a chance to install a number of additional libraries that have been tested on the teensy family. One of them - LiquidCrystalFast - caught my eye and I decided to explore it in more detail.

The LiquidCrystalFast library

LiquidCrystalFast is yet another library for driving text LCDs based on the ubiquitous Hitachi HD44780. I love these displays, and so do many hobbyists; a old post about an Arduino DVM with LCD display is one of the most visited pages on this blog.

The standard Arduino LiquidCrystal library works pretty well, but suffers from two minor issues.

The first is that it doesn't work as it should for 4-row 16-column displays. (It's fine for 2 row displays and for the 4-row 20-column variety).

The other issue is that it relies on precise timing of the signals it sends to the LCD.

Two LCD Driver designs

Displays based on the HD44780 can be driven uni-directionally or bi-directionally. The standard Arduino library uses them uni-directionally, which means that the code contains delays to make sure that the display has time to process each command.

The LiquidCrystalFast library uses the data lines bi-directionally, and as a result it runs significantly faster. Display speed is not usually a problem, but using up too much of the Arduino's processing power can be. If you're trying to do lots of other work on the 8-bit micro, a slow LCD driver isn't ideal.

The library also fixes the bug with 4-row 16-column displays.

Don't fry your teensy!

The LiquidCrystalFast library is a little harder to use on the teensy 3.0 because of voltage incompatibility. Like most ARM-based systems, the teensy accepts inputs between 0 and 3.3 volts; most LCDs use 5 volt signals. If you're using the data lines uni-directionally, that's not a problem, as most displays work fine with 3.3 volt inputs. If you use it bi-directionally the display's 5 volt outputs could damage the teensy.

All this is clearly explained on the teensy website, along with a simple solution. You just insert four 1k ohm resistors between the data pins on the LCD and the GPIO pins on the teensy.

Don't get spaghetti on the Breadboard

The only downside of the hardware layout on the teeny website is that the wiring is a bit spaghetti-like. Neater layouts are easier to check.

Fortunately the library allows you to change the pin assignments on the teensy, and it's possible to do so in a way that lets you create really neat connections.

Here's a Fritzing diagram of the layout I ended up with. It was really easy to wire it up, and it worked right away.

The only thing you need to change in the provided LiquidCrystalFast sketch example is the statement that creates the lcd object, which should read

LiquidCrystalFast lcd(2, 3, 4, 9, 10, 11, 12);
        // LCD pins:  RS RW EN D4 D5  D6  D7

My next task is to modify the breadboarding and the sketch to use a stripboard-based arduino clone which I can drive via I2C; it's an enhanced version of an old project and I plan to use it with the Raspberry Pi and the Quick2Wire interface board.


  1. I have a question. My 20x4 display is a bit different than the one you illustrated here, but it is a 5v system and I had it wired directly using a unidirectional configuration and had no results. I figured it was the 3.3v logic levels so I ran each line through a MC74ACT125 buffer and still no results. I noticed you actually used 1k resistors on the data channels but no level translation. How??

    I had this working great using a PIC18F4550 and might build that project back up again, using serial to it to display from the teensy, but I would rather not. lol.


Post a Comment

Popular posts from this blog

Controlling a Raspberry Pi Pico remotely using PySerial

Five steps to connect Jetson Nano and Arduino

Raspberry Pi Pico project 2 - MCP3008