Go Down

Topic: White Screen After Button Press 2.4" TFT LCD [Solved] (Read 167 times) previous topic - next topic

Teee

Hi all,
New to the Arduino world. I have a 2.4" TFT LCD that uses the 0x9341 driver and I'm using an Uno.

The program below draws button 1 on the bottom center of the screen, once pressed, it should "clear the screen" (tft.fillScreen(BLACK)) and draw a button 2 near the top left part of the screen. If button 2 is pressed then the screen is cleared and button 1 is redrawn at the bottom center of the screen once again.

The problem is, when button 1 is pressed, the screen goes white instead of painting the black background and button 2. How do I get rid of the white screen?

Things to note:

I had to change
Code: [Select]
#define TS_MINX 150

to
Code: [Select]
#define TS_MINX 200

in order to get touchscreen feedback from the entire screen. I tested this with the tftpaint program.

Here is the full code:

Code: [Select]
#include <Adafruit_TFTLCD.h>
#include <Adafruit_GFX.h>
#include <TouchScreen.h>



#define LCD_CS A3   
#define LCD_CD A2   
#define LCD_WR A1   
#define LCD_RD A0   
#define LCD_RESET A4

//Y-plus, Y-minus, X-plus, X-minus
#define YP A3  // A1
#define XM A2  // A2
#define YM 9   // 7
#define XP 8   // 6

//Color definitions
#define BLACK       0x0000     
#define NAVY        0x000F     
#define DARKGREEN   0x03E0     
#define DARKCYAN    0x03EF     
#define MAROON      0x7800     
#define PURPLE      0x780F     
#define OLIVE       0x7BE0
#define LIGHTGREY   0xC618     
#define DARKGREY    0x7BEF     
#define BLUE        0x001F     
#define GREEN       0x07E0     
#define CYAN        0x07FF     
#define RED         0xF800     
#define MAGENTA     0xF81F     
#define YELLOW      0xFFE0     
#define WHITE       0xFFFF     
#define ORANGE      0xFD20     
#define GREENYELLOW 0xAFE5     
#define PINK        0xF81F
     

#define TS_MINX 200
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940

//Change driver here
#define DRIVER 0x9341

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);   



void setup(){
  Serial.begin(9600);
  delay(500);
  tft.reset();
  tft.begin(DRIVER);

 //Draw Button 1 on screen
  drawButton("Btn 1",55, 272, 130, 45, 3);   
 
}

void loop(){
 
  boolean touched = ts.isTouching();
  //If screen is touched
  if (touched){
    //get point on touchscreen that has been touched
    TSPoint p = ts.getPoint();

    //map touchscreen to 240 X 320 pixels
    p.x = map(p.x, TS_MINX, TS_MAXX, 0,240);
    p.y = map(p.y, TS_MINY, TS_MAXY, 0,320);

    //If region of Button 1 is touched
    if((p.y > 272 && p.y < 317 && p.x > 55 && p.x < 185))
    {
      //Redraw screen showing ONLY Button 2
      drawButton("Btn 2", 5, 5, 90, 60, 2);
    }
    //If region of Button 2 is touched
    if (p.y > 5 && p.y < 65 && p.x > 5 && p.x < 95)
    {
      //Redraw screen showing ONLY Button 1
      drawButton("Btn 1",55, 272, 130, 45, 3);
    }
  }
}

//Draws button on screen
void drawButton(String name, int xLoc, int yLoc, uint8_t width, uint8_t height,
               uint8_t textSize){
  //wipe screen with black background
  tft.fillScreen(BLACK);
  //Draw rounded rect
  tft.fillRoundRect(xLoc, yLoc, width, height, 4, CYAN);
  tft.setTextSize(textSize);
  tft.setTextColor(BLACK); 
  //sets cursor to start writing text from.. (x, y)
  //x and y are calculated based on textsize,length of name, etc to centralize text on button
  tft.setCursor(xLoc+(width-(5.65*textSize)*name.length())/2, yLoc+(height-(7*textSize))/2);
  tft.println(name);
}



Any help would be greatly appreciated.  :)

david_prentice

The Touch pins are shared with the LCD pins on many Uno shields.

The <TouchScreen.h> library leaves the analog pins in INPUT mode after you call getPoint() method.
If you add the pinMode() lines after every getPoint() call,   the TFT LCD will be happy. e.g.
Code: [Select]

        TSPoint p = ts.getPoint();
        pinMode(YP, OUTPUT);     //.kbv these pins are shared with TFT
        pinMode(XM, OUTPUT);     //.kbv these pins are shared with TFT


My display uses completely different Touch pins to you.   I tested it with my values.   I have put "your" Touch wiring values back into the sketch:
Code: [Select]

#include <Adafruit_TFTLCD.h>
#include <Adafruit_GFX.h>
#include <TouchScreen.h>        //.kbv ? missing isTouching() method

#define LCD_CS A3               //.kbv mcufriend shields are the same
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4

//Y-plus, Y-minus, X-plus, X-minus
#define YP A3  //A2  //A3  // A1
#define XM A2  //A1  //A2  // A2
#define YM 9   //6   //9   // 7
#define XP 8   //7   //8   // 6
//         teee  kbv   teee   default Touch wiring

//Color definitions
#define BLACK       0x0000
#define NAVY        0x000F
#define DARKGREEN   0x03E0
#define DARKCYAN    0x03EF
#define MAROON      0x7800
#define PURPLE      0x780F
#define OLIVE       0x7BE0
#define LIGHTGREY   0xC618
#define DARKGREY    0x7BEF
#define BLUE        0x001F
#define GREEN       0x07E0
#define CYAN        0x07FF
#define RED         0xF800
#define MAGENTA     0xF81F
#define YELLOW      0xFFE0
#define WHITE       0xFFFF
#define ORANGE      0xFD20
#define GREENYELLOW 0xAFE5
#define PINK        0xF81F

#define TS_LEFT 200 //920
#define TS_TOP  120 //940
#define TS_RT   920 //200
#define TS_BOT  940 //120
//              teee  kbv calibration values

//Change driver here
#define DRIVER 0x9341

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

void setup() {
    Serial.begin(9600);
    delay(500);
    tft.reset();
    tft.begin(DRIVER);

    //Draw Button 1 on screen
    drawButton("Btn 1", 55, 272, 130, 45, 3);
}

void loop()
{
    int Xposn, Yposn;            //.kbv use intuitive names for screen posn
    boolean touched = ts.isTouching();  //.kbv method missing from library
    //If screen is touched
    if (touched) {
        //get point on touchscreen that has been touched
        TSPoint p = ts.getPoint();
        pinMode(YP, OUTPUT);     //.kbv these pins are shared with TFT
        pinMode(XM, OUTPUT);     //.kbv these pins are shared with TFT
        //map touchscreen to 240 X 320 pixels
        Xposn = map(p.x, TS_LEFT, TS_RT, 0, 240); //.kbv makes sense to me
        Yposn = map(p.y, TS_TOP, TS_BOT, 0, 320);

        //If region of Button 1 is touched
        if ((Yposn > 272 && Yposn < 317 && Xposn > 55 && Xposn < 185))
        {
            //Redraw screen showing ONLY Button 2
            drawButton("Btn 2", 5, 5, 90, 60, 2);
        }
        //If region of Button 2 is touched
        if (Yposn > 5 && Yposn < 65 && Xposn > 5 && Xposn < 95)
        {
            //Redraw screen showing ONLY Button 1
            drawButton("Btn 1", 55, 272, 130, 45, 3);
        }
    }
}

//Draws button on screen
void drawButton(String name, int xLoc, int yLoc, uint8_t width, uint8_t height,
                uint8_t textSize) {
    //wipe screen with black background
    tft.fillScreen(BLACK);
    //Draw rounded rect
    tft.fillRoundRect(xLoc, yLoc, width, height, 4, CYAN);
    tft.setTextSize(textSize);
    tft.setTextColor(BLACK);
    //sets cursor to start writing text from.. (x, y)
    //x and y are calculated based on textsize,length of name, etc to centralize text on button
    tft.setCursor(xLoc + (width - (5.65 * textSize)*name.length()) / 2, yLoc + (height - (7 * textSize)) / 2);
    tft.println(name);
}

I hope that this runs ok for you.    I have also changed the names of some macros and variables.    I hope that the more intuitive names make it easier to understand.

Incidentally,  the new Adafruit_GFX library comes with Adafruit_GFX_Button class.

David.

david_prentice

I had a go with the Adafruit_GFX_Button class.
You use exactly the same #includes and #defines for your TFT and TouchScreen but the structure of your setup() and loop() is simpler:
Code: [Select]

Adafruit_GFX_Button btn1;
Adafruit_GFX_Button btn2;

void setup()
{
    Serial.begin(9600);
    delay(500);
    tft.reset();
    tft.begin(DRIVER);
    tft.setRotation(0);
    tft.fillScreen(BLACK);
    // note that Button x,y is the CENTRE and not the TLHC.
    btn1.initButton(&tft, 120, 292, 130, 45, WHITE, CYAN, BLACK, "Btn 1", 3);
    btn2.initButton(&tft,  45,  35,  90, 60, WHITE, CYAN, BLACK, "Btn 2", 2);

    btn1.drawButton(false);         //Draw Button 1 on screen
}

void loop()
{
    int Xposn, Yposn;               //.kbv use intuitive names for screen posn

    if (ts.isTouching()) {          //If screen is touched
        TSPoint p = ts.getPoint();  //point on touchscreen that has been touched
        pinMode(YP, OUTPUT);        //.kbv these pins are shared with TFT
        pinMode(XM, OUTPUT);        //.kbv these pins are shared with TFT
        //map TSPoint to 240 X 320 pixels
        Xposn = map(p.x, TS_LEFT, TS_RT, 0, 240); //.kbv makes sense to me
        Yposn = map(p.y, TS_TOP, TS_BOT, 0, 320);

        btn1.press(btn1.contains(Xposn, Yposn));  //update button state
        btn2.press(btn2.contains(Xposn, Yposn));  //update button state

        if (btn1.isPressed())
        {
            //Redraw screen showing ONLY Button 2
            tft.fillScreen(BLACK);
            btn2.drawButton();
        }
        if (btn2.isPressed())
        {
            //Redraw screen showing ONLY Button 1
            tft.fillScreen(BLACK);
            btn1.drawButton();
        }
    }
}

An alternative loop() that mimics your original logic:
Code: [Select]

void loop()
{
    int Xposn, Yposn;            //.kbv use intuitive names for screen posn

    //If screen is touched
    if (ts.isTouching()) {
        TSPoint p = ts.getPoint();  //point on touchscreen that has been touched
        pinMode(YP, OUTPUT);        //.kbv these pins are shared with TFT
        pinMode(XM, OUTPUT);        //.kbv these pins are shared with TFT
        //map touchscreen to 240 X 320 pixels
        Xposn = map(p.x, TS_LEFT, TS_RT, 0, 240); //.kbv makes sense to me
        Yposn = map(p.y, TS_TOP, TS_BOT, 0, 320);

        //If region of Button 1 is touched
        if (btn1.contains(Xposn, Yposn))
        {
            //Redraw screen showing ONLY Button 2
            tft.fillScreen(BLACK);
            btn2.drawButton();
        }
        //If region of Button 2 is touched
        if (btn2.contains(Xposn, Yposn))
        {
            //Redraw screen showing ONLY Button 1
            tft.fillScreen(BLACK);
            btn1.drawButton();
        }
    }
}


David.

Teee

Thank you so much David! Such a small thing has been wrecking my brain for the past few days. I didn't realize there was a button class in the GFX library. Thanks for sharing  :)

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy