Introduction: Running an HD44780 Display Off the ATmega on a Gertboard

There was a thread on the Raspberry Pi forums about running a 16x2 HD44780 based display off the ATmega chip on the Gertboard.  I normally use a shift register to run my display, so I wasn't much help to them.  I decided to try and get it setup without the shift register to help out the folks having trouble.

So, this instructable will detail how to go about getting an HD44780 display running off the ATmega chip on the Raspberry Pi Gertboard.

Step 1: Ground an 5V

The first step is to connect the display to ground and 5V on the Gertboard.  Because you have to connect a pot to the contrast, I hooked up the Ground and 5V to my breadboard, and plugged the display into that.

Step 2: Contrast

Pin 3 on the display controls Contrast. It's connected from Pin 3 to a 1k pot to ground.

The output from Pin 3 gets connected to one side of the pot, and ground to the middle leg of the pot.

Step 3: Register Select

Pin 4 is Register Select.  This is our first pin connected to the ATmega chip on the Gertboard.  I chose pin 8, which is marked as PB0, just because I could.

I added some white lines in the picture to help clear up where each pin was, as it was hard to tell.

Step 4: Read/Write

Pin 5 is the Read/Write pin, which allows you to read data off the display, or write data to the display.  Reading data is not something you want to do with your Gertboard, because it's 3V3 based, and the output of the display is 5V.  You'll likely fry your board.  So this pin goes to ground.

Step 5: Enable

Pin 6 is the Enable pin.  This tells the display you actually want it to process the data when it is high.  When it is low, data is ignored.  This is our second pin going to the Gertboard.

Step 6: Data Pins

To save pins on the Gertboard, my setup uses four bit mode, so only data pins D4-D7, which are pins 11-14 on the display, are used.  These are connected one at a time, in order, to the Gertboard.

Step 7: The Code

Here's the code for my sketch, which is very heavily based on the code from Raspberry Pi Spy:

const int LCD_RS=8;
const int LCD_E=9;
const int LCD_D4=10;
const int LCD_D5=11;
const int LCD_D6=12;
const int LCD_D7=13;

const int LCD_WIDTH=40;
const boolean LCD_CHR=true;
const boolean LCD_CMD=false;

const int LCD_LINE_1=0x80;
const int LCD_LINE_2=0xC0;

const int PAUSE=1;


void allLow(){
  digitalWrite(LCD_D4,LOW);
  digitalWrite(LCD_D5,LOW);
  digitalWrite(LCD_D6,LOW);
  digitalWrite(LCD_D7,LOW);
}

void tick(){
  delay(PAUSE);
  digitalWrite(LCD_E,HIGH);
  delay(PAUSE);
  digitalWrite(LCD_E,LOW);
  delay(PAUSE);

}


void lcd_byte(int bits, boolean mode){
  if (mode==true){
    digitalWrite(LCD_RS,HIGH);
  } else {
    digitalWrite(LCD_RS,LOW);
  }

  allLow();
  if ((bits&0x10)==0x10) {digitalWrite(LCD_D4,HIGH);}
  if ((bits&0x20)==0x20) {digitalWrite(LCD_D5,HIGH);}
  if ((bits&0x40)==0x40) {digitalWrite(LCD_D6,HIGH);}
  if ((bits&0x80)==0x80) {digitalWrite(LCD_D7,HIGH);}

  tick();

  allLow();
  if ((bits&0x01)==0x01) {digitalWrite(LCD_D4,HIGH);}
  if ((bits&0x02)==0x02) {digitalWrite(LCD_D5,HIGH);}
  if ((bits&0x04)==0x04) {digitalWrite(LCD_D6,HIGH);}
  if ((bits&0x08)==0x08) {digitalWrite(LCD_D7,HIGH);}

  tick();
}

void lcd_string(String message){
  for (int i=0;i<message.length();i++){
    lcd_byte(message.charAt(i),LCD_CHR);
  }
}

void setup(){
  pinMode(LCD_RS,OUTPUT);
  pinMode(LCD_E,OUTPUT);
  digitalWrite(LCD_E,LOW);
  pinMode(LCD_D4,OUTPUT);
  pinMode(LCD_D5,OUTPUT);
  pinMode(LCD_D6,OUTPUT);
  pinMode(LCD_D7,OUTPUT);

  lcd_byte(0x33,LCD_CMD);
  lcd_byte(0x32,LCD_CMD);
  lcd_byte(0x28,LCD_CMD);
  lcd_byte(0x0C,LCD_CMD);
  lcd_byte(0x06,LCD_CMD);
  lcd_byte(0x01,LCD_CMD);

  lcd_byte(LCD_LINE_1,LCD_CMD);
  lcd_string("HELLO");
  lcd_byte(LCD_LINE_2,LCD_CMD);
  lcd_string("WORLD");
}

void loop(){

}

Step 8: Lesson Learned

This code would have worked the first time I tried it, but for one small thing.  The if statements didn't want to work, and I couldn't figure out why they couldn't.

The if statements were originally:

if (bits&0x10==0x10) {digitalWrite(LCD_D4,HIGH);}

but this didn't work.  It took a lot of troubleshooting, and a lot of work, to figure out that the code needed parentheses around the "bits&0x10" part, becoming:

if ((bits&0x10)==0x10) {digitalWrite(LCD_D4,HIGH);}