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:
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 “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.