Easy LCD serial communication.

Hello!

Without searching around for anything similar I developed a basic 'protocol' that allows you to control your LCD effectively by using basic serial commands.

With this snippet of code you can:

  • Software Reset
  • Turn digital pins on/off options: pin, status
  • Scroll the LCD, options: characters, speed
  • Set the X cursor option: location
  • Choose which LCD line to use. option: line
  • Clear the screen.
  • Write text just by sending it over serial

This software uses basic characters to communicate - but that doesn't mean the characters it uses can't be displayed.

To start command mode, send a ` then the command key, then send the command finish character which is #. Any options come after the hash.

If you want to display the character ` simply send it twice, the second time exits command mode and displays the character.

Example commands:

Write 'Hi' over serial: Hi
Clear: C#** Reset: **R#
Cursor position: X#n** // Set curosr position on current line, 10 places out. Line select: **L#2 // Jump to LCD Line 2
Scroll LCD: S#x2** // Scrolls 20 characters at 500m/s each. Pin status: **P#qe // Pin 13 HIGH

the last example has options q and e, looking q and e up in the ASCII chart (Decimal) you'll see q is 113, and e is 101.

The software minuses 100 from the values to give 13 and 1. This example sets Pin13 to the status 1 (HIGH).

(This is because 0 to 31 couldn't be used becuase I was using Arduino IDE Serial monitor and couldn't send "NUL", "SOH", "STX", etc.)

But hey, I'm going to use this to display basic information like winamp etc, this is going to help me I just hope it saves anyone else a bit of time!

Also; if your LCD has more than 2 Lines, this isn't a problem and only minor changes have to be made.

I built this for the 4BIT library for the HD47780, but as you can see it would be easily ported to anything else, I've done basic testing and it works my use.

NOTE: Because it uses the ASCII table commands ARE case sensitive.

#include <LCD4Bit_mod.h> 
LCD4Bit_mod lcd = LCD4Bit_mod(2); 

int incomingByte;
int CommandBuffer[2];
boolean ON = 0;
boolean CommandMode = 0;
boolean clearBugFix = 0;
boolean PrintByte = 1;
boolean currentLine = 0;

void setup() { 
  Serial.begin(9600);
  lcd.init();
  lcd.clear();    
 
  for (int i=0; i<13; i++){ 
    if (!i == 10){
      pinMode(i, OUTPUT);
    }
  }
}

void loop() {
  listen();
}

void Reset(){
  
  int incomingByte;
  int CommandBuffer[2];
  boolean ON = 0;
  boolean CommandMode = 0;
  boolean clearBugFix = 0;
  boolean PrintByte = 1;
  boolean currentLine = 0;
  
  lcd.init();
  lcd.clear();    
 
  for (int i=0; i<14; i++){ 
    if (!i == 10){
      pinMode(i, OUTPUT);
    }
  }
  
 int i = 0;
 while(i < 14){
        digitalWrite(i, LOW);
        if (i = i + 1 == 10){
          i = i + 1;
    }
 }
}

void ClearCommandBuffer(boolean clearCallBack=0, boolean PrintIByte=1){
  for(int i=0; i<2; i++){
    CommandBuffer[i] = 0;
  }
   
  if (clearCallBack){
     clearBugFix = 1;
  }else if(!PrintIByte){
    PrintByte = 0;
  }else{
    incomingByte = 32;
  }
}

void listen(){
    if (Serial.available() > 0) {
        incomingByte = Serial.read();
        
        switch (incomingByte){    
          case 96: // ` is the command byte
             CommandBuffer[0] = 96;   
             if(CommandMode){
                CommandMode = false;           
             }else{
                CommandMode = true;
             }
          break;
          
          case 35: // # is the finsih command byte
            if(CommandBuffer[0] == 96){
              switch (CommandBuffer[1]){
                     case 67: // 'C' for clear
                       ClearCommandBuffer(1);
                       lcd.clear();
                     break;
                     
                     case 76:{ // L for line select
                       ClearCommandBuffer(0, 0);
                       int L = 0;
                       while (!L) {
                          L=Serial.available();
                       }
                          L=Serial.read();
                          Serial.println(L);
                          switch (L){
                             case 49:
                               lcd.cursorTo(1, 0);
                               currentLine = 0;
                             break;
                             
                            case 50:
                              lcd.cursorTo(2, 0);
                              currentLine = 1;
                            break; 
                          }
                     }
                     break;
                     
                     case 82: // R for softwareReset
                       ClearCommandBuffer();
                       Reset();
                     break;  
                     
                     case 80:{ // P for pinselect
                       ClearCommandBuffer(0, 0);
                       int Pin = 0;
                       int Status = 0;
                       
                       while (!Pin) {
                          Pin=Serial.available();
                       }
                       
                        Pin=Serial.read();
                        Serial.println(Pin);
                        Pin = Pin - 100;
                        
                        if (Pin <= 13 && Pin >= 2){
                          while (!Status) {
                            Status=Serial.available();
                         }
                           Status=Serial.read();
                           Status = Status - 100;
                           digitalWrite(Pin, Status);
                        }
                     }
                      break;
                    
                     case 88:{ // X for X cursor
                       ClearCommandBuffer();
                       int X = 0;
                       while (!X) {
                          X=Serial.available();
                       }
                          X=Serial.read();
                          Serial.println(X);
                          X = X - 100;
                          
                          if (currentLine == 0){
                            lcd.cursorTo(1, X);
                          }else{
                            lcd.cursorTo(2, X);
                          }  
                     }
                     break;    
                    
                    case 83:{ // S for scroll
                     ClearCommandBuffer();
                     int S = 0;  
                     int B = 0;                   
                     while (!S) {
                          S=Serial.available();
                     }
                       
                     S=Serial.read();
                     Serial.println(S);
                     S = S - 100;
                     
                     while (!B){
                         B=Serial.available();
                     }
                     
                     B=Serial.read();
                     B = B * 10;
                       lcd.leftScroll(S, B); 
                    }
                    break; 
                     
                 }
                 CommandMode = false;
   
           }
         break;
     }
    
       if (CommandMode == true){
        CommandBuffer[1] = incomingByte;
       }else{
        Serial.println(incomingByte);
        if (clearBugFix == 1){
          lcd.cursorTo(1, -1);
          clearBugFix = 0;
        }else if (!PrintByte){
          PrintByte = 1;
        }else{
          lcd.print(incomingByte);
        }          
       }
   }
}