Using drawRect doesn't work

Hi.

I am rendering to a display (mcufriend shield 9335) using Mcufriend_kbv llibrary to render and TouchScreen to detect screen signals, so i fill a rect that works as a button.

My idea is that when the button is pressed appears a white rect surrounding the button, so, the touch signal is catched with correct coordinates but the rect is not draw.

The code is:

#include <Adafruit_GFX.h>
#include <UTFTGLUE.h>
#include <TouchScreen.h>

#define YP A1
#define YM 7
#define XM A2
#define XP 6

#define TS_MINX 140
#define TS_MAXX 900
#define TS_MINY 120
#define TS_MAXY 940


UTFTGLUE myGLCD(0x9327,A2,A1,A3,A4,A0);
int widh, heigh;

// Touch Screen
TouchScreen ts(XP, YP, XM, YM, 300);
int pointx, pointy;


void setup() {
  myGLCD.InitLCD();
  myGLCD.clrScr();  
}

void loop() {
  showButton();
}

void showButton(){
  myGLCD.setColor(255, 35, 1); // Color button
  myGLCD.fillRect(100, 100, 200, 200); // Fill the red Rect
  myGLCD.setBackColor(255, 35, 1);

  myGLCD.setColor(255, 255, 255);
  myGLCD.print("BUTTON", 110, 110);
  
  while(true){
    readButton();
  }
}

void readButton (){
  // Read the point
  theTouchReads();

 // Ask if point of read is to the button
  if((pointx >= 100 && pointx <= 200) && (pointy >= 100 && pointy <=200)){
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawRect(100, 100, 200, 200); // Draw a white rect, no fill
    delay(2000);
    myGLCD.setColor(255, 35, 1);
    myGLCD.drawRect(100, 100, 200, 200); // "Delete" the white rect
  }
  pointx = pointy = 0;
}

void theTouchReads(){
  TSPoint p = ts.getPoint();
  
  // Si la presion esta en el rango
  if (p.z > 100 && p.z < 1000) {
    pointx = map(p.x, TS_MINX, TS_MAXX, 320, 0);
    pointy = map(p.y, TS_MINY, TS_MAXY, 0, 240);
  }
}

Why the drawRect doesn't works here?

Thanks,.

These Shields have Touch Panels that share pins with the TFT controller.
You were lucky. The TFT controller would have crashed. Most people get a white screen if you do not reset pinMode() for YP, XM after each access of the TouchScreen.

...
void setup() {
  Serial.begin(9600);   //.kbv for Debug
  myGLCD.InitLCD();
  myGLCD.clrScr();  
}
...
void theTouchReads(){
  TSPoint p = ts.getPoint();
  pinMode(XM, OUTPUT);  // .kbv Touch Pins are shared with TFT
  pinMode(YP, OUTPUT);  // .kbv so you must restore to OUTPUT
  // .kbv for Debug,   watch your Touch points
  Serial.println("p.x=" + String(p.x) + " p.y=" + String(p.y) + "   ");

  // Si la presion esta en el rango
  if (p.z > 100 && p.z < 1000) {
//    pointx = map(p.x, TS_MINX, TS_MAXX, 320, 0);
//    pointy = map(p.y, TS_MINY, TS_MAXY, 0, 240);
    // .kbv map Touch values to screen coordinates
    pointx = map(p.x, TS_MINX, TS_MAXX, 0, 320);
    pointy = map(p.y, TS_MINY, TS_MAXY, 0, 240);
  }
}

I still reckon it is crazy to use UTFT methods when the Adafruit methods are easier:

#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <TouchScreen.h>

#define YP A1
#define YM 7
#define XM A2
#define XP 6

// .kbv my Touch screen has these values in Landscape
#define TS_MINX 140 //LEFT
#define TS_MAXX 900 //RIGHT
#define TS_MINY 940 //120 //TOP
#define TS_MAXY 120 //940 //BOT


MCUFRIEND_kbv tft;
int widh, heigh;

// Touch Screen
TouchScreen ts(XP, YP, XM, YM, 300);
int pointx, pointy;

#define ORANGE   0xF900   //weird (255, 35, 1) colour
#define WHITE    0xFFFF
#define BLACK    0x0000

void setup() {
    Serial.begin(9600);   //.kbv for Debug
    tft.begin(tft.readID());
    tft.setRotation(1);   //Landscape
    tft.fillScreen(BLACK);
}

void loop() {
    showButton();
}

void showButton() {
    tft.fillRect(100, 100, 100, 100, ORANGE); // Fill the red Rect
    tft.setTextColor(WHITE);
    tft.setCursor(110, 110);
    tft.print("BUTTON");

    while (true) {
        readButton();
    }
}

void readButton () {
    // Read the point
    theTouchReads();

    // Ask if point of read is to the button
    if ((pointx >= 100 && pointx <= 200) && (pointy >= 100 && pointy <= 200)) {
        tft.drawRect(100, 100, 100, 100, WHITE); // Draw a white rect, no fill
        delay(2000);
        tft.drawRect(100, 100, 100, 100, ORANGE); // "Delete" the white rect
    }
    pointx = pointy = 0;
}

void theTouchReads() {
    TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);  // .kbv Touch Pins are shared with TFT
    pinMode(YP, OUTPUT);  // .kbv so you must restore to OUTPUT
    // .kbv for Debug,   watch your Touch points
    Serial.println("p.x=" + String(p.x) + " p.y=" + String(p.y) + "   ");

    // Si la presion esta en el rango
    if (p.z > 100 && p.z < 1000) {
        // .kbv map Touch values to screen coordinates
        pointx = map(p.x, TS_MINX, TS_MAXX, 0, 320);
        pointy = map(p.y, TS_MINY, TS_MAXY, 0, 240);
    }
}

Here is a simple example that uses multiple buttons with the Adafruit_GFX_Button class:

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

//Y-plus, Y-minus, X-plus, X-minus
#define YP A2 //A3  //A2  //A3  // A1
#define XM A1 //A2  //A1  //A2  // A2
#define YM 6  //9   //6   //9   // 7
#define XP 7  //8   //7   //8   // 6
//              teee  kbv   teee   default Touch wiring
#define TS_LEFT 900 //200 //920
#define TS_RT   139 //920 //200
#define TS_TOP  944 //120 //940
#define TS_BOT  140 //940 //120

//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

MCUFRIEND_kbv tft;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
Adafruit_GFX_Button btns[12];
char legends[12] = "123456789*0#";

int Xposn, Yposn, tftpos, tftwid, tftht; //.kbv use intuitive names for globals

void setup()
{
    int x, y, i;
    char msg[2] = "X";          //initialises msg[1] = 0 (NUL)
    tft.begin(tft.readID());    //use the correct controller
    tft.setRotation(0);         //Portrait
    tftwid = tft.width();
    tftht = tft.height();
    tft.fillScreen(BLACK);
    // note that Button x,y is the CENTRE and not the TLHC.
    for (y = 0, i = 0; y < 4; y++) {
        for (x = 0; x < 3; x++) {
            msg[0] = legends[i];
            btns[i].initButton(&tft, 56 + x * 64, 90 + y * 64, 60, 60,
                               WHITE, CYAN, BLACK, msg, 4);
            btns[i++].drawButton(false);
        }
    }
}

bool getPress()
{
    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
    if (p.z > 10 && p.z < 1000) {
        //map TSPoint to 240 X 320 pixels
        Xposn = map(p.x, TS_LEFT, TS_RT, 0, tftwid); //.kbv makes sense to me
        Yposn = map(p.y, TS_TOP, TS_BOT, 0, tftht);
        return true;
    }
    return false;
}

void loop()
{
    static int old = 0;
    Adafruit_GFX_Button *b;               //pointer to the real button
    if (getPress()) {
        for (int i = 0 ; i < 12; i++) {   //check all buttons
            b = &btns[i];
            b->press(b->contains(Xposn, Yposn));
            b->drawButton(b->isPressed()); //update current state
            if (b->justPressed()) {
                if (tftpos >= tftwid - 12) { //last printable posn
                    tft.fillRect(0, 0, tftwid, 16, BLACK); //erase
                    tftpos = 0;           //and start again
                }
                tft.setCursor(tftpos, 0); //reset text posn, color, size
                tft.setTextSize(2);
                tft.setTextColor(YELLOW);
                tft.print(legends[i]);
                tftpos += 12;             // 2x System font width
                old = i;
            }
        }
    }
    else {
        b = &btns[old];                   //last button is released
        b->press(false);
        if (b->justReleased()) b->drawButton(false);
    }
}

The Adafruit_GFX_Button class is really nice to use. The TouchScreen library less so.

David.

Hi David.

Thanks a lot for your response, i added the code that updates the pinMode to XM and YP pins, that works pretty fine.

Also i tried your Sugguestion about Adafruit_GFX_Button class but the class arent recognized as a type, i tried with the library that i can found in Github: https://codeload.github.com/adafruit/Adafruit-GFX-Library/zip/master

Then i tried with to use the Adafruit methods and use your code as example, this render well but i was confused, the mapping of the touch screen signal seems rare.

So i changed the lines

// .kbv map Touch values to screen coordinates
pointx = map(p.x, TS_MINX, TS_MAXX, 0, 320);
pointy = map(p.y, TS_MINY, TS_MAXY, 0, 240);

to

// .kbv map Touch values to screen coordinates
pointx = map(p.x, TS_MINX, TS_MAXX, 320, 0);
pointy = map(p.y, TS_MINY, TS_MAXY, 240, 0);

And that works fine for me.

Thanks for help.

Look at the Serial Terminal. See what Touch is actually returning. i.e. what your TS_LEFT and TS_RT values are.

Then say

pointx =map(p.x, TS_LEFT, TS_RT, 0, 320);

in other words use a consistent approach to obtaining the screen coordinates.

Of course you can call things TS_MINX or TS_LEFT. You can get the same result by exchanging left and right screen values. My head starts hurting though.

David.