How to Make GUI Using Microcontroller and TFT LCD

by StickPaperTime in Circuits > Microcontrollers

4156 Views, 2 Favorites, 0 Comments

How to Make GUI Using Microcontroller and TFT LCD

cover.jpg

Hi !!! In this instructables we will learn how to make GUI with TFT LCD and some microcontroller. For this project I will use ESP32 as microcontroller and ILI9341 as LCD display

Step 1 : Things You Need

For this project u will need :

  • TFT LCD 2.4
  • ESP32
  • 1 LED
  • Arduino IDE and the correct libraries
  • Jumper

Step 2 : Design the GUI

Step 2 - cover.png
Step 2 - cover anim.png
Step 2 - cover count.png
Step 2 - cover LED.png

In this step I will design some GUI with photoshop for applying to TFT LCD, the design you can see at the picture. The layout page construct by 4 page, each page have own function.

You can make your own design with other software image but in this instructables I made with photoshop and you can download file PSD right here.

Step 3 : Wiring the Component

Step 3 - Schematic.PNG

Now connecting TFT LCD and some LED to ESP32.as picture above, since ILI9341 using logic 3.3 V u can directly connect to ESP32 if u are using microcontroller that are use 5V connect VCC and LED to 3.3V.

here the list of connection :

  1. CS - D15
  2. RESET - D4
  3. DC - D2
  4. MOSI - D23
  5. SCK - D16
  6. LED - 3.3V
  7. MISO - D19
  8. SCK - D16
  9. T_CS - D21
  10. MOSI - D23
  11. MISO - D19
  12. LED - D13

note : the list pin are set up in library you can change the pin number in user_setup at libraries folder and if u are using touch screen don't forget to uncomment TOUCH_CS in user_setup.

Step 4 : Preparing Code to the Display

Step 4 - Converting Color.PNG

Before we look at the code we need to import the library, there are a few of libraries if you check on github but in this project I use TFT_eSPI for the display. Here the link library that I use in this project :

  1. TFT_eSPI
  2. elapsedMillis

After the library installed now import the library

#include <elapsedMillis.h>
#include <TFT_eSPI.h>

elapsedMillis MM;
TFT_eSPI tft = TFT_eSPI();

In this project I add two custom color and you can add new color but you have convert it first to convert the color to RGB565. Here is the link to convert color into RGB565 here. The reason why I convert the color RGB to RGB565 because ILI9341 only support 16 bit color.

And this new color that I used :

#define TFT_REDARK 0x60C3
#define TFT_RED2 0xA0C3
#define TFT_GRAY 0x738E

Next I used free mono bold which is the font you can find inside the library to use the font u have to import first.

#define FMB12 &FreeMonoBold12pt7b
#define FMB18 &FreeMonoBold18pt7b

Note : You can put the custom color and font above void setup.

Now we are going to write the code inside void setup, in this case I want the display rotate to vertical then u have to set the rotation but how ? to rotate u can use this function setRotation() this function allow to rotate the display to make it vertical set to 1/3. After set the rotation you have to swap the color byte order when rendering otherwise the color will be mess to set the color use this function setSwapBytes() and set to true. Don't forget to initialize the LCD by writing init().

  tft.init();
  tft.setRotation(3);
  tft.setSwapBytes(true);

Next declare variable int page; above void setup

Step 5 : Writing the Display Code

Step 5 - display.jpg
Step 5 - count button.jpg
Step 5 - animation.jpg
Step 5 - LED.jpg
Step 5 - structure button.png

To make layout you have to make a new function in this project there are 4 pages, first we are going to make the first page. The first page consist with 4 button and the title GUI.

As you can see the picture above is the structure of button, to draw the button write this code :

  tft.fillRect(x,y,104,44, TFT_BLACK);//Stroke line
  tft.fillRect(x,y,100,40, TFT_RED2);//fill Rect
  tft.fillRect(x,y,2,40, TFT_BLACK);//gap line
  tft.fillRect(x,y,4,40, TFT_REDARK);//Shadow<br>

The code above is to draw a button, too lazy to write the button ? you can use pushImage function to make button using image but the image have to convert into c array first watch this and you can download the file button that I used after convert it into c array.

After download the file resources.h now put inside the same folder of your project now re-open arduino IDE project there will be file header don't forget to include the header in the top of code. Next to make button just write pushImage(x,y,w,h,image,transparent color).

tft.pushImage(x,y,104,44,button,TFT_WHITE);

fill the x and y with coordinate number that you want put, in this case you can check picture in step 2 the coordinate x and y. Next make a text inside the button but first u need to specify which font and color text that u want to use here is the function to change the font setFreeFont("fill the font") and setTextColor("the color of the text",the color of background") after that you can write the text by using drawString("Text",x,y,size).

Next the code for first page will be like this.

void page_1(){
  tft.fillRect(0,0,320,240, TFT_WHITE);//fill the display to white
  
  tft.setTextColor(TFT_BLACK, TFT_RED2);//set the text to black and red background
  tft.setFreeFont(FMB12);//set font with FMB12
  
  tft.fillRect(x,y,104,44, TFT_BLACK);//Stroke line
  tft.fillRect(x,y,100,40, TFT_RED2);//fill Rect
  tft.fillRect(x,y,2,40, TFT_BLACK);//gap line
  tft.fillRect(x,y,4,40, TFT_REDARK);//Shadow
  tft.drawString("COUNT",33,28,1);//write the text

  tft.pushImage(18,88,104,44,button,TFT_WHITE);//draw button with push image function
  tft.drawString("LED",46,101,1);
  
  tft.pushImage(18,160,104,44,button,TFT_WHITE);
  tft.drawString("ANIM",46,172,1);
  
  /* make a title */
  tft.setTextColor(TFT_BLACK, TFT_WHITE);
  tft.setFreeFont(FMB18);   
  tft.drawString("SIMPLE",138,18);
  tft.drawString("GUI!",224,53);

  page = '1';//state of page

Next make some another page with same step and add one number in page and also put page_1() in void setup.

Note : x, y coordinate you can see in PSD step 2

Downloads

Step 6 : Adding Touch Screen Function

Now we are going to add some touch screen function, if you intend to use touch screen function you can read this step but if don't just skip this.

first before doing touch screen you need to calibrate the screen by adding code below and put touch_calibrate into void setup();

/*add this above void setup*/
#include "FS.h"// add this in top of the code
#define CALIBRATION_FILE "/TouchCalData3"
#define REPEAT_CAL true //set false if you already calibrate or want to stop calibrate  

/*add this inside void setup*/
touch_calibrate

/*put this function at bottom of the code, this code not made by me btw*/
void touch_calibrate()
{
  uint16_t calData[5];
  uint8_t calDataOK = 0;

  // check file system exists
  if (!SPIFFS.begin()) {
    Serial.println("Formatting file system");
    SPIFFS.format();
    SPIFFS.begin();
  }

  // check if calibration file exists and size is correct
  if (SPIFFS.exists(CALIBRATION_FILE)) {
    if (REPEAT_CAL)
    {
      // Delete if we want to re-calibrate
      SPIFFS.remove(CALIBRATION_FILE);
    }
    else
    {
      File f = SPIFFS.open(CALIBRATION_FILE, "r");
      if (f) {
        if (f.readBytes((char *)calData, 14) == 14)
          calDataOK = 1;
        f.close();
      }
    }
  }

  if (calDataOK && !REPEAT_CAL) {
    // calibration data valid
    tft.setTouch(calData);
  } else {
    // data not valid so recalibrate
    tft.fillScreen(TFT_BLACK);
    tft.setCursor(20, 0);
    tft.setTextFont(2);
    tft.setTextSize(1);
    tft.setTextColor(TFT_WHITE, TFT_BLACK);

    tft.println("Touch corners as indicated");

    tft.setTextFont(1);
    tft.println();

    if (REPEAT_CAL) {
      tft.setTextColor(TFT_RED, TFT_BLACK);
      tft.println("Set REPEAT_CAL to false to stop this running again!");
    }

    tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);

    tft.setTextColor(TFT_GREEN, TFT_BLACK);
    tft.println("Calibration complete!");

    // store data
    File f = SPIFFS.open(CALIBRATION_FILE, "w");
    if (f) {
      f.write((const unsigned char *)calData, 14);
      f.close();
    }
  }
}

Next move to void loop() to add touch screen you need to write code x, y when ever the screen pressed. To make the ESP32 read the press screen add this code :

    uint16_t x, y;
    int pressed = tft.getTouch(&x,&y);

The code above allow you to collect data from LCD when ever touched, in this step I will show you to add some touch screen function in page_1(). First remember when I told you to add some variable page with some number, so the page variable is representing of current page In page_1() the value of page is 1 then we need to write page 1 in void loop().

  if(page == '1'){   
    uint16_t x, y;
    int pressed = tft.getTouch(&x,&y);
    if(pressed){
      if((x > 18) && (x < 122)){
        if((y > 18) && (y < 62)){
          page_Count();}}}

The code above mean when page equal with 1 then process or the current page now is 1. To collect data when pressed the screen use function getTouch(). After the data save in variable x and y now you have to measure first x coordinate button, first y coordinate , last x coordinate button, and last y coordinate button. This mean when the screen get pressed with following coordinate then if function will execute the process, in code above button count get pressed then the process next is moving display into page_count.

Here the full code for touch screen in page 1 :

  if(page == '1'){ //if current is the first page then execute this   
    uint16_t x, y;
    int pressed = tft.getTouch(&x,&y);
    if(pressed){/* if pressed button count then move to page count*/
      if((x > 18) && (x < 122)){
        if((y > 18) && (y < 62)){
          page_Count();}}}
      
    if(pressed){/* if pressed button LED then move to page count*/
      if((x > 18) && (x < 122)){
        if((y > 88) && (y < 132)){
          page_LED();}}}

    if(pressed){/* if pressed button Animation then move to page count*/
      if((x > 18) && (x < 122)){
        if((y > 160) && (y < 204)){
          page_Animation();}}}  
   }  

Now it's done you can repeat in every page and button.

Note : every rotate screen you need to re-calibrate.

Downloads

Step 7 : Optional

Actually this step is optional if u want to learn print text or adding some animation or you can just skip this.

Printing Text

if you already download full the project file in previous step you will see in page 2 inside void loop I add

tft.fillRect(130,90,207,40,TFT_WHITE);

In page 2 there are 3 button back, +, and - whenever you press + button then the screen will add some number in middle of the screen it happens too when you press - button. But what is meaning tft.fillRect(130,90,207,40,TFT_WHITE) that function to replace the previous text if you try remove the code every time you press + and - button the text will print but not replace the old of the text that's why I add fillRect function to make the screen remove the old text and replacing to the new one.

Adding Animation

This step is for page 4 or page_Animation(), if you look at the void loop in page 4 there are anim_state condition if you pressed button "tap" then some animation will appear to the screen. To make animation running you need millis function to make it moves, with millis we can mainpulation microcontroller so that can make run multitasking to display page_animation() and display animation. Here I make two options to make animation below you can chose with millis or eclipsedMillis. The different is in eclipsedMillis you can reset the value to 0 even loop not over.

/*with millis*/
int current_time = millis();
int previous_time = 0;
    if(anim_state == '1'){
      if(current_time - previous_time > 40){
        tft.pushImage(150, 100,animation_width  , animation_height, walk[j]);
        j++;
        delay(40);
        if(j == 4){
          j = 0;
          }}}
/*with eclipsedMillis*/
    if(anim_state == '1'){
      if(MM>aniD){
        tft.pushImage(150, 100,animation_width  , animation_height, walk[j]);
        j++;
        delay(anim_speed);
        if(j == 4){
          j = 0;
          }
        MM = 0;}}

Thanks

5yje0c.jpg

Thank you for reading this project this is my first time writing in instructables and I'm not good in writing skills in english T-T I'm really sorry if there are some mistake with my write hope this tutorial will helpful.