TFT LCD Technology
Read on to know about what is TFT LCD? How it works? And how we can interface it with Arduino Uno.
Hello geeks, thanks for visiting this blog. As per the title of this topic, in this section, we are going to talk about what is TFT LCD, how it works and how we can interface it with Arduino Uno.
So before getting started, let's discuss the importance and working principle of this technology. TFT LCD is in great demand in electronic fields such as automation, medical type devices, and smartphones due to its low power and high clarity feature.
Moreover, its vivid viewing angle makes TFT more attractive and clearer. Â
We will be discussing:
- Overview of TFT LCD and it's workingÂ
- The detailed comparison of different types of TFT LCDÂ
- TFT LCD With Arduino Uno
- Â Arduino Uno Code for 2.8 TFT LCDÂ
Overview of TFT LCD and it's workingÂ
 TFT stands for thin-film-transistor. It consists of pixels, which are arranged vertically and horizontally. Pixels in the horizontal and vertical alignment determine the resolution of the display. let's take an example, suppose you have an 1800x740 resolution display, that means, it has 1800 pixels aligned horizontally and the 740 vertically. Each pixel has three subpixels RED, GREEN, BLUE. But do you know how does TFT LCD generates different colours? Answer for this is divided into four layers that are as follows: 1. Polarization layer
 2. Thin Film Transistor
 3. Liquid Crystal
 4. RGB Colour filter
Polarization Layer-
 You might have heard about this concept if you are in the photography field. This layer helps to excrete the reflection of the object. As we know TFT LCD constituted of various layers; these layers are sandwiched in between two polarization layers. These two layers are oriented 90 degrees to each other. A polarization filter is used to polarize the un-polarized light.  When we turn on the backlight it produces horizontal and vertical light plane but the first polarization filter, which is near to backlight only allows the horizontal plane to pass through it; whereas the second filter allows a vertical plane to pass through it. Now, you might be wondering how we can see light on the screen if both filters are blocking light. This is a miracle of liquid crystal.Liquid Crystal-
 Liquid crystals are oriented in random directions these liquid crystals are sandwiched between horizontally edged glass and vertically edged glass. This alignment of the glass forces them to bend in a predictable pattern. When light passes through compressed liquid crystals it follows the path of liquid molecules. Any horizontal plane light, passing through the liquid crystal exits along the vertical plane. This effect is called the scattering effect of liquid crystals. These compressed liquid crystals are coated with a transparent electrode and when the voltage is applied to it the liquid crystals align themselves accordingly.Thin-film transistor-
[caption id="attachment_636767" align="aligncenter" width="416"] Â Â Â Â Â Fig Construction and V-I graph of Thin-film Transistor[/caption] To align each liquid crystal in a meaningful way, it is necessary to address each pixel individually and this is done with the help of thin-film transistors. Thin-film transistor layer decides the refresh-rate of the display.RGB colour filter-
[caption id="attachment_636991" align="aligncenter" width="416"] Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Fig. RGB Subpixels[/caption] Un-Polarized light of the backlight passes through a horizontal polarizer which only allows the horizontal light plane to pass through it. This filtered horizontal plane light passes through liquid crystal and gets twisted into a vertical position and then passes through vertical polarization and then through the RGB colour filter. However, when we turn on the thin-film transistor, Liquid crystal does not twist the light beam and stops at vertical polarization. In this way, by adjusting the amount of voltage through each set of crystals we can control the amount of light reaching the colour filter. The brightness of each pixel determines different shades of colour on display. In this way, Voltage to each pixel (liquid crystal) is adjusted to produce various shades of colours. Each pixel consists of three subpixels, but it is so tiny that it is invisible to the human eye to find out its presence.Selection Process-
The selection process of any product is an important perspective for any manufacturer while designing a cost-effective product. This process becomes more complicated when there are several options available for the same product in the market. It is the designer's responsibility to go through all the selection process and choose the right one. A designer should keep in mind the following parameters whenever selecting a correct display. 1. Size of the display
 2. Resolution of the display
 3. Interface type
 4. Viewing angle
 5. Backlight life
 6. Refresh Rate
 7. Power Consummation
 8. Contrast Ratio
9. Driver IC
Different types of Display and the difference between them:
As we know there are different types of displays available in the market. This diversity makes the selection process more complex. To make it a little bit easier here I have shared the major differences which will help you in the selection process of the display.                                                   Fig: Difference between LCDsTFT LCDs are available in different sizes:
TFT LCD Modules are available on our website in different sizes and comes with a different driver ICs. Here I have mentioned a few types of TFT LCDs.Types of LCDÂ
No |                        Types of TFT |  Driver IC |        Communication                   Protocol |
1 |
1.44 inch TFT LCD |
ST7735 | Â Â Â Â Â Â Â Â Â Â Â Â Â SPI |
2 | 1.8 inch TFT LCD | ST7735 | Â Â Â Â Â Â Â SPI |
3 | 2.0 inch TFT LCD | ILI9225 | Â Â Â Â Â Â SPI |
4 | 2.8 inch TFT LCD | ILI9225 | Â Â Â Â Â Â SPI |
     Table: Types of TFT LCD
TFT LCD interfacing with Arduino Uno
 Components You will need to work with this module:
Hardware: Software [caption id="attachment_637422" align="aligncenter" width="554"] Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Fig.: Interfacing Diagram For TFT LCD[/caption] Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ÂArduino Uno Code for 2.8 inch TFT LCD
/*************************************************** This is our GFX example for the Adafruit ILI9341 Breakout and Shield ----> http://www.adafruit.com/products/1651 Check out the links above for our tutorials and wiring diagrams These displays use SPI to communicate, 4 or 5 pins are required to interface (RST is optional) Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. MIT license, all text above must be included in any redistribution ****************************************************/ #include "SPI.h" #include "Adafruit_GFX.h" #include "Adafruit_ILI9341.h" // For the Adafruit shield, these are the default. #define TFT_DC 9 #define TFT_CS 10 // Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); // If using the breakout, change pins as desired //Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO); void setup() { Serial.begin(9600); Serial.println("ILI9341 Test!"); tft.begin(); // read diagnostics (optional but can help debug problems) uint8_t x = tft.readcommand8(ILI9341_RDMODE); Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDMADCTL); Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDPIXFMT); Serial.print("Pixel Format: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDIMGFMT); Serial.print("Image Format: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDSELFDIAG); Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); Serial.println(F("Benchmark Time (microseconds)")); delay(10); Serial.print(F("Screen fill ")); Serial.println(testFillScreen()); delay(500); Serial.print(F("Text ")); Serial.println(testText()); delay(3000); Serial.print(F("Lines ")); Serial.println(testLines(ILI9341_CYAN)); delay(500); Serial.print(F("Horiz/Vert Lines ")); Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE)); delay(500); Serial.print(F("Rectangles (outline) ")); Serial.println(testRects(ILI9341_GREEN)); delay(500); Serial.print(F("Rectangles (filled) ")); Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA)); delay(500); Serial.print(F("Circles (filled) ")); Serial.println(testFilledCircles(10, ILI9341_MAGENTA)); Serial.print(F("Circles (outline) ")); Serial.println(testCircles(10, ILI9341_WHITE)); delay(500); Serial.print(F("Triangles (outline) ")); Serial.println(testTriangles()); delay(500); Serial.print(F("Triangles (filled) ")); Serial.println(testFilledTriangles()); delay(500); Serial.print(F("Rounded rects (outline) ")); Serial.println(testRoundRects()); delay(500); Serial.print(F("Rounded rects (filled) ")); Serial.println(testFilledRoundRects()); delay(500); Serial.println(F("Done!")); } void loop(void) { for(uint8_t rotation=0; rotation<4; rotation++) { tft.setRotation(rotation); testText(); delay(1000); } } unsigned long testFillScreen() { unsigned long start = micros(); tft.fillScreen(ILI9341_BLACK); yield(); tft.fillScreen(ILI9341_RED); yield(); tft.fillScreen(ILI9341_GREEN); yield(); tft.fillScreen(ILI9341_BLUE); yield(); tft.fillScreen(ILI9341_BLACK); yield(); return micros() - start; } unsigned long testText() { tft.fillScreen(ILI9341_BLACK); unsigned long start = micros(); tft.setCursor(0, 0); tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1); tft.println("Hello World!"); tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2); tft.println(1234.56); tft.setTextColor(ILI9341_RED); tft.setTextSize(3); tft.println(0xDEADBEEF, HEX); tft.println(); tft.setTextColor(ILI9341_GREEN); tft.setTextSize(5); tft.println("Groop"); tft.setTextSize(2); tft.println("I implore thee,"); tft.setTextSize(1); tft.println("my foonting turlingdromes."); tft.println("And hooptiously drangle me"); tft.println("with crinkly bindlewurdles,"); tft.println("Or I will rend thee"); tft.println("in the gobberwarts"); tft.println("with my blurglecruncheon,"); tft.println("see if I don't!"); return micros() - start; } unsigned long testLines(uint16_t color) { unsigned long start, t; int x1, y1, x2, y2, w = tft.width(), h = tft.height(); tft.fillScreen(ILI9341_BLACK); yield(); x1 = y1 = 0; y2 = h - 1; start = micros(); for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color); x2 = w - 1; for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color); t = micros() - start; // fillScreen doesn't count against timing yield(); tft.fillScreen(ILI9341_BLACK); yield(); x1 = w - 1; y1 = 0; y2 = h - 1; start = micros(); for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color); x2 = 0; for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color); t += micros() - start; yield(); tft.fillScreen(ILI9341_BLACK); yield(); x1 = 0; y1 = h - 1; y2 = 0; start = micros(); for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color); x2 = w - 1; for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color); t += micros() - start; yield(); tft.fillScreen(ILI9341_BLACK); yield(); x1 = w - 1; y1 = h - 1; y2 = 0; start = micros(); for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color); x2 = 0; for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color); yield(); return micros() - start; } unsigned long testFastLines(uint16_t color1, uint16_t color2) { unsigned long start; int x, y, w = tft.width(), h = tft.height(); tft.fillScreen(ILI9341_BLACK); start = micros(); for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1); for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2); return micros() - start; } unsigned long testRects(uint16_t color) { unsigned long start; int n, i, i2, cx = tft.width() / 2, cy = tft.height() / 2; tft.fillScreen(ILI9341_BLACK); n = min(tft.width(), tft.height()); start = micros(); for(i=2; i<n; i+=6) { i2 = i / 2; tft.drawRect(cx-i2, cy-i2, i, i, color); } return micros() - start; } unsigned long testFilledRects(uint16_t color1, uint16_t color2) { unsigned long start, t = 0; int n, i, i2, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1; tft.fillScreen(ILI9341_BLACK); n = min(tft.width(), tft.height()); for(i=n; i>0; i-=6) { i2 = i / 2; start = micros(); tft.fillRect(cx-i2, cy-i2, i, i, color1); t += micros() - start; // Outlines are not included in timing results tft.drawRect(cx-i2, cy-i2, i, i, color2); yield(); } return t; } unsigned long testFilledCircles(uint8_t radius, uint16_t color) { unsigned long start; int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2; tft.fillScreen(ILI9341_BLACK); start = micros(); for(x=radius; x<w; x+=r2) { for(y=radius; y<h; y+=r2) { tft.fillCircle(x, y, radius, color); } } return micros() - start; } unsigned long testCircles(uint8_t radius, uint16_t color) { unsigned long start; int x, y, r2 = radius * 2, w = tft.width() + radius, h = tft.height() + radius; // Screen is not cleared for this one -- this is // intentional and does not affect the reported time. start = micros(); for(x=0; x<w; x+=r2) { for(y=0; y<h; y+=r2) { tft.drawCircle(x, y, radius, color); } } return micros() - start; } unsigned long testTriangles() { unsigned long start; int n, i, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1; tft.fillScreen(ILI9341_BLACK); n = min(cx, cy); start = micros(); for(i=0; i<n; i+=5) { tft.drawTriangle( cx , cy - i, // peak cx - i, cy + i, // bottom left cx + i, cy + i, // bottom right tft.color565(i, i, i)); } return micros() - start; } unsigned long testFilledTriangles() { unsigned long start, t = 0; int i, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1; tft.fillScreen(ILI9341_BLACK); start = micros(); for(i=min(cx,cy); i>10; i-=5) { start = micros(); tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, tft.color565(0, i*10, i*10)); t += micros() - start; tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, tft.color565(i*10, i*10, 0)); yield(); } return t; } unsigned long testRoundRects() { unsigned long start; int w, i, i2, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1; tft.fillScreen(ILI9341_BLACK); w = min(tft.width(), tft.height()); start = micros(); for(i=0; i<w; i+=6) { i2 = i / 2; tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0)); } return micros() - start; } unsigned long testFilledRoundRects() { unsigned long start; int i, i2, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1; tft.fillScreen(ILI9341_BLACK); start = micros(); for(i=min(tft.width(), tft.height()); i>20; i-=6) { i2 = i / 2; tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0)); yield(); } return micros() - start; }
The final output of the Code Â
[caption id="attachment_637743" align="aligncenter" width="900"]                                                 The final output of the Code   [/caption]
     Â
Good blog which can help you in robotics