Serial LCD using Arduino

Not having much luck using a LCD down a long cable with a parallel interface I’ve started making an Arduino sketch to add serial comms.

#include <LiquidCrystal.h>           // Setup the LCD
LiquidCrystal lcd(9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19);

#define COMMAND 0xFE                 // Command bytes
#define CLEARSCREEN 0x58
#define CURSORTO 0x47
#define GOHOME 0x48
#define GPOON 0x57
#define GPOOFF 0x56

byte newByte;
boolean cmdComplete = false;

void setup(){
  pinMode(2, OUTPUT);                // Set GPO pins to output
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);

  Serial.begin(9600);                // Setup the serial port


  lcd.print("The LCD is Ready");     // Display ready text
  lcd.setCursor(0, 1);
  lcd.print(" Firmware  v1.0 ");

  for (int i=2; i <= 7; i++){        // Turn off the GPO LEDs in turn
    delay(250);
    digitalWrite(i, HIGH);
  }
 
  lcd.clear();                       // Clear the LCD ready for use
}


void loop(){
  checkCommand();                    // Check to see if theres a new byte to process
}









void checkCommand(){
  if (Serial.available()) {         // If theres a new byte
    newByte = Serial.read();        // Buffer the byte

    if(newByte == COMMAND){         // If the byte is a command
      cmdComplete = false;          // Set the command complete flag false
      doCommand();                  // Work out what to do with the command
    }
    else{
      lcd.write(newByte);           // else write the byte to the LCD
    }
  }
}



void doCommand(){
  while (cmdComplete == false){     // While a command is not complete do the loop
    if (Serial.available()) {       // If theres a new byte
      newByte = Serial.read();      // Buffer the byte

// ********* Clear Screen *********

      if(newByte == CLEARSCREEN){   // If byte is Clear Screen
        lcd.clear();                // Clear the screen
        cmdComplete = true;         // Command is complete
      }
      
      
// ********* Cursor To *********

      if(newByte == CURSORTO){      // If byte is cursor to
        int x;                      // Make somewhere to store the coords
        int y;
        boolean doneX = false;      // Make somewhere to store flags
        boolean doneY = false;

        while (doneX == false){     // While waiting for row byte
          if (Serial.available()) { // If theres a new byte
            x = Serial.read();      // Put it in x
            doneX = true;           // row byte complete
          }
        }

        while (doneY == false){     // While waiting for col byte
          if (Serial.available()) { // If theres a new byte
            y = Serial.read();      // Put it in y
            doneY = true;           // col byte complete
          }
        }

        lcd.setCursor(x, y);        // Set the cursor position
        cmdComplete = true;         // Command is complete
      }
      
      
// ********* Go Home *********

      if(newByte == GOHOME){        // If byte is cursor to
        lcd.home();                 // Set cursor to home position
        cmdComplete = true;         // Command is complete
      }


// ********* Turn GPO On *********

      if(newByte == GPOON){         // If byte is GPO ON
        int gpo;                    // Make somewhere to store the current GPO
        boolean doneGPO = false;    // Make somewhere to store GPO done flag

        while (doneGPO == false){   // While waition for GPO number
          if (Serial.available()) { // If theres a new byte
            gpo = Serial.read();    // Store GPO number
            doneGPO = true;         // Stored GPO
          }
        }
        if (gpo > 5 || gpo < 0){    // If the GPO number is illegal
          cmdComplete = true;       // Command is complete
          break;                    // Exit function
        } 
        gpo = gpo + 2;              // Adjust GPO number to match Arduino pin
        digitalWrite(gpo, LOW);     // Write GPO pin
        cmdComplete = true;         // COmmand is complete
      }
      
      
// ********* Turn GPO Off *********

      if(newByte == GPOOFF){        // If byte is GPO OFF
        int gpo;                    // Make somewhere to store the current GPO
        boolean doneGPO = false;    // Make somewhere to store GPO done flag

        while (doneGPO == false){   // While waition for GPO number
          if (Serial.available()) { // If theres a new byte
            gpo = Serial.read();    // Store GPO number
            doneGPO = true;         // Stored GPO
          }
        }
        if (gpo > 5 || gpo < 0){    // If the GPO number is illegal
          cmdComplete = true;       // Command is complete
          break;                    // Exit function
        }  
        gpo = gpo + 2;              // Adjust GPO number to match Arduino pin
        digitalWrite(gpo, HIGH);    // Write GPO pin
        cmdComplete = true;         // COmmand is complete
      }
    }
  }
}

The layout in Eagle is a bit messy, still not quite got the hang of it, but you can make out the connections alright.

Arduino pin numbering connections are:

LCD  Arduino:
RS   9
RW   10
E    11
D0   12
D1   13
D2   A0 / 14
D3   A1 / 15
D4   A2 / 16
D5   A3 / 17
D6   A4 / 18
D7   A5 / 19

GPO  Arduino:
0    2
1    3
2    4
3    5
4    6
5    7

I chose those pins as the LCD pins run down one side of the chip making the connection on a single sided PCB much easier, also the analogue inputs aren’t needed for this project

I have stuck to the Matrix Orbital commands so far, since thats the Serial LCD I tend to use. :slight_smile: