SparkFun will be closed on Tuesday, December 24th, and Wednesday, December 25th, in observance of the Christmas holiday. Any orders qualifying for same day shipping placed after 2:00 p.m. (MST) on Monday, December 23rd, will be processed on Thursday, December 26th, when we return to regular business hours. Wishing you a safe and happy holiday from all of us at SparkFun!
Please note - we will not be available for Local Pick up orders from December 24th-December 27th. If you place an order for Local Pick-Up we will have those ready on Monday, December 30th.
Looking for an Arduino shield with a little extra zest? Something to add color to that drab Arduino-blue? Look no further than the Color LCD Shield! The Color LCD Shield includes everything you need to add a 132x132 pixel, color display to your Arduino.
The purpose of this quick start guide is to get your Color LCD Shield from zero to nifty, as quickly as possible. We'll touch on assembly, and then we'll go straight into some example code. Want to turn your LCD Shield into a clock? Stay tuned...
To assure that there's a solid electrical connection between the Color LCD Shield and your Arduino, you'll need to solder headers onto the shield. Thus, in addition to the shield and headers, you'll also need some soldering tools. The most basic of soldering irons and solder should do just fine. It's pretty basic soldering.
Oh, and, of course, you'll need an Arduino. The standard Arduino Uno is recommended, though older versions should work as well.
Looking at the Shield, it may seem like it's got a lot going on, but it's really a pretty simple board. There's the LCD, a knock off Nokia 6100 screen. Below and to the left of the LCD are an IC and some passive components whose sole purpose in life is boosting 5V to about 7V, which is required to illuminate the LCD's backlight. Finally, to the right of the boost circuit are a few momentary push-buttons for use as...buttons.
LCD Pin | Arduino Pin |
---|---|
Reset (RES) | 8 |
Chip-select | 9 |
Data in/out (DIO) | 11 |
Serial Clock (SCK) | 13 |
If you're using the Color LCD Shield with other shields or components, be wary of sharing these pins. You should be safe if you want to set up an SPI bus, using the DIO and SCK pins, but the other two pins should not be shared with any other devices. Also, be aware that the buttons are connected to pins 3, 4, and 5.
When you first receive the Shield, the LCD should be covered with a protective sticker. Don't toss this in the garbage bin just yet, and put on your detective hat. You see, one of the more irritating things about this display is we don't always initially know what makes it tick. Embedded into each display is a driver, which is really what controls these LCDs. The driver turns a simple 3-wire serial signal -- something we can easily send with an Arduino -- into a HUGE set of outputs (upwards of 500 pins). Our displays come with two possible driver options: an Epson S1D15G00 or a Philips PCF8833. If you've got a red tab on your protective sticker, it's most likely an Epson, a blue tab is usually indicative of the Phillips driver. File which display you have into the back of your mind because we'll need it again. There are some minor differences between the drivers, but in the end they'll both display the same thing.
Before we get into full-blown play-time mode, a word of caution. Hopefully you've received the Color LCD Shield in one piece (not including those little headers), and, if so, I'm guessing you want to keep it that way. The LCD should be well-secured to the board with some double-sided tape, but if it's moving around, do what you can to pin it to the board. The LCD's little connector is pretty fragile, and if it wiggles around too much, it's bound to rip off. Take my word, and be gentle with the LCD.
Now, on to assembly. There's not much to this. You've got four headers, and their home-to-be should be pretty unmistakable. Just don't stick the 6-pin headers into the 8-pin socket, and you should be fine.
If you've never soldered before, don't fret! This is a great place to start. Though, I'd recommend reading over our excellent soldering tutorials beforehand.
When you're soldering the headers onto the shield, try to keep them as flush as possible with the board. You want the shield to be able to plug straight into the Arduino, and bent headers aren't very conducive to that. Make sure you insert the headers on the top side of the board (the one with the white print on it), and solder to the bottom side.
If this isn't your first shield, I'd recommend using an older shield to help keep your Color LCD Shield headers as straight as possible. Before soldering, you can plug the older shield into the Color LCD Shield. This will keep the unsoldered headers in place, and (assuming the headers in your other shield are straight) will make sure you're installing them flat against the board.
If you haven't done so already, download and install the Arduino IDE. Their site should have all the information you need to get rolling.
Are you stressing out about how you're going to communicate with the LCD's driver? Don't. I've got you covered. The Nokia 6100 LCD has been around for a long while, and the example code for it has piled up. Just check the documents section on its product page. I've compiled some of the better examples into an Arduino library that should make it super-simple to use the LCD. Huge thanks to Jim Lynch, Mark Sproul, Peter Davenport and no doubt countless others who've funneled this code to where it is now.
You can download the Arduino library from its github home. To install the library, simply unzip it into your Arduino libraries folder, which is in your Arduino sketchbook folder. If you're on a PC, this is usually C:\Users\username (Windows 7/8) or C:/Documents and Settings/username/My Documents (XP). If you're having trouble installing the library, Arduino's site explains it in further detail.
The library is filled with functions that draw all sorts of shapes or characters, but before you can do any of that you must initialize the LCD. Any sketch that uses the Color LCD Shield should include the following bits of code:
// Color LCD Shield library#include <ColorLCDShield.h> LCDShield lcd; // Creates an LCDShield, named lcd void setup() { lcd.init(PHILIPS); // Initializes lcd, using an PHILIPS driver lcd.contrast(-51); // 40's usually a good contrast value lcd.clear(TEAL); // oooh, teal! } void loop() { }
If you upload that to your Arduino, it should clear your screen to a cool teal color. If it doesn't work, try substituting EPSON for PHILIPS in the lcd.init() function. Remember our talk about LCD drivers, that's where that info will come in handy.
Now, try clearing the screen to other colors., or adjusting the contrast. The predefined colors are (don't forget all caps): BLACK, NAVY, BLUE, TEAL, EMERALD, GREEN, CYAN, SLATE, INDIGO, TURQUOISE, OLIVE, MAROON, PURPLE, GRAY, SKYBLUE, BROWN, CRIMSON, ORCHID, RED, MAGENTA, ORANGE, PINK, CORAL, SALMON, ORANGE, GOLD, YELLOW, WHITE, PALEROYALCORNFLOWERBLUE. OK, maybe not that last one. I had some fun making colors...
However, don't let those defined colors limit your color spectrum, the LCD uses 12-bit RGB values to define colors, which means there are 4096 possible colors. Rather than sending one of the predefined color values, try putting a 12-bit value into the clear function; pick three hex digits (0-F), and arrange them as 0x123 (replacing 1, 2, and 3). The first value is the amount of red you want, the middle value is green, and the last value is blue.
Note: If you have a PHILLIPS LCD, the colors may be all wonky (this was hopefully fixed with a recent library update). That's because the Phillips LCD reads 12-bit colors as BGR, so red and blue may be swapped.
Well, that's fun, but I'm guessing you want more than just a multicolored night-light. How about some shapes?! But first: coordinates. The Nokia 6100 LCD is a 132x132 pixel screen. The origin (0, 0 point) of the screen is on the top-right side of the board. There's an x-axis and a y-axis, to pinpoint any of the 17424 pixels. Confused? Check the diagram:
You can't see the first or last rows/columns, so imagine that each axis spans from 2 to 131. Just about every function we use in the LCD Shield library relies on setting individual pixels. Try sending this code to your Arduino:
#include <ColorLCDShield.h>LCDShield lcd; // Creates an LCDShield, named lcd void setup() { lcd.init(PHILIPS); // Initializes lcd, using an PHILIPS driver lcd.contrast(-51); // -51's usually a good contrast value lcd.clear(ORANGE); // oooh, orange! lcd.setPixel(BLUE, 66, 66); // set a pixel in the middle } void loop() { }
Can you find the lonely, little, blue pixel? Try moving it around to different parts of the display, changing the colors. Can you add more than one pixel? Create an animation?
From the setPixel function, we can move on to more advanced drawing functions: lines, circles, and rectangles. Oh my!
#include <ColorLCDShield.h> LCDShield lcd; // Creates an LCDShield, named lcd void setup() { lcd.init(PHILIPS); // Initializes lcd, using an PHILIPS driver lcd.contrast(-51); // -51's usually a good contrast value lcd.clear(WHITE); // clear the screen lcd.setCircle(66, 66, 55, RED); // Circle in the mid, 55 radius lcd.setCircle(66, 66, 54, RED); // Circle in the mid, 54 radius lcd.setRect(55, 34, 77, 98, 1, BLACK); lcd.setRect(34, 55, 98, 77, 1, BLACK); lcd.setLine(27, 27, 105, 105, RED); lcd.setLine(26, 27, 104, 105, RED); lcd.setLine(28, 27, 106, 105, RED); } void loop() { }
The setCircle function only takes one set of x/y coordinates, and centers a circle of a specified radius around that point. setLine and setRect both require two sets of x/y coordinates. The line function draws a straight line from coordinate 0 to coordinate 1, while the setRect draws a box with opposite corners at the two coordinate pairs. Try changing the colors of everything. Try moving stuff around. Can you figure out what the 5th parameter in the setRect does?
One final feature of the library allows you to add text to the LCD. There's the setChar function, which allows you to place one, and only one, character at specified coordinates. Then there's the setStr function, which will place a string of characters on the screen.
#include <ColorLCDShield.h> LCDShield lcd; // Creates an LCDShield, named lcd void setup() { lcd.init(PHILIPS); // Initializes lcd, using an PHILIPSdriver lcd.contrast(-51); // -51's usually a good contrast value lcd.clear(WHITE); // clear the screen lcd.setStr("Just say no", 2, 20, SLATE, WHITE); lcd.setStr("to addition", 110, 20, SLATE, WHITE); lcd.setCircle(66, 66, 45, RED); // Circle in the mid, 55 radius lcd.setCircle(66, 66, 44, RED); // Circle in the mid, 54 radius lcd.setRect(55, 34, 77, 98, 1, BLACK); lcd.setRect(34, 55, 98, 77, 1, BLACK); lcd.setLine(34, 34, 98, 98, RED); lcd.setLine(33, 34, 97, 98, RED); lcd.setLine(35, 34, 99, 98, RED); } void loop() { }
Seems there's been some mix-up between anti-smoking campaigners and mathematicians.
When you use the setStr or setChar functions, you get to pick two colors: a foreground and background. Watch out for the order in which you add stuff to the screen. Whatever comes last will overlap anything before it.
With that, you should have a good idea how to use everything in the ColorLCDShield Arduino library. I'll leave you with this example. It's lengthy, but it's fun. And, it gives you a good idea of what can be done with the library.
/* ChronoLCD Color - An example sketch for the Color LCD Shield Library by: Jim Lindblom SparkFun Electronics date: 6/23/11 license: CC-BY SA 3.0 - Creative commons share-alike 3.0 use this code however you'd like, just keep this license and attribute. Let me know if you make hugely, awesome, great changes. This sketch draws an analog and digital clock on the Color LCD Shield. You can also use the on-board buttons to set the hours and minutes. Use the defines at the top of the code to set the initial time. You can also adjust the size and color of the clock. To set the time, first hit S3. Then use S1 and S2 to adjust the hours and minutes respectively. Hit S3 to start the clock back up. This example code should give you a good idea of how to use the setCircle, setLine, and setStr functions of the Color LCD Shield Library. */ #include <ColorLCDShield.h> // Color LCD Shield library // Enter the time below in 12-hr format #define HOURS 10 #define MINUTES 21 #define SECONDS 00 #define AMPM 0 // enter 0 for AM, 1 for PM #define CLOCK_RADIUS 50 // radius of clock face #define CLOCK_CENTER 55 // If you adjust the radius, you'll probably want to adjust this #define H_LENGTH 30 // length of hour hand #define M_LENGTH 40 // length of minute hand #define S_LENGTH 48 // length of second hand #define BACKGROUND BLACK // room for growth, adjust the background color according to daylight #define C_COLOR RED // This is the color of the clock face, and digital clock #define H_COLOR BLUE // hour hand color #define M_COLOR GREEN // minute hand color #define S_COLOR YELLOW // second hand color LCDShield lcd; int hours, minutes, seconds, ampm; int buttonPins[3] = { 3, 4, 5}; void setup() { /* Set up the button pins as inputs, set pull-up resistor */ for (int i=0; i<3; i++) { pinMode(buttonPins[i], INPUT); digitalWrite(buttonPins[i], HIGH); } hours = HOURS; minutes = MINUTES; seconds = SECONDS; ampm = AMPM; /* Initialize the LCD, set the contrast, clear the screen */ lcd.init(PHILIPS); lcd.contrast(-51); lcd.clear(BACKGROUND); drawClock(); // Draw the clock face, this includes 12, 3, 6, 9 displayAnalogTime(hours, minutes, seconds); // Draw the clock hands displayDigitalTime(hours, minutes, seconds, ampm); // Draw the digital clock text } void loop() { /* We'll run around checking for button presses, until it's been a second */ while(millis() % 1000) { if (!digitalRead(buttonPins[2])) setTime(); // If S3 was pressed, go set the time } /* We'll get here if it's been a second. We need to increase seconds by 1 and then go from there */ seconds++; if (seconds >= 60) { seconds = 0; // If seconds is 60, set it back to 0 minutes++; // and increase minutes by 1 if (minutes >= 60) { minutes = 0; // If minutes is 60, set it back to 0 hours++; // and increase hours by 1 if (hours == 12) ampm ^= 1; // If it's 12 o'clock, flip ampm if (hours >= 13) hours = 1; // If hours is 13, set it to 1. 12-hr clock. } } /* Once each second, we'll redraw the clock with new values */ drawClock(); displayAnalogTime(hours, minutes, seconds); displayDigitalTime(hours, minutes, seconds, ampm); } /* setTime uses on-shield switches S1, S2, and S3 to set the time pressing S3 will exit the function. S1 increases hours, S2 increases seconds. */ void setTime() { /* Reset the clock to midnight */ seconds = 0; minutes = 0; hours = 12; ampm = 0; /* Draw the clock, so we can see the new time */ drawClock(); displayAnalogTime(hours, minutes, seconds); displayDigitalTime(hours, minutes, seconds, ampm); while (!digitalRead(buttonPins[2])) ; // wait till they let go of S1 /* We'll run around this loop until S3 is pressed again */ while(digitalRead(buttonPins[2])) { /* If S1 is pressed, we'll update the hours */ if (!digitalRead(buttonPins[0])) { hours++; // Increase hours by 1 if (hours == 12) ampm ^= 1; // Flip am/pm if it's 12 o'clock if (hours >= 13) hours = 1; // Set hours to 1 if it's 13. 12-hour clock. /* and update the clock, so we can see it */ drawClock(); displayAnalogTime(hours, minutes, seconds); displayDigitalTime(hours, minutes, seconds, ampm); } if (!digitalRead(buttonPins[1])) { minutes++; // Increase minutes by 1 if (minutes >= 60) minutes = 0; // If minutes is 60, set it back to 0 /* and update the clock, so we can see it */ drawClock(); displayAnalogTime(hours, minutes, seconds); displayDigitalTime(hours, minutes, seconds, ampm); } } /* Once S3 is pressed, we'll exit, but not until it's released */ while(!digitalRead(buttonPins[2])) ; } /* displayDigitalTime() takes in values for hours, minutes, seconds and am/pm. It'll print the time, in digital format, on the bottom of the screen. */ void displayDigitalTime(int h, int m, int s, int ap) { char timeChar[11] = { 'x', 'x', 0x0A, 'x', 'x', 0x0A, 'x', 'x' }; /* Gotta turn the values into individual integers */ timeChar[0] = h/10; timeChar[1] = h - (timeChar[0] * 10); timeChar[3] = m/10; timeChar[4] = m - (timeChar[3] * 10); timeChar[6] = s/10; timeChar[7] = s - (timeChar[6] * 10); /* once we have each integer separated, we need to turn them into displayable characters. Adding 0x30 does this (check an ASCII table. We set the colons to 0x0A initially, this will turn them into the proper 0x3A.*/ for (int i=0; i<8; i++) timeChar[i] += 0x30; timeChar[8] = ' '; // add a space between the time and AM/PM /* Add AM or PM to the end of the timeChar string */ if (!ap) { timeChar[9] = 'A'; timeChar[10] = 'M'; } else { timeChar[9] = 'P'; timeChar[10] = 'M'; } /* add some blank spaces after the time, otherwise it'll display unwanted characters */ timeChar[11] = ' '; timeChar[12] = ' '; /* Print the time on the clock */ lcd.setStr(timeChar, CLOCK_CENTER + CLOCK_RADIUS + 4, 22, C_COLOR, BACKGROUND); } /* drawClock() simply draws the outer circle of the clock, and '12', '3', '6', and '9'. Room for growth here, if you want to customize your clock. Maybe add dashe marks, or even all 12 digits. */ void drawClock() { /* Draw the circle */ lcd.setCircle(CLOCK_CENTER, 66, CLOCK_RADIUS, C_COLOR); /* Print 12, 3, 6, 9, a lot of arbitrary values are used here for the coordinates. Just used trial and error to get them into a nice position. */ lcd.setStr("12", CLOCK_CENTER - CLOCK_RADIUS, 66-9, C_COLOR, BACKGROUND); lcd.setStr("3", CLOCK_CENTER - 9, 66 + CLOCK_RADIUS - 12, C_COLOR, BACKGROUND); lcd.setStr("6", CLOCK_CENTER + CLOCK_RADIUS - 18, 66-4, C_COLOR, BACKGROUND); lcd.setStr("9", CLOCK_CENTER - 9, 66 - CLOCK_RADIUS + 4, C_COLOR, BACKGROUND); } /* displayAnalogTime() draws the three clock hands in their proper position. Room for growth here, I'd like to make the clock hands arrow shaped, or at least thicker and more visible. */ void displayAnalogTime(int h, int m, int s) { double midHours; // this will be used to slightly adjust the hour hand static int hx, hy, mx, my, sx, sy; /* Adjust time to shift display 90 degrees ccw this will turn the clock the same direction as text */ h -= 3; m -= 15; s -= 15; if (h <= 0) h += 12; if (m < 0) m += 60; if (s < 0) s += 60; /* Delete old lines: */ lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, BACKGROUND); // delete second hand lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, BACKGROUND); // delete minute hand lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, BACKGROUND); // delete hour hand /* Calculate and draw new lines: */ s = map(s, 0, 60, 0, 360); // map the 0-60, to "360 degrees" sx = S_LENGTH * sin(3.14 * ((double) s)/180); // woo trig! sy = S_LENGTH * cos(3.14 * ((double) s)/180); // woo trig! lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+sx, 66+sy, S_COLOR); // print second hand m = map(m, 0, 60, 0, 360); // map the 0-60, to "360 degrees" mx = M_LENGTH * sin(3.14 * ((double) m)/180); // woo trig! my = M_LENGTH * cos(3.14 * ((double) m)/180); // woo trig! lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+mx, 66+my, M_COLOR); // print minute hand midHours = minutes/12; // midHours is used to set the hours hand to middling levels between whole hours h *= 5; // Get hours and midhours to the same scale h += midHours; // add hours and midhours h = map(h, 0, 60, 0, 360); // map the 0-60, to "360 degrees" hx = H_LENGTH * sin(3.14 * ((double) h)/180); // woo trig! hy = H_LENGTH * cos(3.14 * ((double) h)/180); // woo trig! lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, H_COLOR); // print hour hand }
From here, it's all you. How are you going to use your new Color LCD Shield? We love to hear about neat projects from our customers, drop us a line!
I hope you enjoyed this tutorial, and maybe learned a thing or two. If you've got any questions or comments, please drop them into the comment box below.
Realizing that this tutorial is retired, however it is still extremely useful. Wanted to point out to others that PHILLIPS is spelt wrong in all the posted code (there should be 2 L's). I came here to resurrect a project I started 10 years ago!
In my previous comment, I forgot telling that the bug doesn't affect the graphic drawings like making a circle, etc ...
It is then useless to set the second parameter to 1 in the Philips lcd.init sequence.
It seems there is a little bug in the ColorLCDShield.cpp Library file. If you have a PHILIPS driver and if you don't remove those 2 lines : "fColor = swapColors(fColor); bColor = swapColors(bColor);" you will get red & blue colors inverted when printing characters on the screen. Have fun with that tool !!!
How much milli amps the lcd is asking for ?
I have some spare LCD's from Old Nokia devices. I was wondering if you carried the board by itself so I can reuse my LCDs without the waste and the extra bucks? Thanks in advance!
Jim,
Thank you for sharing....
I too appear to have a similar odd duck (red tag, spazzed out screen using EPSON, works as a PHILLIPS)
You saved me lots of time.
Thank you again!
I've run into an interesting situation here.
I recently purchased a color LCD shield and attempted to use it with the various sample sketches.
The LCD was covered with a plastic coversheet with a red tab, which wold indicate the "Epson" driver.
I am using a Rev 3 Arduino UNO (Genuine Arduino), and the 1.0 series libraries.
The odd behavior I noted is as follows:
If run as an Epson device, any attempt to display any kind of image at all results in a display showing what appears to be random, multi-colored snow.
If I change the script to the "Phillips" device, the display shows a valid image instead of snow - however the colors are inverted as if it's really an Epson device.
Has anyone else noticed this? Are there any known solutions?
Thanks!
Jim (JR)
Hi will this work with the Arduino Ethernet Shield ?
Has anyone noticed that RED is BLUE?
Maybe cuz I'm using the PHILLIPS lcd shield. Can the library be updated?
I suppose I could just lookup the hexadecimal code. I'm just lazy right now. I'm going to enjoy playing with this. :)
I have a PHILLIPS too, we need to use BGR instead of RGB. A macro that swaps the first and last byte will make these colors right (someone help me with this forums code formatting and I'll post the macro here).
About a year ago I was given a Freaklabs Freakduino as my badge for a competition. I was also given a Sparkfun Color LCD Shield to play with later. I only just go around to soldering the pins on the shield yesterday. Tonight I decided to give it a try. Well the protective tab on my LCD is Green not red or blue. Turns out my shield works with the Epson drivers which were already configured by default.
The Freakduino has a built in 802.15.4 (Xbee/Zigbee) radio chipset which also uses the SPI bus. Luckily the CS pin for this display is 9 (although that collides with the aux LED) and the CS pin for the radio chip is pin 3 so I can use both on the bus without resorting to using my Go-between shield. The downside is that one of the LCD shield's buttons is also on pin 3 so that won't be available if I'm using the radio unless I use my Go-between shield to remap the button to another pin.
I haven't actually tested the radio and the LCD at the same time yet but I'll post a follow up once I have a definitive success or failure. Short of that I've successfully run the Sparkfun logo example and a bunch of Peter Davenport's examples including the Arduino O-scope which is pretty sweet.
Hi Jimbo,
Very neat and clear tutorial. However how do I put a bitmap image on the LCD? I have searched all over but there is no library or sketch which explains it out.
Any help in this regard will be much appreciated.
-AJ
Using sparkfun LCD shield (EPSON) with Uno R3