Serial --> LCD

By: kmat

2008-04-10 13:21:10

Last weekend I built an RBBB board that I bought at DorkbotPDX 0x01. This is the cheapest way to get into an Arduino that I know of. And pretty much the cheapest microcontroller setup you can get. Thanks guys who put these kits together for us locally! I had never done anything with Arduino before (hardly even with microcontrollers) so this offered a low entry fee and great support.

I had some 2-line LCDs I had bought a few weeks ago from Electronics Goldmine for $1.79. They aren't backlit but they are so cheap it just seemed like a good thing to have. One painful thing about Hitachi 44780-based LCD displays is that they use a LOT of IO pins to display stuff. 8bit mode uses all of the digital pins on the Arduino. 4bit mode still uses a lot. I saw some other solutions like using a shift register to bring it down to two pins. But the simplicity of of Serial LCDs was really appealing, so I thought I'd rig one up using the RBBB as a controller. Any future projects that need an LCD can then just talk serially to the Arduino LCD controller and very little is needed to make things work. img

This project was almost too simple due to the great libraries available for the Arduino. I used the built-in Serial library and the LiquidCrystal library from the Arduino Playground.

So investigation into the way the Hitachi chips works showed that it would be nice to break out some of the control code into special characters so that signaling could be really simple from the controlling board (in testing this was my PC running Linux's minicom). The 44780 has a limited display set so that makes a lot of characters in the ASCII set available to use as specials. I picked some that seemed good to me to use as control characters. They're documented in the code. I also wanted to be able to send any arbitrary control codes to the LCD as well, so I implemented a system where you can send Ctrl-R followed by the command in the next byte. Seems to work well. With this code, in theory anything available on the 44780 is exposed to the serial connection.

I added the ability to show an initialization string mostly because I wanted to see it working on boot.

Anyway, here's the code such as it is:

// Serial_LCD -------------------------------------------------------------------------// Simple Serial LCD sketch for Arduino (on my RBBB)// Uses the LCD in 8bit mode.  Some commands are pulled out for ease of use.  All// others can be sent by first signalling Ctrl-R, then sending the Hitaci 44780// command in the following byte.  No error catching is done on 44780 commands// so you can hang the LCD controller by sending bogus stuff, necessitating a reset.//// Set up for 2-line LCDs, but you could easily modify for more.//// Karl N. Matthias -- April 2008 -- karl [a t] matthias [d o t] org// ------------------------------------------------------------------------------------#include <LiquidCrystal.h>    // include LiquidCrystal library (Arduino playground)LiquidCrystal lcd = LiquidCrystal(); // create a LiquidCrystal object to control an LCDchar string[] = "Nadia Rocks!";byte line = 0;               // track which line of the display we are onbyte cursor = 1;             // LCD underline cursor on/offvoid setup(void){    lcd.init();              // initialize the LCD    digitalWrite(13,HIGH);   // turn on an LED for debugging    lcd.commandWrite(0x38);  // two line mode    lcd.clear();             // clear the display    delay(10);               // delay 10 ms to view change    Serial.begin(9600);      // slow for SoftwareSerial on another Arduino    lcd.printIn(string);     // show initialization string (Nadia is my daughter)}void loop(void){  char input;  while(Serial.available() > 0) {    input = Serial.read();    switch(input) {      case 0x0D:                   // carriage return      case 0x0A:                   // line feed        if(line == 0) {          lcd.commandWrite(0xC0); // move to first character of second line        } else {          lcd.commandWrite(0x02); // move to first character of first line        }        line = !line;        break;      case 0x5C:                 // '\' is used to clear screen        lcd.clear();        break;      case 0x08:                 // Backspace shifts display left        lcd.commandWrite(0x18);        break;      case 0x09:                 // Tab shifts display right        lcd.commandWrite(0x1C);        break;      case 0x11:                 // Ctrl-Q toggles cursor mode        if(cursor) {          lcd.commandWrite(0x0C);        } else {          lcd.commandWrite(0x0E);        }        cursor = !cursor;        break;      case 0x12:                 // Ctrl-R: Issue arbitrary LCD commands        while(Serial.available() == 0) { }  // block until we get 2nd byte        input = Serial.read();        lcd.commandWrite(input);        break;      default:        if(input > 31) {         // first printable character, the space ' ' is 32          lcd.print(input);          Serial.println(input);        }    }  }} //repeat forever
Back to archive index