Thursday, 26 September 2013

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.