Интерфейс сенсорного экрана TFT Arduino возвращает только одну кнопку

Я пытаюсь создать код для Arduino, который возвращает значение для кнопки, нажатой пользователем. Однако, какую бы кнопку я ни нажимал, возвращается только 2. Кроме того, при нажатии других кнопок, похоже, нажата кнопка 2.

Что это может быть? Есть идеи, как решить эту проблему?

Это мой текущий код.

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

#define MINPRESSURE 500
#define MAXPRESSURE 2000
#define PRETO   0x0000
#define VERMELHO     0xF800
#define VERDE   0x07E0
#define BRANCO   0xFFFF

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

#define TS_LEFT 945
#define TS_RT 221
#define TS_TOP 916
#define TS_BOT 201

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
Adafruit_GFX_Button botoes[4];
MCUFRIEND_kbv tft;

int posX, posY;
int escolha = 0;

bool obterToque(void) {
    TSPoint p = ts.getPoint();
    pinMode(YP, OUTPUT);      
    pinMode(XM, OUTPUT);
    digitalWrite(YP, HIGH);   
    digitalWrite(XM, HIGH);
    bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
    if (pressed) {
        posX = map(p.x, TS_LEFT, TS_RT, 0, 320); 
        posY = map(p.y, TS_TOP, TS_BOT, 0, 240);
        // Отладка: вывод необработанных и сопоставленных координат касания
        //Serial.print("Необработанный X:"); Serial.print(px); Serial.print(", Необработанный Y:"); Serial.println(py);
        //Serial.print("Отображено по X:"); Serial.print(posX); Serial.print(", Отображено по Y:"); Serial.println(posY);
        return true;
    }
    return false; 
}

void setup() {
  Serial.begin(9600);
  uint16_t ID = tft.readID();
  tft.begin(ID);
  tft.setRotation(3);
  telaInicial();
}

void telaInicial(){
  tft.fillScreen(PRETO);
  botoes[0].initButton(&tft,  160, 40, 250, 40, BRANCO, VERDE, PRETO, "1. Normal Sinus", 2);
  botoes[1].initButton(&tft, 160, 95, 250, 40, BRANCO, VERDE, PRETO, "2. Atrial Fibrillation", 2);
  botoes[2].initButton(&tft, 160, 150, 250, 40, BRANCO, VERDE, PRETO, "3. Ventricular Ectopy", 2);
  botoes[3].initButton(&tft, 160, 205, 250, 40, BRANCO, VERDE, PRETO, "4. SV Arrhythmia", 2);

  for (int i = 0; i < 4; i++) {
    botoes[i].drawButton(false);
  }
}

void TeclaPressionada(bool teclaTocada) {
  for (int i = 0; i < 4; i++) {
    botoes[i].press(teclaTocada && botoes[i].contains(posX, posY));
  }
  checkPressedButton();
}

void checkPressedButton() {
  for (int i = 0; i < 4; i++) {
    if (botoes[i].justPressed()) {
      checkPressed(i);
    }
  }
}

void esperaSoltar() {
  while (obterToque()) {
    delayMicroseconds(50);
  }
}

void checkPressed(int button) {
    botoes[button].drawButton(true);
    esperaSoltar();
    botoes[button].drawButton();

    if (button == 0) {
        escolha = 1;
    } else if (button == 1) {
        escolha = 2;
    } else if (button == 2) {
        escolha = 3;
    } else if (button == 3) {
        escolha = 4;
    }

    Serial.print("Escolha: ");
    Serial.println(escolha);
}

void loop() {
  bool toque = obterToque();
  TeclaPressionada(toque);
}

Спасибо за чтение.

, 👍0

Обсуждение

почему отладочный код отключен?, @jsotola

Всем привет, наконец-то я нашел урок, который решает эту проблему: https://www.youtube.com/watch?v=wn-1hHjRyjo, @GIOVANNE LUCAS BARRETO PINHEIR


1 ответ


Лучший ответ:

1

Мне удалось найти ответ в этом видеоуроке: https://www.youtube.com/watch?v=wn-1hHjRyjo

Вот проект экрана, над которым я работаю.

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

MCUFRIEND_kbv tft;

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

#define TS_LEFT 945
#define TS_RT 221
#define TS_TOP 916
#define TS_BOT 201

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

// Definição de cores
#define BLACK 0x0000
#define BLUE 0x2015
#define BLUE2 0x0DDE
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define GREY 0xC639

// Variáveis Globais
uint32_t startRead = 0;
int page = 0;
int posX;
int posY;

// Variables for ECG data
float ecgValue = 0.0; // Current ECG value received from serial
int scale = 75;      // Scale factor for voltage values
int startY;          // Vertical center for the waveform
int ecgIndex = 0;    // Current index for plotting
int xPos = 0;        // Horizontal position to draw the next data point
int choice = 0;       // User rhythm selection variable to lead to desired rhythm


#define MINPRESSURE 10
#define MAXPRESSURE 1000

void setup(void) {
  Serial.begin(115200);
  Serial.println("TFT Test");
  tft.reset();
  delay(500);
  uint16_t identifier = tft.readID();
  tft.begin(identifier);
  tft.setRotation(1);
  tft.setCursor(0, 0);
  tft.setTextColor(BLACK);
  tft.setTextSize(2);

  tft.println("Programa feito por: ");
  tft.println("Giovanne Lucas");
  tft.println("Barreto");
  tft.println("giovanne.pinto@medicina.uniceplac.edu.br");

  delay(2000);
  tft.fillScreen(BLACK);

  displayBootScreen();
  delay(5000);

  telainicial();
  page = 0;

  startY = tft.height() / 2; // Calculate vertical center for ECG plotting
}

void displayBootScreen() {
    int screenWidth = tft.width();
    int screenHeight = tft.height();
    tft.drawBitmap(0, 0, bootImage, screenWidth, screenHeight, WHITE);
    delay(5000);
    tft.fillScreen(0x0000); // Placeholder: Fill screen with black
    tft.setTextColor(0xFFFF);
    tft.setTextSize(2);
    //tft.setCursor(10, screenHeight / 2 - 10);
    //tft.print("Booting...");
}

void telainicial() {
  tft.fillScreen(WHITE);
  tft.fillRoundRect(5, 5, 310, 30, 0, BLACK);
  tft.fillRoundRect(7, 7, 306, 26, 0, BLUE);
  tft.setCursor(120, 10);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.print("MENU");

  tft.fillRoundRect(50, 55, 220, 40, 0, BLACK);
  tft.fillRoundRect(52, 57, 216, 36, 0, GREY);
  tft.setCursor(60, 65);
  tft.setTextColor(BLACK);
  tft.setTextSize(1);
  tft.print("1. Ritmo Sinusal");

  tft.fillRoundRect(50, 115, 220, 40, 0, BLACK);
  tft.fillRoundRect(52, 117, 216, 36, 0, GREY);
  tft.setCursor(60, 124);
  tft.setTextColor(BLACK);
  tft.setTextSize(1);
  tft.print("2. Fibrilacao Atrial");

  tft.fillRoundRect(50, 175, 220, 40, 0, BLACK);
  tft.fillRoundRect(52, 177, 216, 36, 0, GREY);
  tft.setCursor(60, 185);
  tft.setTextColor(BLACK);
  tft.setTextSize(1);
  tft.print("3. Ectopia Ventricular");
}

void tela1() {
  tft.fillScreen(WHITE);
  tft.fillRoundRect(5, 5, 310, 30, 0, BLACK);
  tft.fillRoundRect(7, 7, 306, 26, 0, BLUE);
  tft.setCursor(120, 10);
  tft.setTextColor(WHITE);
  tft.setTextSize(1);
  tft.print("Ritmo Sinusal");

  tft.fillTriangle(30, 20, 50, 30, 50, 10, GREY); // Botão de voltar
}

void tela2() {
  tft.fillScreen(WHITE);
  tft.fillRoundRect(5, 5, 310, 30, 0, BLACK);
  tft.fillRoundRect(7, 7, 306, 26, 0, BLUE);
  tft.setCursor(90, 10);
  tft.setTextColor(WHITE);
  tft.setTextSize(1);
  tft.print("Fibrilacao Atrial");

  tft.fillTriangle(30, 20, 50, 30, 50, 10, GREY); // Botão de voltar
}

void tela3() {
  tft.fillScreen(WHITE);
  tft.fillRoundRect(5, 5, 310, 30, 0, BLACK);
  tft.fillRoundRect(7, 7, 306, 26, 0, BLUE);
  tft.setCursor(90, 10);
  tft.setTextColor(WHITE);
  tft.setTextSize(1);
  tft.print("Ectopia Ventricular");

  tft.fillTriangle(30, 20, 50, 30, 50, 10, GREY); // Botão de voltar
}

void tela4() {
  tft.fillScreen(WHITE);
  tft.fillRoundRect(5, 5, 310, 30, 0, BLACK);
  tft.fillRoundRect(7, 7, 306, 26, 0, BLUE);
  tft.setCursor(90, 10);
  tft.setTextColor(WHITE);
  tft.setTextSize(1);
  tft.print("Arritmia Supraventricular");

  tft.fillTriangle(30, 20, 50, 30, 50, 10, GREY); // Botão de voltar
}


void plotECG() {
  static int xPos = 0; // horizontal position to draw the next data point
  static int startY = tft.height() / 2; // vertical center for the waveform
  static int lastY = startY; // previous Y coordinate

  if (Serial.available() > 0) {
    float ecgValue = Serial.parseFloat();
    int y1 = startY - (int)(ecgValue * scale); // calculate Y coordinate based on ECG value

    // draw a line from the previous point to the current point
    tft.drawLine(xPos - 1, lastY, xPos, y1, RED);

    // update lastY and xPos for the next loop iteration
    lastY = y1;
    xPos = (xPos + 1) % tft.width(); // wrap xPos around the screen width

    // clear the screen and redraw the grid if necessary
    if (xPos == 0) {
      tft.fillScreen(WHITE); // clear the screen
      drawECGGrid(); // redraw the grid
    }
  }
}

void loop() {
  TSPoint p = ts.getPoint();
  pinMode(XM, OUTPUT);
  digitalWrite(XM, LOW);
  pinMode(YP, OUTPUT);
  digitalWrite(YP, HIGH);
  pinMode(YM, OUTPUT);
  digitalWrite(YM, LOW);
  pinMode(XP, OUTPUT);
  digitalWrite(XP, HIGH);

  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    posX = map(p.y, TS_LEFT, TS_RT, 0, 320);
    posY = map(p.x, TS_TOP, TS_BOT, 0, 240);

    if (page == 0) {
      if (posX > 52 && posX < 268 && posY > 57 && posY < 93)  //RITMO SINUSAL
      {
        page = 1;
        choice = 1;
        tela1();
        delay(50); // debounce
      }
      if (posX > 52 && posX < 268 && posY > 117 && posY < 153)  //FIBRILACAO ATRIAL
      {
        page = 2;
        choice = 2;
        tela2();
        delay(50); // debounce
      }
      if (posX > 52 && posX < 268 && posY > 177 && posY < 213)  //ECTOPIA VENTRICULAR
      {
        page = 3;
        choice = 3;
        tela3();
        delay(50); // debounce
      }
    } else {
      // Verifica o botão de voltar
      if (posX > 30 && posX < 50 && posY > 10 && posY < 30)  //botão voltar
      {
        telainicial();
        page = 0;
      }
    }
  }
  if (page == 1) {
    plotECG(); // Ritmo Sinusal
  } else if (page == 2) {
    plotECG(); // Fibrilação Atrial
  } else if (page == 3) {
    plotECG(); // Ectopia Ventricular
  } else if (page == 4) {
    plotECG(); // Arritmia Supraventricular
  }

  // Always send the choice value to the serial port
  Serial.print("Choice: ");
  Serial.println(choice);

}

// Function to draw the ECG grid
void drawECGGrid() {
    int smallSquareSize = 10; // 10 pixels for small squares
    int largeSquareSize = 50; // 50 pixels for large squares

    uint16_t smallGridColor = GREY; // Light grey color for small squares
    uint16_t largeGridColor = 0x7BEF; // Darker grey color for large squares

    // Draw the small squares
    for (int x = 0; x <= tft.width(); x += smallSquareSize) {
        tft.drawFastVLine(x, 0, tft.height(), smallGridColor);
    }
    for (int y = 0; y <= tft.height(); y += smallSquareSize) {
        tft.drawFastHLine(0, y, tft.width(), smallGridColor);
    }

    // Draw the large squares
    for (int x = 0; x <= tft.width(); x += largeSquareSize) {
        tft.drawFastVLine(x, 0, tft.height(), largeGridColor);
    }
    for (int y = 0; y <= tft.height(); y += largeSquareSize) {
        tft.drawFastHLine(0, y, tft.width(), largeGridColor);
    }
}
,

каков ответ? ... что вызвало проблему?, @jsotola

Вижу, что это два разных подхода к одному и тому же вопросу. Думаю, второй пример кода лучше, поскольку он создаёт страницы и обновляет экран в зависимости от того, что касается пользователя. Вместо того, чтобы использовать несколько функций для обработки выбора страниц., @GIOVANNE LUCAS BARRETO PINHEIR