Arduino and the LCD Breakout Board

The Color LCD Breakout Board, from SparkFun, is good starting point for experimenting with Arduino peripherals. It has two switches, a tri-color LED, and a 128x128 color LCD. The parts on the board are designed to work at 3.3v, so it also provides an opportunity to look at level-shifting between 5v and 3.3v.

While I won't describe the process, I also used this exercise to try out Fritzing. Fritzing is a program for drawing connection diagrams and turning them into schematics and PCB layouts. It is a good way to create nice looking connection diagrams (top image to the left). The latest version for Linux, OSX, or MS-Windows, can be downloaded from the Fritzing Download page.

There are three parts to this exercise. First we'll get the LED working, then connect up the switches, and finally setup and write to the LCD.

Resources

In addition to an Arduino (I used an Arduino UNO) and the Color LCD Breakout Board, you will need:

You can get the source code for the sketches from GitHub.

There is a lot more information about the LCD itself , but it is not referenced from the SparkFun page for this Color LCD Breakout Board. Instead check out the links on the SparkFun Color LCD 128x128 Nokia Knock-Off page.

Preparations

You should have the Arduino IDE setup and configured on your computer. For the sketches below you will need version 1.0 or newer. I used version 1.0.3.

The description here will use Linux (Ubuntu) references and file locations, but you should be able to follow along using any Arduino supported OS.

You will need to add header pins or wires to the  Color LCD Breakout Board in order to connect it to the solderless breadboard. I chose to add header pins and remove two of the standoffs so that I could plug it directly in to the breadboard.

Connections
Figure 1: Connection Diagram

Tri-Color LED

First we will hook up the Tri-Color LED and flash each of the colors.

license here

The schematic shows that the anodes of the diodes are connected to 3.3v and that there are limiting resistors on the board. Since the Arduino UNO is a +5v device the LED will be reverse-biased (3.3 - 5 = -1.7v) when the output from the Arduino UNO is high.  We don't have a part number for the LED so we can not look up the maximum rating, but it is typically several volts (LEDs have lower reverse bias limits than other diode types) so it should be OK for us to hook the STAT0-3 signals directly to the Arduino UNO.

We only need a few of the connections shown in Figure 1:
  • Ground: black wires
  • +3.3v: green wires
  • LED: blue wires
    • STAT0 to Pin 2
    • STAT1 to Pin 3
    • STAT2 to Pin 4
If the connections are correct, this sketch will flash the three components of the LED on, one at a time:

/*
 * LED Blink
 * Turns the RGB LEDs on the LCD Breakout board on/off.
 */
 
// Identify the LED connections
int ledRed = 2;   // RED
int ledBlue = 3;  // BLUE
int ledGreen = 4;  // GREEN
int ledOFF=HIGH;
int ledON=LOW;

// the setup routine runs once when you press reset:
void setup() {               
  // turn the leds off and then set the pins as outputs so that
  // there is no pulse during startup.
  digitalWrite(ledRed, ledOFF);
  digitalWrite(ledBlue, ledOFF);
  digitalWrite(ledGreen, ledOFF);
  pinMode(ledRed, OUTPUT);    
  pinMode(ledBlue, OUTPUT);    
  pinMode(ledGreen, OUTPUT);    
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(ledRed, ledON);
  delay(1000);               // wait for a second
  digitalWrite(ledRed, ledOFF);
  digitalWrite(ledBlue, ledON);
  delay(1000);               // wait for a second
  digitalWrite(ledBlue, ledOFF);
  digitalWrite(ledGreen, ledON);
  delay(1000);               // wait for a second
  digitalWrite(ledGreen, ledOFF);
}

If your are using the code from GitHub and have installed it in your sketchbook directory, then you will find the sketch in the open menu as LED_Exercises->LED_Blink

Switches

Hook up the switches next.


From the schematic we see that switches short the S1 and S2 signals directly to ground. A pull-up resistor is needed so that the S1 and S2 signals are high when the switches are open. Since the signals are not used anywhere else, the internal pull-up resistors in the CPU on the Arduino will work just fine.

The test sketch for this section will turn the LED on when the switches are pressed, so in addition to the hookup listed above, we need two connections (purple wires in Figure 1 above):

  • S1 to Pin 5
  • S2 to Pin 6
This sketch will turn on the LED as follows (P=pressed):

 SW1   SW2  Red  Green  Blue
         
 P    On    
   P    On  
 P  P      On

/*
 * SwitchTest
 *
 * Test the switches on the LCD Breakout board.
 *
 * SW1 => RED LED On
 * SW2 => GREEN LED On
 * SW1+SW2 => BLUE LED On
 *
 *   Requires Arduino 1.0.1 or newer due to the use of INPUT_PULLUP.
 *   Requires Bounce library from the Playground:
 *     http://playground.arduino.cc//Code/Bounce
 *
 */
#include <Bounce.h>

// Identify the connections
const int ledRed = 2;
const int ledBlue = 3;
const int ledGreen = 4;

const int buttonSW1 = 5;
const int buttonSW2 = 6;

// Identify LED states
const int ledOFF = HIGH;
const int ledON = LOW;

// Switch states
const uint8_t SWPressed = LOW;
const uint8_t SWReleased = HIGH;

// Set options
const unsigned long interval_ms = 5;

// debounced switches
Bounce sw1 = Bounce(buttonSW1, interval_ms);
Bounce sw2 = Bounce(buttonSW2, interval_ms);

void setup() {
  // Use Arduino's built-in pullups rather than external resistors.
  pinMode(buttonSW1, INPUT_PULLUP);
  pinMode(buttonSW2, INPUT_PULLUP);

  // Assume the switches are not pressed when the sketch starts
  sw1.write(SWReleased);
  sw2.write(SWReleased);

  // turn the leds off and then set the pins as outputs so that
  // there is no pulse during startup.
  digitalWrite(ledRed, ledOFF);
  digitalWrite(ledBlue, ledOFF);
  digitalWrite(ledGreen, ledOFF);
  pinMode(ledRed, OUTPUT);    
  pinMode(ledBlue, OUTPUT);    
  pinMode(ledGreen, OUTPUT);    
}

void loop() {
  sw1.update();
  sw2.update();

  if ((sw1.read() == SWPressed) && (sw2.read() == SWPressed))
  {
    digitalWrite(ledRed, ledOFF);
    digitalWrite(ledGreen, ledOFF);
    digitalWrite(ledBlue, ledON);
  }
  else if (sw1.read() == SWPressed)
  {
    digitalWrite(ledRed, ledON);
    digitalWrite(ledGreen, ledOFF);
    digitalWrite(ledBlue, ledOFF);
  }
  else if (sw2.read() == SWPressed)
  {
    digitalWrite(ledRed, ledOFF);
    digitalWrite(ledGreen, ledON);
    digitalWrite(ledBlue, ledOFF);
  }
  else
  {
    digitalWrite(ledRed, ledOFF);
    digitalWrite(ledGreen, ledOFF);
    digitalWrite(ledBlue, ledOFF);
  }

}

If your are using the code from GitHub and have installed it in your sketchbook directory, then you will find the sketch in the open menu as LED_Exercises->SwitchTest

Color LCD

Getting the LCD hooked up and working is a bit more complicated. The issues include:
  1. +3.3v to +5v level translation.
  2. The LCD controller must be identified.
  3. The display may need to be aligned.
Item 2 will be addressed by the  gLCD library written and maintained by Tom Carpenter. Alternative libraries are can be found on the SparkFun product pages for the breakout board and the bare LCD. I chose Tom's because it is well documented and he is actively maintaining and improving the library.

+3.3v to +5v Level Translation

Since all the signals are unidirectional, level translation is straight forward and can be easily handled by a suitable buffer. The 74HC4050 Hex Non-Inverting Buffer is inexpensive and easy to use. We power the chip using the lower voltage (+3.3v) and then use one of the 6 buffers for each of the four (4) signals:
  • 74HC4050:1 to +3.3v, blue wire
  • 74HC4050:8 to GND, black wire
  • Ardino Pin 8 to 74HC4050:3, yellow wire
  • Ardino Pin 9 to 74HC4050:5, yellow wire
  • Ardino Pin 11 to 74HC4050:7,yellow wire
  • Ardino Pin 13 to 74HC4050:9,yellow wire
  • 74HC4050:2 to RESET, orange wire
  • 74HC4050:4 to CS, orange wire
  • 74HC4050:6 to DIO, orange wire
  • 74HC4050:10 to SCK, orange wire
  • +5V to VBATT, red wire
The wire colors are those shown in Figure 1, above, and the notation 74HC4050:N identifies pin N of the 74HC4050.


Install gLCD Library

The Arduino IDE expects libraries to be installed in specific locations based on the name of the library and the way it will be referenced in the code. The files that make up the  gLCD library need to be located in the $HOME/sketchbook/libraries/gLCD/ directory. These command will download and install the version 3.4 (the one I used) of the library:

$  wget "https://github.com/TCWORLD/gLCD-Library/blob/master/Downloads/gLCD%20v3_4.zip?raw=true" -O /tmp/gLCD.zip
$ cd ~/sketchbook/libraries/
$ unzip /tmp/gLCD.zip

If the Arduino IDE was running, restart it. Look for gLCD under libraries:


Tom has included three example sketches with the library. These should work on with the Color LCD Breakout Board using the connections described above. When you are ready, read these sketches carefully to learn more about the how to use this versatile library. If you have trouble getting the LCD portion of the Color LCD Breakout Board working, Tom's example sketches are the best place to start looking for solutions.


LCD Setup and Alignment

While the example sketches included in the gLCD library are a great place to start, the following simplified sketch is the reference for the rest of this exercise.

/*
 * gLCD_test - Check configuration for SparkFun Color LCD Breakout
 *
 * Verify setup for use with gLCD-Library by drawing squares at
 * different distances from the edge of the display.
 *
 * Requires gLCD library from https://github.com/TCWORLD/gLCD-Library
 * Tested with gLCD version 3.4
 */
#include <gLCD.h>

// allocate pins for each function
const char RST = 8;
const char CS = 9;
const char Clk = 13;
const char Data = 11;

gLCD graphic(RST, CS, Clk, Data, HIGH_SPEED);

// Screen offset and size
// - Adjust Xoffset/Yoffset until boxes start in the top left corner of
//   the screen
//
// - Then if blue is visible outside the Red box, adjust the Xmax,Ymax
//   values.
//
// Repeat until all four edges of the Red box are visible and there is
// no blue showing outside the Red box.
const int Xoffset = 2;
const int Yoffset = 0;
const int Xmax = 129;
const int Ymax = 129;

void setup() {
  // See gLCD/examples/BasicFunctions.pde for driver options
  // (EPSON/PHILLIPS)
  //
  // Set the rotation based on the LCD 'tab' location:
  //    Top: ROTATION_0
  // Bottom: ROTATION_180
  //  Right: ROTATION_90
  //   Left: ROTATION_270
  graphic.begin(Xoffset, Yoffset, 0, EPSON, ROTATION_180);

  // Draw boxes around the edge of the screen
  graphic.setForeColour(15, 0, 0);   // Red
  graphic.Box(0, 0, Xmax, Ymax,6);

  graphic.setForeColour(15, 15, 15); // White
  graphic.Box(1, 1, Xmax-1, Ymax-1, 6);

  graphic.setForeColour(0, 15, 0);   // Green
  graphic.Box(2, 2, Xmax-2, Ymax-2, 6);

  graphic.setForeColour(15, 15, 15); // White
  graphic.Box(3, 3, Xmax-3, Ymax-3, 6);

  // Write a welcome message at the center of the screen
  graphic.setForeColour(0,15,0);
  graphic.setBackColour(15,0,0);
  graphic.setFont(Normal_SolidBG);
  graphic.setCoordinate(Xmax/2, Ymax/2);
  graphic.print("Hello");

  // Mark the center of the screen
  graphic.setForeColour(15,15,15);
  graphic.Line(0, 0, Xmax, Ymax, SolidForeColour);
  graphic.Line(0, Ymax, Xmax, 0, SolidForeColour);

}


void loop() {
  // Nothing to do
  while(1)
  {
    delay(1000);
  }
}


Here is what you should see on the LCD after uploading the sketch:

gLCD test display
Figure 2, gLCD_test sketch

Identify the LCD Controller


The Color LCD Breakout Board can come with either an Epson or a Phillips LCD Controller. It is not possible to determine the controller by visual examination and, since there are no output signals from the LCD Controller, it is not possible to determine the controller automatically. That leaves trial and error.

There are two lines in the sketch that you might have to change:

gLCD graphic(RST, CS, Clk, Data, HIGH_SPEED);

and more likely,

  graphic.begin(Xoffset, Yoffset, 0, EPSON, ROTATION_180);

If you don't see anything like the display in Figure 2, the try the following:
  • Change HIGH_SPEED to NORMAL_SPEED in the first line.
If that doesn't work, then,
  • Change EPSON to PHILLIPS_1 in the second line.
If the second change (EPSON to PHILLIPS_1) works, then you should try setting the first line back to HIGH_SPEED (NORMAL_SPEED is really quite slow).

Should those two simple changes not work, then you will need to read the setup comments in the gLCD library examples for other configuration options.


LCD Alignment

There are three adjustments to make; rotation, offset and max size. Rotation is obvious and straight forward. The value in this line

  graphic.begin(Xoffset, Yoffset, 0, EPSON, ROTATION_180);

is for the way I have the LCD breakout board plugged into the breadboard. Other valid rotation values are: ROTATION_0, ROTATION_90, and ROTATION_270.

The offset and max size are a bit more finicky. I suggest modifying the offset values first. Also note that I observed some problems with the display clear and filling large rectangles when the sum of the offset and the max pixels exceeded 131. So you may need to reduce the max values while adjusting the offsets.

const int Xoffset = 2;
const int Yoffset = 0;
const int Xmax = 129;
const int Ymax = 129;

The offset values set the position of the top left corner on the display. The outermost box is in red, so adjust the offsets until the top left pixel is red.

Once the offsets have been set, set the max values. The goal is to have a red box all the way around the display with no blue pixels outside the box. You might want to use a magnifying glass!

Wrap-up

At this point you have checked out all the devices on the breakout board and you are ready to put it to use. What you use it for is up to your imagination- I'm thinking about a waterfall display for a software defined radio.

Feedback

I have a group on Google+, join up and let me know what you think about this exercise.

Comments