SparkFun SerLCD Interfacing

It wasn't immediately apparent how to interface with the Sparkfun Serial enabled lcds So it seemed worth a quick writeup.

NOTE: If you just want to use the LCD display, you may be looking for the libraries here http://playground.arduino.cc/Code/SerLCD

First, obtain and read this documentation from sparkfun: http://www.sparkfun.com/datasheets/LCD/SerLCD_V2_5.PDF

The thing that I was hung up on most was the fact that Serial.print(0xFE, HEX); does not send 11111110 across the line, it was apparently sending "0xFE" in ASCII (and my LCD was printing it out)

So, instead, you need to use: Serial.write(0xFE); in order to send sparkfun's command flag in a format that the SerLCD microcontroller can understand.

Interfacing boils down to this. Whatever you send over Serial.print() gets printed out on the LCD. The exceptions are 2 command flags, 0xFE and 0x7C. 0xFE is for things like cursor positioning, and clearing the LCD (See: 3.3 in the sparkfun doc). 0x7C is for things like, changing the backlight brightness, and turning the lcd on and off.

Code

With all that said, here is my code to get you started: (with an edit by wbp to put the delay in the functions instead of in the calling code)

void setup()
{
  Serial.begin(9600);
  backlightOn();
}

void loop()
{  
  selectLineOne();
  Serial.print(millis());
  selectLineTwo();
  Serial.print(millis()/2);
  delay(100);
}

void selectLineOne(){  //puts the cursor at line 0 char 0.
   Serial.write(0xFE);   //command flag
   Serial.write(128);    //position
   delay(10);
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
   Serial.write(0xFE);   //command flag
   Serial.write(192);    //position
   delay(10);
}
void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
if (position<16){ Serial.write(0xFE);   //command flag
              Serial.write((position+128));    //position
}else if (position<32){Serial.write(0xFE);   //command flag
              Serial.write((position+48+128));    //position 
} else { goTo(0); }
   delay(10);
}

void clearLCD(){
   Serial.write(0xFE);   //command flag
   Serial.write(0x01);   //clear command.
   delay(10);
}
void backlightOn(){  //turns on the backlight
    Serial.write(0x7C);   //command flag for backlight stuff
    Serial.write(157);    //light level.
   delay(10);
}
void backlightOff(){  //turns off the backlight
    Serial.write(0x7C);   //command flag for backlight stuff
    Serial.write(128);     //light level for off.
   delay(10);
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  Serial.write(0xFE);
}

That code starts off with the backlight on, then on each loop it displays the current millisecond count on the top line, and millis()/2 on the bottom line. (just because i wanted different values.)

So, cursor positioning is rather trivial once you figure out how to send the command. To get to line 1, character 0 you just send:

   Serial.write(0xFE);   //command flag
   Serial.write(128);    //position

and to get to line 2 character 0 you just add 64 to 128.

The delays in loop() needed to be placed there because if the commands got too close together, the LCD seemed to just go blank. I imagine they could be massaged and troubleshot further so the execution time could be reduced. This would be sufficient for displaying an analog pin's value though.

Physical Setup

As you can see I was just sending through the arduino's TX pin. This works fine in practice, but you may want to be sure to unplug it during code uploading, otherwise the LCD gets spammed with data, and it could potentially mess with it's configuration. (for instance, if it receives a 0x7C followed by some random integer.) Using the SoftwareSerial library is one way to avoid that...

Using SoftwareSerial with serLCD

The code below assumes the RX pin on the serLCD is connected to digital pin 2 on the Arduino.

Code:

#include <SoftwareSerial.h>

#define txPin 2

SoftwareSerial LCD = SoftwareSerial(0, txPin);
// since the LCD does not send data back to the Arduino, we should only define the txPin
const int LCDdelay=10;  // conservative, 2 actually works

// wbp: goto with row & column
void lcdPosition(int row, int col) {
  LCD.write(0xFE);   //command flag
  LCD.write((col + row*64 + 128));    //position 
  delay(LCDdelay);
}
void clearLCD(){
  LCD.write(0xFE);   //command flag
  LCD.write(0x01);   //clear command.
  delay(LCDdelay);
}
void backlightOn() {  //turns on the backlight
  LCD.write(0x7C);   //command flag for backlight stuff
  LCD.write(157);    //light level.
  delay(LCDdelay);
}
void backlightOff(){  //turns off the backlight
  LCD.write(0x7C);   //command flag for backlight stuff
  LCD.write(128);     //light level for off.
   delay(LCDdelay);
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  LCD.write(0xFE);
}

void setup()
{
  pinMode(txPin, OUTPUT);
  LCD.begin(9600);
  clearLCD();
  lcdPosition(0,0);
  LCD.print("Hello world!");
}

void loop()
{
}

SparkFun 4 x 20 serLCD code

The above code was tremendously useful getting started with SparkFun's 4x20 serial LCD. I had some syntax errors trying to use it as-is, but I'm afraid I didn't keep track of the edits I made to get it to compile. I also changed/added the line and positioning code for the four-line module, and some more calls of the functions in the loop, so I could be sure everything I added was working. It should be reasonably simple to modify for use with a 4x16 module.

Code:

void setup() {
Serial.begin(9600);
}

void loop() {
// Example usage:
clearLCD();
backlightOn();
//Print text on each line
selectLineOne();
delay(100);
Serial.print("Line One");
delay(500);
selectLineTwo();
delay(100);
Serial.print("Line Two");
delay(500);
selectLineThree();
delay(100);
Serial.print("Line Three");
delay(500);
selectLineFour();
delay(100);
Serial.print("Line Four");
delay(500);

//print a character at the end of each line:
goTo(19);
delay(100);
Serial.print("*");
goTo(39);
delay(100);
Serial.print("*");
goTo(59);
delay(100);
Serial.print("*");
goTo(79);
delay(100);
Serial.print("*");

delay(500);
backlight50();
delay(500);
backlightOff();
delay(500);

}
//SerialLCD Functions
void selectLineOne(){  //puts the cursor at line 0 char 0.
   Serial.write(0xFE);   //command flag
   Serial.write(128);    //position
}
void selectLineTwo(){  //puts the cursor at line 2 char 0.
   Serial.write(0xFE);   //command flag
   Serial.write(192);    //position
}
void selectLineThree(){  //puts the cursor at line 3 char 0.
   Serial.write(0xFE);   //command flag
   Serial.write(148);    //position
}
void selectLineFour(){  //puts the cursor at line 4 char 0.
   Serial.write(0xFE);   //command flag
   Serial.write(212);    //position
}
void goTo(int position) { //position = line 1: 0-19, line 2: 20-39, etc, 79+ defaults back to 0
if (position<20){ Serial.write(0xFE);   //command flag
              Serial.write((position+128));    //position
}else if (position<40){Serial.write(0xFE);   //command flag
              Serial.write((position+128+64-20));    //position 
}else if (position<60){Serial.write(0xFE);   //command flag
              Serial.write((position+128+20-40));    //position
}else if (position<80){Serial.write(0xFE);   //command flag
              Serial.write((position+128+84-60));    //position              
} else { goTo(0); }
}
void clearLCD(){
   Serial.write(0xFE);   //command flag
   Serial.write(0x01);   //clear command.
}
void backlightOn(){  //turns on the backlight
    Serial.write(0x7C);   //command flag for backlight stuff
    Serial.write(157);    //light level.
}
void backlightOff(){  //turns off the backlight
    Serial.write(0x7C);   //command flag for backlight stuff
    Serial.write(128);     //light level for off.
}
void backlight50(){  //sets the backlight at 50% brightness
    Serial.write(0x7C);   //command flag for backlight stuff
    Serial.write(143);     //light level for off.
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  Serial.write(0xFE);
}

Share