#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#define TFT_DC 17
#define TFT_CS 5
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// Definiciones de colores
#define BLACK 0x0000
#define WHITE 0xFFFF
#define BLUE 0x001F
#define LIGHTGREY 0xC618
// Pines de los botones
#define BUTTON_UP_PIN 34
#define BUTTON_DOWN_PIN 35
#define BUTTON_SELECT_PIN 32
// Opciones del menú
const char* menuOptions[] = {"Home", "Settings", "About", "Exit"};
const int numOptions = sizeof(menuOptions) / sizeof(menuOptions[0]);
int selectedOption = 0;
// Variables para manejar el estado de los botones
bool lastButtonUpState = HIGH;
bool lastButtonDownState = HIGH;
bool lastButtonSelectState = HIGH;
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(1);
tft.fillScreen(BLACK);
// Configuración de los pines de los botones
pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP);
pinMode(BUTTON_SELECT_PIN, INPUT_PULLUP);
drawMenu();
}
void loop() {
handleButtonInput();
}
void handleButtonInput() {
// Leer el estado actual de los botones
bool currentButtonUpState = digitalRead(BUTTON_UP_PIN);
bool currentButtonDownState = digitalRead(BUTTON_DOWN_PIN);
bool currentButtonSelectState = digitalRead(BUTTON_SELECT_PIN);
// Detección de flanco descendente (cuando se presiona el botón)
if (currentButtonUpState == LOW && lastButtonUpState == HIGH) {
selectedOption = (selectedOption - 1 + numOptions) % numOptions;
drawMenu();
}
if (currentButtonDownState == LOW && lastButtonDownState == HIGH) {
selectedOption = (selectedOption + 1) % numOptions;
drawMenu();
}
if (currentButtonSelectState == LOW && lastButtonSelectState == HIGH) {
executeOption(selectedOption);
}
// Actualizar el último estado de los botones
lastButtonUpState = currentButtonUpState;
lastButtonDownState = currentButtonDownState;
lastButtonSelectState = currentButtonSelectState;
}
void drawMenu() {
tft.fillScreen(BLACK);
tft.setTextSize(2);
tft.setCursor(10, 10);
tft.setTextColor(WHITE);
tft.print("Main Menu");
for (int i = 0; i < numOptions; i++) {
if (i == selectedOption) {
tft.setTextColor(WHITE);
tft.fillRoundRect(10, 40 + i * 40, 300, 40, 5, BLUE); // Fondo azul para la opción seleccionada
} else {
tft.setTextColor(LIGHTGREY);
}
// Dibujar iconos manualmente para cada opción
drawIcon(i, 20, 45 + i * 40); // Llamamos a la función para dibujar el icono
// Dibujar el texto de las opciones
tft.setCursor(60, 45 + i * 40); // Ajustar la posición del texto
tft.print(menuOptions[i]);
}
}
// Función para dibujar iconos simples para cada opción del menú
void drawIcon(int option, int x, int y) {
switch (option) {
case 0: // Icono de "Home"
tft.drawRect(x, y, 20, 20, WHITE); // Dibujar un rectángulo como casa
tft.drawTriangle(x, y, x + 10, y - 10, x + 20, y, WHITE); // Techo triangular
break;
case 1: // Icono de "Settings"
tft.drawCircle(x + 10, y + 10, 10, WHITE); // Círculo para representar un engranaje
tft.drawLine(x + 5, y + 10, x + 15, y + 10, WHITE); // Línea central
tft.drawLine(x + 10, y + 5, x + 10, y + 15, WHITE); // Otra línea central
break;
case 2: // Icono de "About"
tft.fillCircle(x + 10, y + 10, 10, WHITE); // Círculo lleno
tft.setTextColor(BLACK);
tft.setCursor(x + 5, y + 3);
tft.print("i"); // Letra "i" en el círculo
break;
case 3: // Icono de "Exit"
tft.drawLine(x, y, x + 20, y + 20, WHITE); // Línea diagonal de la "X"
tft.drawLine(x + 20, y, x, y + 20, WHITE); // Otra línea diagonal de la "X"
break;
}
}
void executeOption(int option) {
tft.fillScreen(BLACK);
tft.setTextSize(3);
tft.setTextColor(WHITE);
tft.setCursor(10, 100);
switch (option) {
case 0:
tft.print("Home selected");
break;
case 1:
tft.print("Settings selected");
break;
case 2:
tft.print("About selected");
break;
case 3:
tft.print("Exiting...");
delay(2000); // Esperar un momento
ESP.restart(); // Reiniciar el ESP32
break;
}
delay(2000); // Pausa antes de volver al menú
drawMenu(); // Volver al menú principal
}