Trouble with TFT touchscreen, ili9341, buttons, changing pages

I've got quite a bit of time in this now and I may have bitten off more that I can chew.

I'm using an Uno R3, but it will be a bare bones 328P-AU or the 328PB, and I bought an ILI9341 with touchscreen controller. Amazon Link

I found some videos by Bytes and Bits that helped me get the screen up and running and being able to use the touch. Most tutorials for the ili9341 are using a shield that I am not using, so this has already been difficult, while this is using the adafruit 9341 library, it is using that only for the display. The touchscreen part is using the XPT2046 library, which there are not very many examples in it to learn from.

What I need... I need to be able to make a home screen where I choose from different parameters to adjust and then run the main function of the device using the chosen values. I've tried multiple things and I can't get this to work. I have never created a menu before, nor have I tried using a touch screen, so it is all new.

I can get what I want on the first page, I can then select an item on the first page and goto a second page. If I go to the first option, I can then change the value of the parameter. I can even go back to the main menu, but that is where it breaks. I get button bleed through and the values from whatever page I was on also show up on the home screen now, and you can't get back out of the home page after that.

Once I get that all sorted, I would also like to get rid of having to calibrate every time I reset or turn on the display.

Below is my code. Thanks!


#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "XPT2046_Touchscreen.h"
#include "Math.h"
 
// Define SPI pins for both display and touch
#define TFT_CS 10
#define TFT_DC 9
#define TFT_MOSI 11
#define TFT_CLK 13
#define TFT_RST 8
#define TFT_MISO 12
#define TS_CS 7
#define ROTATION 3

char currentPage;
 
 
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC/RST
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
XPT2046_Touchscreen ts(TS_CS);
 
// calibration values
float xCalM = 0.0, yCalM = 0.0; // gradients
float xCalC = 0.0, yCalC = 0.0; // y axis crossing points
 
int8_t blockWidth = 20; // block size
int8_t blockHeight = 20;
int16_t blockX = 0, blockY = 0; // block position (pixels)
 
class ScreenPoint {
public:
int16_t x;
int16_t y;
 
// default constructor
ScreenPoint(){
}
 
ScreenPoint(int16_t xIn, int16_t yIn){
x = xIn;
y = yIn;
}
};

class Button {
  public:

    int x;
    int y;
    int width;
    int height;
    char *text;

    Button(){
    }

    void initButtonP(int xPos, int yPos, int butWidth, int butHeight, char *butText){
      x = xPos;
      y = yPos;
      width = butWidth;
      height = butHeight;
      text = butText;
      renderP();
    }
    void initButtonM(int xPos, int yPos, int butWidth, int butHeight, char *butText){
      x = xPos;
      y = yPos;
      width = butWidth;
      height = butHeight;
      text = butText;
      renderM();
    }
    void renderP(){
      tft.fillRect(x,y,width,height,ILI9341_GREEN);
      tft.setCursor(x+5,y+5);
      tft.setTextSize(2);
      tft.setTextColor(ILI9341_WHITE);
      tft.print(text);
    }
    void renderM(){
      tft.fillRect(x,y,width,height,ILI9341_RED);
      tft.setCursor(x+5,y+5);
      tft.setTextSize(2);
      tft.setTextColor(ILI9341_WHITE);
      tft.print(text);
    }

    bool isClicked(ScreenPoint sp) {
      if ((sp.x >= x) && (sp.x <= (x+width)) && (sp.y <= (y+height))){
        return true;
      }
      else {
        return false;
      }
    }
};
 
ScreenPoint getScreenCoords(int16_t x, int16_t y){
int16_t xCoord = round((x * xCalM) + xCalC);
int16_t yCoord = round((y * yCalM) + yCalC);
if(xCoord < 0) xCoord = 0;
if(xCoord >= tft.width()) xCoord = tft.width() - 1;
if(yCoord < 0) yCoord = 0;
if(yCoord >= tft.height()) yCoord = tft.height() - 1;
return(ScreenPoint(xCoord, yCoord));
}



void calibrateTouchScreen(){
TS_Point p;
int16_t x1,y1,x2,y2;
 
tft.fillScreen(ILI9341_BLACK);
// wait for no touch
while(ts.touched());
tft.drawFastHLine(10,20,20,ILI9341_RED);
tft.drawFastVLine(20,10,20,ILI9341_RED);
while(!ts.touched());
delay(50);
p = ts.getPoint();
x1 = p.x;
y1 = p.y;
tft.drawFastHLine(10,20,20,ILI9341_BLACK);
tft.drawFastVLine(20,10,20,ILI9341_BLACK);
delay(500);
while(ts.touched());
tft.drawFastHLine(tft.width() - 30,tft.height() - 20,20,ILI9341_RED);
tft.drawFastVLine(tft.width() - 20,tft.height() - 30,20,ILI9341_RED);
while(!ts.touched());
delay(50);
p = ts.getPoint();
x2 = p.x;
y2 = p.y;
tft.drawFastHLine(tft.width() - 30,tft.height() - 20,20,ILI9341_BLACK);
tft.drawFastVLine(tft.width() - 20,tft.height() - 30,20,ILI9341_BLACK);
 
int16_t xDist = tft.width() - 40;
int16_t yDist = tft.height() - 40;
 
// translate in form pos = m x val + c
// x
xCalM = (float)xDist / (float)(x2 - x1);
xCalC = 20.0 - ((float)x1 * xCalM);
// y
yCalM = (float)yDist / (float)(y2 - y1);
yCalC = 20.0 - ((float)y1 * yCalM);
 
Serial.print("x1 = ");Serial.print(x1);
Serial.print(", y1 = ");Serial.print(y1);
Serial.print("x2 = ");Serial.print(x2);
Serial.print(", y2 = ");Serial.println(y2);
Serial.print("xCalM = ");Serial.print(xCalM);
Serial.print(", xCalC = ");Serial.print(xCalC);
Serial.print("yCalM = ");Serial.print(yCalM);
Serial.print(", yCalC = ");Serial.println(yCalC);
 
}
 
Button btnIP;
Button btnIM;
Button btnVP;
Button btnVM;
Button btnMI;
Button btnMV;
Button btnMM;
int IV = 30;
float VV = 385.00;

void setup() {
Serial.begin(9600);
 
// avoid chip select contention
pinMode(TS_CS, OUTPUT);
digitalWrite(TS_CS, HIGH);
pinMode(TFT_CS, OUTPUT);
digitalWrite(TFT_CS, HIGH);
 
tft.begin();
tft.setRotation(ROTATION);
tft.fillScreen(ILI9341_BLACK);
ts.begin();
ts.setRotation(ROTATION);
calibrateTouchScreen();
//btnMV.initButtonP(0,50,180,25,"Discharge");
//btnMI.initButtonP(0,100,180,25,"Voltage");
//btnVP.initButtonP(175,125,20,25,"+");
//btnVM.initButtonM(175,200,80,25,"Main Menu");
currentPage = '0'; //  Indicates that we are at Home Screen
Home();
}

unsigned long lastFrame = millis();

void loop(void) {
  ScreenPoint sp;
  // limit frame rate
while((millis() - lastFrame) < 20);
lastFrame = millis();
// Home Screen
if(currentPage=='0'){
    
if (ts.touched()) {
  TS_Point p = ts.getPoint();
  sp = getScreenCoords(p.x, p.y);
if(btnMV.isClicked(sp)){
    currentPage = '1'; // Go to Discharge Current
     tft.fillScreen(ILI9341_BLACK);
     discharge();
   }
else if(btnMI.isClicked(sp)){
    currentPage = '2'; // Go to Cutoff Voltage
     tft.fillScreen(ILI9341_BLACK);
     cutoff();
   }
}
}


// Discharge Current
if(currentPage=='1'){
   tft.setCursor(225,50);
    tft.print(IV);
    tft.setCursor(275,50);
    tft.print("A");
if (ts.touched()) {
  TS_Point p = ts.getPoint();
  sp = getScreenCoords(p.x, p.y);
  if(btnIP.isClicked(sp)){
    IV++;
    tft.fillRect(200,50,125,50,ILI9341_BLACK);
    delay(50);
    }
    else if (btnIM.isClicked(sp)){
      IV--;
      tft.fillRect(200,50,125,50,ILI9341_BLACK);
     delay(50);
    }
    else if (btnMM.isClicked(sp)){
      currentPage=='0';
      Home();
    }
   
    
}
}

// Cutoff Voltage
if(currentPage=='2'){
   tft.setCursor(205,50);
    tft.print(VV/100);
    tft.setCursor(275,50);
    tft.print("V");
if (ts.touched()) {
  TS_Point p = ts.getPoint();
  sp = getScreenCoords(p.x, p.y);
  if(btnIP.isClicked(sp)){
    VV++;
    tft.fillRect(205,50,60,50,ILI9341_BLACK);
    delay(50);
    }
    else if (btnIM.isClicked(sp)){
      VV--;
      tft.fillRect(205,50,60,50,ILI9341_BLACK);
     delay(50);
    }
    else if (btnMM.isClicked(sp)){
      currentPage=='0';
      Home();
    }
   
    
}
}
}

 
void Home(){
    tft.fillScreen(ILI9341_BLACK);
    btnMV.initButtonP(0,50,180,25,"Discharge");
    btnMI.initButtonP(0,100,180,25,"Voltage");
    
}

void discharge(){
    btnIP.initButtonP(175,50,20,25,"+");
    btnIM.initButtonM(175,75,20,25,"-");
    btnMM.initButtonM(100,200,140,25,"Main Menu");
    tft.setCursor(0,50);
    tft.setTextSize(3);
    tft.setTextColor(ILI9341_YELLOW);
    tft.print("Discharge");
    tft.setCursor(0,75);
    tft.print("Current");
    tft.setCursor(225,50);
    tft.print(IV);
    tft.setCursor(275,50);
    tft.print("A");
}

void cutoff(){
    btnIP.initButtonP(135,50,20,25,"+");
    btnIM.initButtonM(135,75,20,25,"-");
    btnMM.initButtonM(100,200,140,25,"Main Menu");
    tft.setCursor(0,50);
    tft.setTextSize(3);
    tft.setTextColor(ILI9341_BLUE);
    tft.print("Voltage");
    tft.setCursor(0,75);
    tft.print("Cutoff");
}


I figured out how to not calibrate every time. That part was pretty easy. And I was missing a comparison in my boolean statement that I added, which made the buttons behave better on the screens they were on. I was having issues being able to press above buttons and activate, but that was fixed by adding (sp.y >= y) the boolean comparison.

So really, the issue is when you go back to the home screen the buttons for the home screen don't work, but the buttons, which are hidden, for the last page work, and the value is there that I am incrementing. I don't understand why that is there.

I figured out my issue.
it was when I set the currentPage to the page I was using == instead of just setting it currentPage='0' for main menu. Changed that and it seems to be working. Now to actually fill it out a bit.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.