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 https://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.
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.
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...
The code below assumes the RX pin on the serLCD is connected to digital pin 2 on the Arduino.
#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() { }
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.
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); }