Tangible Computing
9. Using the Adafruit LCD display


This is an introduction to getting your TFT LCD screen, supplied by Adafruit, wired up and ready to use their sample graphics code. It is a 128 x 160 display. We will use the libraries provided by Adafruit to draw pictures and write text to the screen. We will also be able to read and write to our micro SD card through the LCD screen.

If you flip over the LCD screen, you'll see the following:



On the right side in the image we have a slot for the micro SD card and on the left we have the 10 pins we need to wire.

BEFORE YOU BEGIN!
You cannot reverse polarity with these screens. This means if you mess up with the wiring with the ground and power, then you will fry your screen!


To finish assembling your display you need put the remaining two small bolts into the display board. The two remaining small bolts belong in the holes in the display board to act as legs to support it when plugged into the breadboard with the display extended out over the base plate. The final version should look like this:



Now, here is a quick list of where the pins of the LCD screen connect to on the Arduino board, in the order from left to right (LCD screen facing up), with pins of the LCD at the bottom, closest to you. Pictures are below, as well as a recommended wiring order! This is just a reference!
  1. GND to BB GND bus
  2. VCC to BB positive bus
  3. RESET to Pin 8
  4. D/C (Data/Command) to Pin 7
  5. CARD_CS (Card Chip Select) to Pin 5
  6. TFT_CS (TFT/screen Chip Select) to Pin 6
  7. MOSI (Master Out Slave In) to Pin 51
  8. SCK (Clock) to Pin 52
  9. MISO (Master In Slave Out) to 50
  10. LITE (Backlite) to BB positive bus
Photo


Fritizing


9.1 Recommended Wiring Order

  1. Hook up the GND (ground), VCC (Power) and LITE first.

    TEST: Give power to your Arduino (doesn't matter what program you have running). You just need to make sure there's power for your screen. Your screen should light up now! This is important to do because if your screen doesn't light up now, it won't later. If it doesn't, (unplug the power first, then) try changing your wires. You could have a faulty wire, or there might be a problem with the screen. Once you've completed this task, make sure you remove the power since you'll be wiring again!

  2. Next hook up the RESET, D/C, CARD_CS, and TFT_CS pins. Notice that if you are hooking up these pins in the order they appear, they go to digital pins 8, 7, 5 then 6, respectively. (Not 8, 7, 6, 5.)

    Note: The CARD_CS that hooks up to digital pin 5 is used for accessing SD card. While it is not neccessary to wire this up to get the screen working, it'll help prevent you from connecting a wire to the wrong spot on the breadboard, so wire it up anyways!

  3. Next you ned to wire up the MOSI, SCK and MISO pins. The digital pins on the Arduino are set, so the MOSI, SCK and MISO must connect to digital pins 51, 52 and 50, respectively.


9.2 Hello World: Graphics Test

Once you have all of your wires hooked up, we can now upload Adafruit's graphics test program! It's a lot of code, but it shows you how to draw on the screen, print text, etc.

code/graphicstest_highspeed/graphicstest_highspeed.ino

    /***************************************************
      This is an example sketch for the Adafruit 1.8" SPI display.
      This library works with the Adafruit 1.8" TFT Breakout w/SD card
      ----> http://www.adafruit.com/products/358
      as well as Adafruit raw 1.8" TFT display
      ----> http://www.adafruit.com/products/618
     
      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
     ****************************************************/
     
    //#define sclk 13
    //#define mosi 11
    #define cs   6
    #define dc   7
    #define rst  8  // you can also connect this to the Arduino reset
     
    #include <Adafruit_GFX.h>    // Core graphics library
    #include <Adafruit_ST7735.h> // Hardware-specific library
    #include <SPI.h>
     
    // Option 1: use any pins but a little slower
    //Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, mosi, sclk, rst);
     
    // Option 2: must use the hardware SPI pins
    // (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
    // an output. This is much faster - also required if you want
    // to use the microSD card (see the image drawing example)
    Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
    float p = 3.1415926;
     
    void setup(void) {
      Serial.begin(9600);
      Serial.print("hello!");
     
      // Our supplier changed the 1.8" display slightly after Jan 10, 2012
      // so that the alignment of the TFT had to be shifted by a few pixels
      // this just means the init code is slightly different. Check the
      // color of the tab to see which init code to try. If the display is
      // cut off or has extra 'random' pixels on the top & left, try the
      // other option!
     
      // If your TFT's plastic wrap has a Red Tab, use the following:
      tft.initR(INITR_REDTAB);   // initialize a ST7735R chip, red tab
      // If your TFT's plastic wrap has a Green Tab, use the following:
      //tft.initR(INITR_GREENTAB); // initialize a ST7735R chip, green tab
     
      Serial.println("init");
     
      uint16_t time = millis();
      tft.fillScreen(ST7735_BLACK);
      time = millis() - time;
     
      Serial.println(time, DEC);
      delay(500);
     
      // large block of text
      tft.fillScreen(ST7735_BLACK);
      testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST7735_WHITE);
      delay(1000);
     
      // tft print function!
      tftPrintTest();
      delay(4000);
     
      // a single pixel
      tft.drawPixel(tft.width()/2, tft.height()/2, ST7735_GREEN);
      delay(500);
     
      // line draw test
      testlines(ST7735_YELLOW);
      delay(500);
     
      // optimized lines
      testfastlines(ST7735_RED, ST7735_BLUE);
      delay(500);
     
      testdrawrects(ST7735_GREEN);
      delay(500);
     
      testfillrects(ST7735_YELLOW, ST7735_MAGENTA);
      delay(500);
     
      tft.fillScreen(ST7735_BLACK);
      testfillcircles(10, ST7735_BLUE);
      testdrawcircles(10, ST7735_WHITE);
      delay(500);
     
      testroundrects();
      delay(500);
     
      testtriangles();
      delay(500);
     
      mediabuttons();
      delay(500);
     
      Serial.println("done");
      delay(1000);
    }
     
    void loop() {
      tft.invertDisplay(true);
      delay(500);
      tft.invertDisplay(false);
      delay(500);
    }
     
    void testlines(uint16_t color) {
      tft.fillScreen(ST7735_BLACK);
      for (int16_t x=0; x < tft.width(); x+=6) {
        tft.drawLine(0, 0, x, tft.height()-1, color);
      }
      for (int16_t y=0; y < tft.height(); y+=6) {
        tft.drawLine(0, 0, tft.width()-1, y, color);
      }
     
      tft.fillScreen(ST7735_BLACK);
      for (int16_t x=0; x < tft.width(); x+=6) {
        tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
      }
      for (int16_t y=0; y < tft.height(); y+=6) {
        tft.drawLine(tft.width()-1, 0, 0, y, color);
      }
     
      tft.fillScreen(ST7735_BLACK);
      for (int16_t x=0; x < tft.width(); x+=6) {
        tft.drawLine(0, tft.height()-1, x, 0, color);
      }
      for (int16_t y=0; y < tft.height(); y+=6) {
        tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
      }
     
      tft.fillScreen(ST7735_BLACK);
      for (int16_t x=0; x < tft.width(); x+=6) {
        tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
      }
      for (int16_t y=0; y < tft.height(); y+=6) {
        tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
      }
    }
     
    void testdrawtext(char *text, uint16_t color) {
      tft.setCursor(0, 0);
      tft.setTextColor(color);
      tft.setTextWrap(true);
      tft.print(text);
    }
     
    void testfastlines(uint16_t color1, uint16_t color2) {
      tft.fillScreen(ST7735_BLACK);
      for (int16_t y=0; y < tft.height(); y+=5) {
        tft.drawFastHLine(0, y, tft.width(), color1);
      }
      for (int16_t x=0; x < tft.width(); x+=5) {
        tft.drawFastVLine(x, 0, tft.height(), color2);
      }
    }
     
    void testdrawrects(uint16_t color) {
      tft.fillScreen(ST7735_BLACK);
      for (int16_t x=0; x < tft.width(); x+=6) {
        tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color);
      }
    }
     
    void testfillrects(uint16_t color1, uint16_t color2) {
      tft.fillScreen(ST7735_BLACK);
      for (int16_t x=tft.width()-1; x > 6; x-=6) {
        tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1);
        tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2);
      }
    }
     
    void testfillcircles(uint8_t radius, uint16_t color) {
      for (int16_t x=radius; x < tft.width(); x+=radius*2) {
        for (int16_t y=radius; y < tft.height(); y+=radius*2) {
          tft.fillCircle(x, y, radius, color);
        }
      }
    }
     
    void testdrawcircles(uint8_t radius, uint16_t color) {
      for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
        for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
          tft.drawCircle(x, y, radius, color);
        }
      }
    }
     
    void testtriangles() {
      tft.fillScreen(ST7735_BLACK);
      int color = 0xF800;
      int t;
      int w = 63;
      int x = 159;
      int y = 0;
      int z = 127;
      for(t = 0 ; t <= 15; t+=1) {
        tft.drawTriangle(w, y, y, x, z, x, color);
        x-=4;
        y+=4;
        z-=4;
        color+=100;
      }
    }
     
    void testroundrects() {
      tft.fillScreen(ST7735_BLACK);
      int color = 100;
      int i;
      int t;
      for(t = 0 ; t <= 4; t+=1) {
        int x = 0;
        int y = 0;
        int w = 127;
        int h = 159;
        for(i = 0 ; i <= 24; i+=1) {
          tft.drawRoundRect(x, y, w, h, 5, color);
          x+=2;
          y+=3;
          w-=4;
          h-=6;
          color+=1100;
        }
        color+=100;
      }
    }
     
    void tftPrintTest() {
      tft.setTextWrap(false);
      tft.fillScreen(ST7735_BLACK);
      tft.setCursor(0, 30);
      tft.setTextColor(ST7735_RED);
      tft.setTextSize(1);
      tft.println("Hello World!");
      tft.setTextColor(ST7735_YELLOW);
      tft.setTextSize(2);
      tft.println("Hello World!");
      tft.setTextColor(ST7735_GREEN);
      tft.setTextSize(3);
      tft.println("Hello World!");
      tft.setTextColor(ST7735_BLUE);
      tft.setTextSize(4);
      tft.print(1234.567);
      delay(1500);
      tft.setCursor(0, 0);
      tft.fillScreen(ST7735_BLACK);
      tft.setTextColor(ST7735_WHITE);
      tft.setTextSize(0);
      tft.println("Hello World!");
      tft.setTextSize(1);
      tft.setTextColor(ST7735_GREEN);
      tft.print(p, 6);
      tft.println(" Want pi?");
      tft.println(" ");
      tft.print(8675309, HEX); // print 8,675,309 out in HEX!
      tft.println(" Print HEX!");
      tft.println(" ");
      tft.setTextColor(ST7735_WHITE);
      tft.println("Sketch has been");
      tft.println("running for: ");
      tft.setTextColor(ST7735_MAGENTA);
      tft.print(millis() / 1000);
      tft.setTextColor(ST7735_WHITE);
      tft.print(" seconds.");
    }
     
    void mediabuttons() {
      // play
      tft.fillScreen(ST7735_BLACK);
      tft.fillRoundRect(25, 10, 78, 60, 8, ST7735_WHITE);
      tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_RED);
      delay(500);
      // pause
      tft.fillRoundRect(25, 90, 78, 60, 8, ST7735_WHITE);
      tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_GREEN);
      tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_GREEN);
      delay(500);
      // play color
      tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_BLUE);
      delay(50);
      // pause color
      tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_RED);
      tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_RED);
      // play color
      tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_GREEN);
    }


Once the media buttons (play and pause) symbols begin their inverting cycle, the program is done (it just loops over inverting the screen)!
9. Using the Adafruit LCD display
Tangible Computing / Version 3.20 2013-03-25