Feedback!

Word Processor LCD HD44780

Views: 1466 Difficulty: 2 Status: Development
Lcd_hd44780_main

Write messages on Liquid Crystal Displays with potentiometers or keyboards.

Use your words! Write text on a Liquid Crystal Display with an Arduino and an HD44780 Hitachi-style LCD. The text can come from one of our shift-register based keyboards, or from a potentiometer. The HD44780 is a de facto industry standard for Liquid Crystal Displays and you can find lots of different LCDs that use this protocol. For example, Sparkfun has one with an RGB backlight, adafruit has a big 16x4 LCD, and you can find a ton on eBay, but be careful sometimes the super discount varieties have non-standard pin layouts.

Pal-Sized Word Processing

Hd44780_w_hand
Driving the HD44780 with of our Arduino Clones.

Video of LCD Screen and Keyboard Typing

This video shows the LCD Screen powered by our Arduino-Clone and hooked up to the AlphaZed keyboard and the DIY Keyboard.

Arduino Code for Typing on an LCD Screen

This code uses the liquid crystal Arduino library along with our DIY keyboard to allow you to type on an LCD Screen. The DIY Keyboard tutorial explains how to read text from the keys now the challenge is to put that text on the LCD screen. The main function that is in charge of this is called write_message() and it goes like this:
void write_message() {  
  if (something_in) {
    if      (key_pressed == SHIFT)  shift_pressed();
    else if (key_pressed == ENTER)  enter_pressed();
    else if (key_pressed == DELETE) delete_pressed();
    else write_char(key_pressed);
  }
  something_in = false;
  // print the message  
  lcd.setCursor(0,0);
  lcd_print_line( 0, message.substring(0, 16) );
  lcd_print_line( 1, message.substring(16,31)+message[31] );
  lcd.setCursor(cursor_index,line_index);
  delay(200); 
}
First, we check the global boolean something_in. This variable will be true whenever a key has been pressed. It is set in the read_keyboard function. If a key has been pressed, then we check if it is one of the control characters: shift, enter or delete. If it is, then we call the function associated with that control character. Otherwise, we call the write_char function, which will add the character to the message string and increment the cursor_index and line_index appropriately. Then, regardless of whether a key was pressed or not, we write the message out to the screen. We break it up into two substrings each displayed on the two lines of the HD44780 LCD.
/*  LucidTronix code for typing on an LCD Screen
 *  Uses the liquid Crystal library as well as our
 *  DIY Keyboard
 *  See the tutorial at:
 *  http://lucidtronix.com/tutorials/46
 */

#include <LiquidCrystal.h>
#define SHIFT '@'
#define ENTER '#'
#define DELETE '^'

// initialize the library with the numbers of the interface pins and the original message
LiquidCrystal lcd(6, 7, 19, 18, 17, 16);
String message = "        ";


// keyboard specific
int dataPin = 8;//12
int clockPin = 9;//11
int latchPin = 10;//10


String letters[] ={"yz #^@.!","qrstuvwx","ijklmnop", "abcdefgh"};  //"edcbahgf"
String letters_cap[] ={"YZ #^@.!","QRSTUVWX","IJKLMNOP","ABCDEFGH" };
int num_registers = 4;
byte button_states[] = {0x00,0x00,0x00,0x00};  //01 00 10 00
char key_pressed;
boolean something_in = false;
boolean shift_state = 0;


// some more initialization
int mode = 0;
int num_modes = 2;
int cur_scroll = 0;
int cur_msg_length = 0;
int cursor_index = 0;
int line_index = 0;
int char_index = 0;
unsigned long last_press = 0;
int scroll_pos = 0;



void setup() {
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);

  // Print a message to the LCD.
  lcd.print("hello!!");
  delay(500);
  lcd.blink();
  
  // setup the pins for the keyboard
  pinMode(dataPin, INPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  
  // setup the size of the message
  pad_string_with_zeros( &message, 32 );
}

void loop() {
  read_keyboard();
  write_message();
  scroll_message();
  
  delay(50);
}


void scroll_message() {

  if (analogRead(1) < 200 ) {
    lcd.scrollDisplayLeft();
    scroll_pos++;
    if (scroll_pos > 31) scroll_pos = 0;
    delay (4*analogRead(1));  
  }
  else if (analogRead(1) > 400){
    //Maybe wont werk
    scroll_pos = 0;
    lcd.setCursor(0,0);
    /*
    if (scroll_pos > 0) {
      for (int i=0; i<scroll_pos; i++) lcd.scrollDisplayRight();
      scroll_pos = 0;
    }
    */
  } 
  
}




void write_message() {
  
  // Shift button pressed
  
  if (something_in) {
    if      (key_pressed == SHIFT)  shift_pressed();
    else if (key_pressed == ENTER)  enter_pressed();
    else if (key_pressed == DELETE) delete_pressed();
    else write_char(key_pressed);
  }
  something_in = false;
  
  // print the message  
  lcd.setCursor(0,0);
  lcd_print_line( 0, message.substring(0, 16) );
  lcd_print_line( 1, message.substring(16,31)+message[31] );
  lcd.setCursor(cursor_index,line_index);
  delay(200);
  
}


void write_char(char in) {
      message[line_index*16+cursor_index] = in;
      
      if ( cursor_index ==  15) {
        cursor_index = line_index*15;
        line_index = 1;
      }
      else cursor_index++;
}


void delete_char(){
  message[line_index*16+cursor_index] = ' ';
  if (cursor_index == 0) {
    cursor_index = line_index*15;
    line_index = 0;
  }
  else cursor_index--;
}



void lcd_print_line( int line, String message ) {
 
  lcd.setCursor(0,line);
  lcd.print(message);
  lcd.setCursor(0,0);
  
}

void pad_string_with_zeros( String* str, int s_max ){
  
  int s = str->length();
  
  if ( s < s_max ) {
    String zeros;
    for (int i=0; i<=s_max-s-1; i++){
      zeros += " ";
    } 
    *str = *str + zeros;
  }
}





void read_keyboard(){
  if (millis() - last_press > 400) {
    //set it to 0 to transmit data serially  
    digitalWrite(latchPin,LOW);
    //while the shift register is in serial mode
    //collect each shift register into a byte
    //the register attached to the chip comes in first 
    
    for (int i = 0; i < num_registers; i++){
      button_states[i] = shiftIn(dataPin, clockPin);
    }
    digitalWrite(latchPin,HIGH);
    something_in = false;
    
    for (int i = 0; i < num_registers; i++){
      
      if (!shift_state) something_in = translate_buttons_2_keys(button_states[i], letters[i]);
      else              something_in = translate_buttons_2_keys(button_states[i], letters_cap[i]);
      
      if (something_in) {
        last_press = millis();
        break;
      }
    }
    
    
    
  }
}



boolean translate_buttons_2_keys(byte buttons, String letter_group){
  for(int i = 0 ; i < 8; i++){  
     if ( (1 << i) & buttons ){
       key_pressed = letter_group[i];       
       message[line_index*16+cursor_index] = key_pressed;
       return true;
     }     
  }
  
  return false; 
}



void shift_pressed() { shift_state = !shift_state; }
void enter_pressed() { if (!line_index) line_index = 1; }
void delete_pressed() { delete_char(); }

byte shiftIn(int myDataPin, int myClockPin) { 
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);

  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(20);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      myDataIn = myDataIn | (1 << i);
    }
    else {
      pinState = 0;
    }

    digitalWrite(myClockPin, 1);

  }
  return myDataIn;
}
Permalink: http://lucidtronix.com/tutorials/46
A QWERTY keyboard you build yourself....
32 buttons for a fully-functioning hand-held USB keyboard....
RGB Flashlight, wearable sound art, rainbow lamp....
Keyboard kit using CD4021 shift registers and big through hole buttons....
The heartduino is a heart-shaped arduino clone complete with onboard sensors and a 70 pixel LED matri...
Control a 120v outlet with a 5V arduino....
Rainbow flower necklace using the TLC5940....
Wall-ter is a wall following robot....