Tutorial: Arduino and TFT LCD

This is chapter twenty-nine of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe.

The first chapter is here, the complete series is detailed here. Please note from November 1, 2010 files from tutorials will be found here.

Welcome back fellow arduidans!

Today we continue with experimenting with colour LCD units. In this article we will get started with a very clear and sharp unit – the 4D Systems 1.44″ TFT serial interface LCD:

The LCD is an LED-backlit thin-film transistor type, resolution is 128 x 128 pixels, with an RGB colour range of 65536.

As an aside, this is a very powerful piece of hardware. The module not only contains a 1.44″ square TFT LCD, there is also a dedicated graphics processor and a microSD card interface. One can program the display processor in the same manner as another microcontroller platform for incredibly interesting results. For more information, please visit here.

However in the spirit of keeping things simple, this article will focus on driving the LCD directly using our Arduino or compatibleboards. There are two firmware versions of this module – the GFX and the SGC. We need to have the SGC firmware, as this allows control via the serial TX/RX pins from our Arduno board. If you have purchased the SGC module, you’re ready to go. Scroll down until you see “And we’re back…”. However if you have the GFX version, please read the following instructions on how to change your LCD’s firmware from GFX to SGC…

Changing the firmware from GFX to SGC

  • At the moment this process only seems available to users of Microsoft Windows. All complaints to 4D Systems.
  • First of all, remove the ATmega328 from your Arduino board. Please be careful, use a chip puller if possible. We are going to use the board as a simple serial-USB converter;
  • Insert your LCD module into a solderless breadboard;
  • Connect Arduino pin 0 (RX) to display pin 7 (RX); connect Arduino pin 1 (TX) to display pin 8 (TX). [Yes – TX>TX, RX>RX];
  • Connect Arduino 5V to display pin 9; connect Arduino GND to display pin 6; your LCD should display the following:

  • Visit here, download and open the PmmC Loader application; visit here and download the .pmmc file to your local drive;
  • Connect your Arduino board via USB to the computer; then run the PmmC loader application;
  • Select the appropriate COM: port, load in the .pmmc file, then click Load. The firmware update should take less than sixty seconds;
  • When finished, you will be presented with the following on the computer:

… and the following on your LCD:

  • At this point unplug the USB lead from your Arduino board and all leads into the Arduino board;
  • Re-insert the ATmega328 back into your Arduino board;
  • Reconnect the wires from the LCD module to the Arduino, but this time connect Arduino TX to LCD RX; and LCD TX to Arduino RX.
  • Now you have  the serial-interface SGC firmware model LCD.

And we’re back…

To control this LCD, it requires commands to be sent via Serial.write(), and such commands are in the form of hexadecimal numbers. (You see something new every day). You can download the reference book with all the commands: SGC Commands.pdf and bypass the library by directly writing the hexadecimal numbers directly to the module.

However, to get up to speed as fast as possible we can use a library with more of the popular functions included. Kudos and thanks to Oscar Gonzalez for writing a very useful library. Download the library from here and install into your ../Arduino-002x/libraries folder, then re-start the Arduino IDE if you had it running. You may be wondering why the library is nameddisplayshield4d – the LCD manufacturer sells this LCD on an Arduino shield. Although that would be great for experimenting, one would need to purchase another standalone LCD if their project moved forward – myself included. So that’s why we’re using the bare LCD board.

To connect the LCD to our Arduino is very simple:

  • LCD pin 5 to Arduino RST;
  • LCD pin 6 to Arduino GND;
  • LCD pin 7 to Arduino D1;
  • LCD pin 8 to Arduino D0;
  • LCD pin 9 to Arduino 5V.

In the following examples we will demonstrate the various functions available in the library. As this is chapter 29, (when will this stop?) I will no longer explain the more basic functions or ideas that you should know by now, instead relying on comments within the sketch if it feels necessary.

Firstly we will demonstrate text display. Initialising the display requires a few functions:

#include <displayshield4d.h> // include the LCD library
DisplayShield4d  lcd;

The second line creates an instance of lcd to be used with the relevant functions. Next, within void setup():

Serial.begin(115200);  // LCD speed is very high
lcd.Init(); // wake up LCD
lcd.Clear(); // clear the LCD, set background to black

To write text to the LCD, the following function is required:

lcd.setfontmode(OLED_FONT_TRANSPARENT);  // set font background type

This line sets the font transparency. If we use the parameter OLED_FONT_TRANSPARENT the unused pixels in the character area will be transparent and continue to show what they were set to before the text was over-written with. You can also useOLED_FONT_OPAQUE, which blocks the item displayed “behind” the text.

Whenever a function requires a colour parameter, we use:

lcd.RGB(x,y,z);

where x, y and z are numerical values (between 0 and 255) for the red, green and blue components of the required colour. If you need an RGB numerical reference, download this handy chart. Finally, to display some text we use the following:

lcd.drawstringblock(a, b, c, lcd.RGB(255, 255, 255), d, e, "Hello, world");

The parameters required are:

  • a – the x-position of the first character. E.g. if this was a zero, the top-left pixel of the first character would be on the left-most pixel column of the LCD;
  • b – the y-position of the first character. e.g. if both a and b were zero, the text would start from the top-left of the LCD;
  • c – numerical code for the font to use: 1 is for 5×7 pixel characters, 2 for 8×8 and 3 for 8×12;
  • the three values within the lcd.RGB() function determine the colour of the text;
  • d – x-axis resolution multiplier. E.g. if you double this and use the 5×7 font, the characters will be double-width;
  • e – y-axis resolution multiplier.

Now let’s see this in action with the following sketch:

Example 29.1

/*  Example 29.1 - uLCD-144 text demonstration
http://tronixstuff.com/tutorials > chapter 29  CC by-sa-nc  */
#include <displayshield4d.h> // necessary library
DisplayShield4d  lcd; // create an instance of the LCD
void setup()
{
Serial.begin(115200);  // LCD speed is very high
lcd.Init(); // wake up LCD
lcd.Clear(); // clear the LCD, set background to black
}
void loop()
{
lcd.Clear(); // clear LCD
lcd.setfontmode(OLED_FONT_TRANSPARENT);  // set font background type
for (int a=0; a<128; a+=8)
{
lcd.drawstringblock(0, a, 2 , lcd.RGB(255, 0, 0), 1, 1, "visit me");
}
delay(2000);
lcd.Clear();
for (int a=0; a<128; a+=16)
{
lcd.drawstringblock(0, a, 0, lcd.RGB(0, 255, 0), 2, 2, "0123456789");
}
delay(2000);
lcd.Clear();
for (int a=0; a<128; a+=32)
{
lcd.drawstringblock(0, a, 0, lcd.RGB(0, 0, 255), 4, 4, "Great");
}
delay(2000);
}

And a short video clip of the example in action:

As you can see the display update speed is much better than the LCD from the previous chapter. Although this example was short, don’t be afraid to try out your own parameters in the example sketch.

Question – How many capacitors are used in a Freetronics KitTen?

Next we will demonstrate the various graphics functions in the library. Creating graphics isn’t rocket science, it just takes some imagination (something I admit to lacking) and following the parameters for each function. Our first is

lcd.putpixel(x,y,lcd.RGB(r,g,b));

which places a pixel on the screen at location x,y of colour described using lcd.RGB(). Next we have

lcd.line(x1,y1,x2,y2,lcd.RGB(r,g,b));

which draws a line from x1, y1 to x2, y2 of colour rgb. One can also create rectangles and so on using

lcd.rectangle(x,y,l,h,z,lcd.RGB(r,g,b));

This will create a rectangle with the top-left point at x,y; width is l pixels, height is h pixels, and a new parameter z. If z is 0, the function will draw a solid shape, if z is 1, it will display only a wire-frame rectangle with a pixel width of one. Circles are created using

lcd.circle(x,y,r,z,lcd.RGB(r,g,b);

where x and y are the coordinates for the centre of the circle, r is the radius, and z is the solid/wireframe parameter. And finally – triangles:

lcd.triangle(x1,y1,x2,y2,x3,y3,z,lcd.RGB(r,g,b));

This will draw a triangle with the corners at the coordinate parameters; z again is the solid/wireframe parameter. However you need to order the corners in an anti-clockwise order. This will become evident in the example sketch below.

Example 29.2

In this example we run through the graphical functions described above. By following through the sketch you should gain an idea of how the graphical functions are used, in order to create your own displays.

/*  Example 29.2 - uLCD-144 graphic library demonstration
http://tronixstuff.com/tutorials > chapter 29  CC by-sa-nc  */
int a,b,c,d,e=0;
#include <displayshield4d.h> // necessary library
DisplayShield4d  lcd; // create an instance of the LCDvoid
setup()
{
randomSeed(analogRead(0));
Serial.begin(115200);  // LCD speed is very high
lcd.Init(); // wake up LCD
lcd.Clear(); // clear the LCD, set background to black
}
void loop()
{
lcd.Clear();
for (int z=0; z<2500; z++)
{
a=random(127);
b=random(127);
c=random(255);
d=random(255);
e=random(255);
lcd.putpixel(a,b,lcd.RGB(c,d,e));
}
delay(1000);
lcd.Clear();
for (int z=0; z<64; z++)
{
lcd.line(0,0,127,z*2,lcd.RGB(0,255,0));
}
for (int z=0; z<64; z++)
{
lcd.line(0,0,z*2,127,lcd.RGB(0,0,255));
}
delay(1000);
lcd.Clear();
for (int z=0; z<15; z++)
{
lcd.rectangle(z*10, z*10, 20, 20, 1, lcd.RGB(255,0,0));
delay(250);
lcd.rectangle(z*10, z*10, 20, 20, 0, lcd.RGB(0,0,255));
delay(250);
lcd.rectangle(z*10, z*10, 20, 20, 0, lcd.RGB(0,0,0));
delay(250);
}
delay(1000);
lcd.Clear();
for (int z=0; z<14; z++)
{
lcd.circle(63,63,z*3, 1, lcd.RGB(0,0,255));
delay(250);
lcd.circle(63,63,z*3, 0, lcd.RGB(0,255,0));
delay(250);
lcd.circle(63,63,z*3, 0, lcd.RGB(0,0,0));
delay(250);
}
delay(1000);
lcd.Clear();
for (int z=10; z>-0; --z)
{
lcd.triangle(127,127,64,z*10,0,127,1,lcd.RGB(0,255,0));
delay(250);
lcd.triangle(127,127,64,z*10,0,127,0,lcd.RGB(0,0,255));
delay(250);
lcd.triangle(127,127,64,z*10,0,127,0,lcd.RGB(0,0,0));
delay(250);
}
}

And here is the video of example 29.2 in action … brought to you by Mr Blurrycam:

So there you have it, another useful part and a very nice colour LCD to make use of. Stay tuned for upcoming Arduino tutorials by subscribing to the blog, RSS feed (top-right), twitter or joining our Google Group.

If you have any questions about the processes or details in this article, please ask in our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, there is the odd competition or give-away –  and we can all learn something.

Otherwise, have fun, stay safe, be good to each other – and make something!

Advertisements
By John Boxall

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s