ESP32 with 3,5" 320x480 TFT

Helo everyone !

I'm using an 3.5" touch display with ESP32-WROOM and I have loaded the file "MCUFRIEND_kbv/button simple", after running the "TouchScreen_Calibr_native.ino" with the following result:

const int XP=27,XM=15,YP=4,YM=14; //320x480 ID=0x9486
const int TS_LEFT=919,TS_RT=131,TS_TOP=947,TS_BOT=49;

PORTRAIT CALIBRATION 320 x 480
x = map(p.x, LEFT=919, RT=131, 0, 320)
y = map(p.y, TOP=947, BOT=49, 0, 480)

LANDSCAPE CALIBRATION 480 x 320
x = map(p.y, LEFT=947, RT=49, 0, 480)
y = map(p.x, TOP=131, BOT=919, 0, 320)

I made the appropriate substitutions in the main file, and the 3.5" display shows me only a red rectangle with two buttons underneath, one "ON" and one "OFF," but both do not react to pushing them, causing everything to remain unchanged.
I honestly had been expecting any graphical reaction.
Where am I going wrong or omitting something?

Below, I enclose the code "Button_simple.ino"

Thank you for your help,

Roberto

</>


#if 1

#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include <TouchScreen.h>
#define MINPRESSURE 200
#define MAXPRESSURE 1000

// ALL Touch panels and wiring is DIFFERENT
// copy-paste results from TouchScreen_Calibr_native.ino
const int XP = 27, XM = 15, YP = 4, YM = 14; //ID=0x9341
const int TS_LEFT = 919, TS_RT = 131, TS_TOP = 947, TS_BOT = 49;

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

Adafruit_GFX_Button on_btn, off_btn;

int pixel_x, pixel_y; //Touch_getXY() updates global vars
bool Touch_getXY(void)
{
TSPoint p = ts.getPoint();
pinMode(YP, OUTPUT); //restore shared pins
pinMode(XM, OUTPUT);
digitalWrite(YP, HIGH); //because TFT control pins
digitalWrite(XM, HIGH);
bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
if (pressed) {
pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
}
return pressed;
}

#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

void setup(void)
{
Serial.begin(9600);
uint16_t ID = tft.readID();
Serial.print("TFT ID = 0x");
Serial.println(ID, HEX);
Serial.println("Calibrate for your Touch Panel");
if (ID == 0xD3D3) ID = 0x9486; // write-only shield
tft.begin(ID);
tft.setRotation(0); //PORTRAIT
tft.fillScreen(BLACK);
on_btn.initButton(&tft, 60, 200, 100, 40, WHITE, CYAN, BLACK, "ON", 2);
off_btn.initButton(&tft, 180, 200, 100, 40, WHITE, CYAN, BLACK, "OFF", 2);
on_btn.drawButton(false);
off_btn.drawButton(false);
tft.fillRect(40, 80, 160, 80, RED);
}

/* two buttons are quite simple
*/
void loop(void)
{
bool down = Touch_getXY();
on_btn.press(down && on_btn.contains(pixel_x, pixel_y));
off_btn.press(down && off_btn.contains(pixel_x, pixel_y));
if (on_btn.justReleased())
on_btn.drawButton();
if (off_btn.justReleased())
off_btn.drawButton();
if (on_btn.justPressed()) {
on_btn.drawButton(true);
tft.fillRect(40, 80, 160, 80, GREEN);
}
if (off_btn.justPressed()) {
off_btn.drawButton(true);
tft.fillRect(40, 80, 160, 80, RED);
}
}
#endif

If you are posting code please use proper "Code Window" e.g. select text. click </> icon.

Adafruit Touchscreen.h library does not work very well on ESP32.
Use Touchscreen_kbv.h (from the Calibration sketch)

Historically Adafruit Touchscreen.h would not even compile on ESP32.
If it compiles now I will have a look at "why" it does not work. (perhaps later)

David.

Sure enough. Afafruit's TouchScreen.h library compiles on ESP32 now.

TouchScreen.h assumes 10-bit analogRead() like on Uno, Mega2560, ...
But ESP32 native analogRead() is 12-bit.

All that you need to do is call analogReadResolution(10); in setup()
This applies to ARM targets too, e.g. Zero, Due, ...

To be on the safe side:

#if defined(__arm__) || defined(ESP32)
    analogReadResolution(10);
#endif

David.

Dear David,
please excuse me if I try your patience, but no I can't get the sketches on your site "...examples/button_simple/button_simple.ino" to work.
I don't know where I am wrong or what I omit, but I have been trying each combination in uselessly for many hours.
From the calibration test I get:

const int XP=27,XM=15,YP=4,YM=14; //320x480 ID=0x9486
const int TS_LEFT=919,TS_RT=131,TS_TOP=947,TS_BOT=49;

PORTRAIT CALIBRATION 320 x 480
x = map(p.x, LEFT=919, RT=131, 0, 320)
y = map(p.y, TOP=947, BOT=49, 0, 480)

LANDSCAPE CALIBRATION 480 x 320
x = map(p.y, LEFT=947, RT=49, 0, 480)
y = map(p.x, TOP=131, BOT=919, 0, 320)

But I can't insert it and get it to work, ad my code is:

#if 1

#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include <TouchScreen.h>
#define MINPRESSURE 200
#define MAXPRESSURE 1000

// ALL Touch panels and wiring is DIFFERENT
// copy-paste results from TouchScreen_Calibr_native.ino
const int XP =27, XM = 14, YP = 4, YM =14; //ID=0x9341
const int TS_LEFT = 907, TS_RT = 136, TS_TOP = 942, TS_BOT = 139;

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

Adafruit_GFX_Button on_btn, off_btn;

int pixel_x, pixel_y;     //Touch_getXY() updates global vars
bool Touch_getXY(void)
{
    TSPoint p = ts.getPoint();
    pinMode(YP, OUTPUT);      //restore shared pins
    pinMode(XM, OUTPUT);
    digitalWrite(YP, HIGH);   //because TFT control pins
    digitalWrite(XM, HIGH);
    bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
    if (pressed) {
        pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
        pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
    }
    return pressed;
}

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

void setup(void)
{
    Serial.begin(9600);
    uint16_t ID = tft.readID();
    Serial.print("TFT ID = 0x");
    Serial.println(ID, HEX);
    Serial.println("Calibrate for your Touch Panel");
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    tft.begin(ID);
    tft.setRotation(0);            //PORTRAIT
    tft.fillScreen(BLACK);
    on_btn.initButton(&tft,  60, 200, 100, 40, WHITE, CYAN, BLACK, "ON", 2);
    off_btn.initButton(&tft, 180, 200, 100, 40, WHITE, CYAN, BLACK, "OFF", 2);
    on_btn.drawButton(false);
    off_btn.drawButton(false);
    tft.fillRect(40, 80, 160, 80, RED);
}

/* two buttons are quite simple
 */
void loop(void)
{
    bool down = Touch_getXY();
    on_btn.press(down && on_btn.contains(pixel_x, pixel_y));
    off_btn.press(down && off_btn.contains(pixel_x, pixel_y));
    if (on_btn.justReleased())
        on_btn.drawButton();
    if (off_btn.justReleased())
        off_btn.drawButton();
    if (on_btn.justPressed()) {
        on_btn.drawButton(true);
        tft.fillRect(40, 80, 160, 80, GREEN);
    }
    if (off_btn.justPressed()) {
        off_btn.drawButton(true);
        tft.fillRect(40, 80, 160, 80, RED);
    }
}
#endif


Sorry again and thank you,
Roberto

I edited button_simple.ino e.g. for your calibration

// ALL Touch panels and wiring is DIFFERENT
// copy-paste results from TouchScreen_Calibr_native.ino
//const int XP = 6, XM = A2, YP = A1, YM = 7; //ID=0x9341
//const int TS_LEFT = 907, TS_RT = 136, TS_TOP = 942, TS_BOT = 139;
const int XP=27,XM=15,YP=4,YM=14; //320x480 ID=0x9486
const int TS_LEFT=919,TS_RT=131,TS_TOP=947,TS_BOT=49;

and for my advice in #3.

void setup(void)
{
#if defined(__arm__) || defined(ESP32)
    analogReadResolution(10);
#endif
    Serial.begin(9600);
    uint16_t ID = tft.readID();

My Shield is different calibration to yours.
same XP, XM, ... pins but different TS_TOP, TS_BOT

The buttons "worked" but [ON] button was about 1/2 down the screen instead of 1/3 down the screen. I am assuming that you have 320x480 Shield with ILI9486 controller from #1.

Your code in #4 implies a 240x320 Screen with ILI9341

Obviously the buttons would be in the correct place if I had pasted my calibration.

David.

Many thanks David.... whith your help now all working.
Roberto

Dear David,
I come back to torment you with my questions.

Regarding the code you can read above, I have tried changing the screen from landscape to portrait, but the buttons do not work properly, enabling themselves in random parts of the screen.

I have tried with some stupid, casual logic to change the code, with no appreciable results.

I abuse your courtesy again by asking how and where I should modify the code.

I appreciate your help and solid experience and look forward to your valuable assistance.

Regards, Roberto

If you want to handle different rotations you need to map the x, y to the specific rotation. Replace your Touch_XY() function with this.

void mapxy(int x, int y)
{
    int aspect = tft.getRotation();     //LANDSCAPE
    int tft_width = tft.width();
    int tft_height = tft.height();
    switch (aspect & 3) {
        case 0:      //PORTRAIT
            pixel_x = map(x, TS_LEFT, TS_RT, 0, tft_width);
            pixel_y = map(y, TS_TOP, TS_BOT, 0, tft_height);
            break;
        case 1:      //LANDSCAPE
            pixel_x = map(y, TS_TOP, TS_BOT, 0, tft_width);
            pixel_y = map(x, TS_RT, TS_LEFT, 0, tft_height);
            break;
        case 2:      //PORTRAIT REV
            pixel_x = map(x, TS_RT, TS_LEFT, 0, tft_width);
            pixel_y = map(y, TS_BOT, TS_TOP, 0, tft_height);
            break;
        case 3:      //LANDSCAPE REV
            pixel_x = map(y, TS_BOT, TS_TOP, 0, tft_width);
            pixel_y = map(x, TS_LEFT, TS_RT, 0, tft_height);
            break;
    }
}

bool Touch_getXY(void)
{
    TSPoint p = ts.getPoint();
    pinMode(YP, OUTPUT);      //restore shared pins
    pinMode(XM, OUTPUT);
    bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
    if (pressed) {
        mapxy(p.x, p.y);
    }
    return pressed;
}

I tried to make the example as simple as possible. I intend to add the ARM/ESP32 conditional to the next release. But I will put the mapxy() function in the button_list.ino (which very few readers ever notice)

I would appreciate your opinion. (please omit the grovelling)

Dear David,
thank very much for your interesting and precious reply.
Regards, Roberto

Hi David,
as you can see from the attached code, I used your example to build the architecture of my VFO sketch with a parametric pushbutton selection.

#if 1

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

#define MINPRESSURE 200
#define MAXPRESSURE 1000


const int XP =27, XM = 15, YP = 4, YM =14; //ID=0x9486
const int TS_LEFT = 907, TS_RT = 120, TS_TOP = 944, TS_BOT = 48;

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

Adafruit_GFX_Button band_btn, step_btn, fast_btn, run_btn;

int pixel_x, pixel_y;     //Touch_getXY() updates global vars

bool Touch_getXY(void)
{
    TSPoint p = ts.getPoint();
    pinMode(YP, OUTPUT);      //restore shared pins
    pinMode(XM, OUTPUT);

    digitalWrite(YP, HIGH);   //because TFT control pins
    digitalWrite(XM, HIGH);

    bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
    if (pressed) {

        pixel_x = map(p.y, 944, 48, 0, 480); //.kbv makes sense to me
        pixel_y = map(p.x, 120, 907, 0, 320);
    }
    return pressed;
}

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define GREY    0x8410
#define WHITE   0xFFFF

void setup(void)
{



    #if defined(__arm__) || defined(ESP32)
       analogReadResolution(10);
    #endif


    uint16_t ID = tft.readID();
    if (ID == 0xD3D3) ID = 0x9486; 
    tft.begin(ID);
    tft.setRotation(1);            //LANDSCAPE
    tft.fillScreen(BLACK);
 
// Buttons of Main page
    band_btn.initButton(&tft,  60, 285, 100, 40, WHITE, CYAN, BLACK, "BAND", 2);    
    band_btn.drawButton(false);

    step_btn.initButton(&tft, 180, 285, 100, 40, WHITE, CYAN, BLACK, "STEP", 2);
    step_btn.drawButton(false);

    fast_btn.initButton(&tft, 300, 285, 100, 40, WHITE, CYAN, BLACK, "FAST", 2);
    fast_btn.drawButton(false);

    run_btn.initButton(&tft, 420, 285, 100, 40, WHITE, CYAN, BLACK, " RUN", 2);
    run_btn.drawButton(false);

    tft.fillRect(40, 80, 160, 80, RED);

}


void loop(void)
{

// -----------------------------------------------------------------
    bool down = Touch_getXY();
    band_btn.press(down && band_btn.contains(pixel_x, pixel_y));
 
    if (band_btn.justReleased())  band_btn.drawButton();
    if (step_btn.justReleased())  step_btn.drawButton();
    if (fast_btn.justReleased())  fast_btn.drawButton();    
    if (run_btn.justReleased())   run_btn.drawButton();     

    if (band_btn.justPressed()) {
            band_btn.drawButton(true);
            tft.fillRect(40, 80, 160, 80, GREEN);
            band_page();
                                }

    step_btn.press(down && step_btn.contains(pixel_x, pixel_y));
    if (step_btn.justPressed()) {
        step_btn.drawButton(true);
        tft.fillRect(40, 80, 160, 80, RED);

                                }
    fast_btn.press(down && fast_btn.contains(pixel_x, pixel_y));
    if (fast_btn.justPressed()) {
        fast_btn.drawButton(true);
        tft.fillRect(40, 80, 160, 80, YELLOW);        
                                 }

   run_btn.press(down && run_btn.contains(pixel_x, pixel_y));
    if (run_btn.justPressed()) {
        run_btn.drawButton(true);
        tft.fillRect(40, 80, 160, 80, BLUE);        
                                 }                                 
}
#endif

void band_page(){


  Adafruit_GFX_Button GEN_btn, LW_btn, BCN_btn, MW_btn, SW_btn, FM_btn, HAM160_btn, HAM80_btn, HAM40_btn, HAM30_btn, HAM20_btn, HAM17_btn, HAM15_btn, HAM12_btn, HAMCB_btn, HAM10_btn, HAM6_btn, HAM2_btn;  // 18 working bands

 tft.fillScreen(BLACK); 

    GEN_btn.initButton(&tft,  40, 35, 60, 40, WHITE, YELLOW, BLACK, "GEN", 2);    
    GEN_btn.drawButton(false);

    LW_btn.initButton(&tft,  120, 35, 60, 40, WHITE, YELLOW, BLACK, "LW", 2);    
    LW_btn.drawButton(false);

    BCN_btn.initButton(&tft,  200, 35, 60, 40, WHITE, YELLOW, BLACK, "BCN", 2);    
    BCN_btn.drawButton(false);   

    MW_btn.initButton(&tft,  280, 35, 60, 40, WHITE, YELLOW, BLACK, "MW", 2);    
    MW_btn.drawButton(false);     

    SW_btn.initButton(&tft,  360, 35, 60, 40, WHITE, YELLOW, BLACK, "SW", 2);    
    SW_btn.drawButton(false);   

    FM_btn.initButton(&tft,  440, 35, 60, 40, WHITE, YELLOW, BLACK, "FM", 2);    
    FM_btn.drawButton(false);   

    HAM160_btn.initButton(&tft,  40, 125, 60, 40, WHITE, YELLOW, BLACK, "160m", 2);   
    HAM160_btn.drawButton(false);    

    HAM80_btn.initButton(&tft,  120, 125, 60, 40, WHITE, YELLOW, BLACK, "80 m", 2);    
    HAM80_btn.drawButton(false);        

    HAM40_btn.initButton(&tft,  200, 125, 60, 40, WHITE, YELLOW, BLACK, "40 m", 2);    
    HAM40_btn.drawButton(false);  

    HAM30_btn.initButton(&tft,  280, 125, 60, 40, WHITE, YELLOW, BLACK, "30 m", 2);    
    HAM30_btn.drawButton(false);  

    HAM20_btn.initButton(&tft,  360, 125, 60, 40, WHITE, YELLOW, BLACK, "20 m", 2);    
    HAM20_btn.drawButton(false);    

    HAM17_btn.initButton(&tft,  440, 125, 60, 40, WHITE, YELLOW, BLACK, "17 m", 2);    
    HAM17_btn.drawButton(false);  

    HAM15_btn.initButton(&tft,  40, 215, 60, 40, WHITE, YELLOW, BLACK, "15 m", 2);    
    HAM15_btn.drawButton(false);  

    HAM12_btn.initButton(&tft,  120, 215, 60, 40, WHITE, YELLOW, BLACK, "12 m", 2);    
    HAM12_btn.drawButton(false);  

    HAMCB_btn.initButton(&tft,  200, 215, 60, 40, WHITE, YELLOW, BLACK, "C.B.", 2);    
    HAMCB_btn.drawButton(false);  

    HAM10_btn.initButton(&tft,  280, 215, 60, 40, WHITE, YELLOW, BLACK, "10 m", 2);    
    HAM10_btn.drawButton(false);    

    HAM6_btn.initButton(&tft,  360, 215, 60, 40, WHITE, YELLOW, BLACK, "6 m", 2);    
    HAM6_btn.drawButton(false);     

    HAM2_btn.initButton(&tft,  440, 215, 60, 40, WHITE, YELLOW, BLACK, "2 m", 2);    
    HAM2_btn.drawButton(false);      


}

The main page consists of 4 buttons (Band, Step, Fast and Run) which should direct the screen to 4 distinct choice screens.
My problem (as yet unsolved) is to switch to the following pages, cancelling the buttons on the home page, which now remain active, superimposed on those of the new page.
How can I, by switching to the second (or third, fourth) page, override the buttons of the page of origin?

Thank you, Roberto

I have found the solution.
Thanks anyways,
Roberto