Driving a 4-Bit LCD with an Arduino

I received my Arduino Diecimilia today.  Man, what a cool little device.  I ordered it last weekend with the intent of using it to learn about programming microcontrollers, in hopes of making some neat toys.  One of the first things I wanted to be able to do right away was drive an LCD display.  This is very important because I feel that all devices should have LCD displays.  All of them.  Nowadays, I look down on printers without LCD displays (and network cards for that matter) with utter disgust.

Anyway, I went to SurplusGizmos and found myself a nice and cheap 16×2 backlit LCD display.  It uses the KS0066 controller chip, which is supposedly compatible with the legendary Hitachi HD44780 command set.  Because I couldn’t wait for the Arduino to come, I tested it first with a parallel port and lcdproc.

When the Arduino came today, I was ready to try the LCD with it.  Using the integrated LiquidCrystal library, I was able to drive it in 4- and 8-bit mode.  However, in 4-bit mode, the LCD seemed to have trouble keeping up, as long strings would get garbled pretty badly.  It worked fine in 8-bit mode, so I figured this was likely due to the controller switching upper/lower nibbles too quickly.

So, in a bit of shameful C++ fu, I created a derivative library that just subclasses the existing one and puts a 2ms delay after each write operation.  This seems to completely clear up the problem, and I can happily have four digitial IO lines back as a result.

The code is extremely simple, so I’ll just post it here for the taking.  The header is:

#include “../LiquidCrystal/LiquidCrystal.h”

class Slow4BitLCD : public LiquidCrystal {
  public:
    Slow4BitLCD(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
    void write(uint8_t);
};

…and the implementation is:

#include <inttypes.h>
#include “WProgram.h”

#include <Slow4BitLCD.h>
#include “../LiquidCrystal/LiquidCrystal.h”

Slow4BitLCD::Slow4BitLCD(uint8_t rs, uint8_t rw, uint8_t en, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
  : LiquidCrystal::LiquidCrystal(rs, rw, en, d0, d1, d2, d3)
{}

void Slow4BitLCD::write(uint8_t value) {
  LiquidCrystal::write(value);
  delayMicroseconds(2000);
}

Create an Arduino library called “Slow4BitLCD” and put those two files in (with .h and .cpp extensions, respectively) and you should be in business.

Category(s): Hardware

Comments are closed.