#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// ==========================
// TFT
// ==========================
#define TFT_CS 22
#define TFT_DC 21
#define TFT_RST 17
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// ==========================
// LEDs
// ==========================
#define LED_VERDE 25
#define LED_AMARILLO 26
#define LED_ROJO 27
// ==========================
// BUZZER
// ==========================
#define BUZZER 14
// ==========================
// BOTONES
// ==========================
#define BTN_EXPANDIR 32
#define BTN_RETRAER 33
#define BTN_ELEVADOR 16
#define BTN_EMERGENCIA 13
// ==========================
// ESTADOS
// ==========================
bool modulosAbiertos = false;
bool elevadorAbajo = false;
bool emergencia = false;
// Para detectar un clic, no mantener pulsado
bool anteriorExpandir = HIGH;
bool anteriorRetraer = HIGH;
bool anteriorElevador = HIGH;
bool anteriorEmergencia = HIGH;
unsigned long ultimoClick = 0;
const unsigned long debounce = 180;
// ==========================
// LEDs
// ==========================
void estadoListo() {
digitalWrite(LED_VERDE, HIGH);
digitalWrite(LED_AMARILLO, LOW);
digitalWrite(LED_ROJO, LOW);
}
void estadoProceso() {
digitalWrite(LED_VERDE, LOW);
digitalWrite(LED_AMARILLO, HIGH);
digitalWrite(LED_ROJO, LOW);
}
void estadoEmergencia() {
digitalWrite(LED_VERDE, LOW);
digitalWrite(LED_AMARILLO, LOW);
digitalWrite(LED_ROJO, HIGH);
}
// ==========================
// BUZZER
// ==========================
void beep() {
tone(BUZZER, 1800, 150);
}
void beepProceso() {
tone(BUZZER, 1200, 300);
}
// ==========================
// PANTALLA BASE
// ==========================
void encabezado() {
tft.fillScreen(ILI9341_BLACK);
tft.fillRect(0, 0, 320, 42, ILI9341_NAVY);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(3);
tft.setCursor(105, 8);
tft.print("HERA");
tft.setTextSize(1);
tft.setCursor(105, 32);
tft.print("CONTROL SYSTEM");
tft.drawFastHLine(0, 45, 320, ILI9341_CYAN);
}
// ==========================
// PANTALLA PRINCIPAL
// ==========================
void pantallaPrincipal() {
encabezado();
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(2);
tft.setCursor(20, 60);
tft.print("SISTEMA LISTO");
// módulos
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(15, 100);
tft.print("Modulos:");
if (modulosAbiertos) {
tft.setTextColor(ILI9341_GREEN);
tft.print(" ABIERTOS");
} else {
tft.setTextColor(ILI9341_CYAN);
tft.print(" CERRADOS");
}
// elevador
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(15, 135);
tft.print("Elevador:");
if (elevadorAbajo) {
tft.setTextColor(ILI9341_YELLOW);
tft.print(" ABAJO");
} else {
tft.setTextColor(ILI9341_GREEN);
tft.print(" ARRIBA");
}
// emergencia
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(15, 170);
tft.print("Estado:");
tft.setTextColor(ILI9341_GREEN);
tft.print(" SEGURO");
// pie
tft.fillRect(0, 215, 320, 25, ILI9341_NAVY);
tft.setTextSize(1);
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(55, 223);
tft.print("HERA - EMERGENCY RESPONSE");
}
// ==========================
// PANTALLA DE MOVIMIENTO
// ==========================
void pantallaMovimiento(String linea1, String linea2) {
encabezado();
tft.setTextColor(ILI9341_YELLOW);
tft.setTextSize(2);
tft.setCursor(20, 75);
tft.print(linea1);
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(20, 120);
tft.print(linea2);
tft.setTextColor(ILI9341_YELLOW);
tft.setCursor(20, 175);
tft.print("EN PROCESO...");
}
// ==========================
// PANTALLA DE EMERGENCIA
// ==========================
void pantallaEmergencia() {
tft.fillScreen(ILI9341_RED);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(3);
tft.setCursor(45, 55);
tft.print("EMERGENCIA");
tft.drawRect(20, 105, 280, 80, ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(60, 125);
tft.print("SISTEMA");
tft.setCursor(55, 155);
tft.print("DETENIDO");
tft.setTextSize(1);
tft.setCursor(60, 215);
tft.print("Presione EMERGENCIA");
tft.setCursor(85, 228);
tft.print("para reiniciar");
}
// ==========================
// EXPANDIR
// ==========================
void expandir() {
if (emergencia) return;
if (modulosAbiertos) {
beep();
return;
}
estadoProceso();
beepProceso();
pantallaMovimiento(
"EXPANSION",
"Abriendo modulos"
);
delay(1500);
modulosAbiertos = true;
estadoListo();
beep();
pantallaPrincipal();
}
// ==========================
// RETRAER
// ==========================
void retraer() {
if (emergencia) return;
if (!modulosAbiertos) {
beep();
return;
}
estadoProceso();
beepProceso();
pantallaMovimiento(
"RETRACCION",
"Cerrando modulos"
);
delay(1500);
modulosAbiertos = false;
estadoListo();
beep();
pantallaPrincipal();
}
// ==========================
// ELEVADOR
// ==========================
void elevador() {
if (emergencia) return;
estadoProceso();
beepProceso();
if (!elevadorAbajo) {
pantallaMovimiento(
"ELEVADOR",
"Bajando plataforma"
);
delay(1500);
elevadorAbajo = true;
} else {
pantallaMovimiento(
"ELEVADOR",
"Subiendo plataforma"
);
delay(1500);
elevadorAbajo = false;
}
estadoListo();
beep();
pantallaPrincipal();
}
// ==========================
// EMERGENCIA
// ==========================
void emergenciaSistema() {
emergencia = !emergencia;
if (emergencia) {
estadoEmergencia();
tone(BUZZER, 2500);
pantallaEmergencia();
} else {
noTone(BUZZER);
estadoListo();
pantallaPrincipal();
}
}
// ==========================
// SETUP
// ==========================
void setup() {
Serial.begin(115200);
// LEDs
pinMode(LED_VERDE, OUTPUT);
pinMode(LED_AMARILLO, OUTPUT);
pinMode(LED_ROJO, OUTPUT);
// buzzer
pinMode(BUZZER, OUTPUT);
// botones
pinMode(BTN_EXPANDIR, INPUT_PULLUP);
pinMode(BTN_RETRAER, INPUT_PULLUP);
pinMode(BTN_ELEVADOR, INPUT_PULLUP);
pinMode(BTN_EMERGENCIA, INPUT_PULLUP);
// SPI TFT
SPI.begin(
18, // SCK
19, // MISO
23 // MOSI
);
// iniciar TFT
tft.begin();
// horizontal
tft.setRotation(1);
// estado inicial
estadoListo();
// pantalla inicio
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_CYAN);
tft.setTextSize(4);
tft.setCursor(100, 65);
tft.print("HERA");
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(55, 125);
tft.print("SYSTEM STARTING");
beep();
delay(1800);
pantallaPrincipal();
}
// ==========================
// LOOP
// ==========================
void loop() {
bool btnExpandir = digitalRead(BTN_EXPANDIR);
bool btnRetraer = digitalRead(BTN_RETRAER);
bool btnElevador = digitalRead(BTN_ELEVADOR);
bool btnEmergencia = digitalRead(BTN_EMERGENCIA);
// EXPANDIR
if (
btnExpandir == LOW &&
anteriorExpandir == HIGH &&
millis() - ultimoClick > debounce
) {
ultimoClick = millis();
expandir();
}
// RETRAER
if (
btnRetraer == LOW &&
anteriorRetraer == HIGH &&
millis() - ultimoClick > debounce
) {
ultimoClick = millis();
retraer();
}
// ELEVADOR
if (
btnElevador == LOW &&
anteriorElevador == HIGH &&
millis() - ultimoClick > debounce
) {
ultimoClick = millis();
elevador();
}
// EMERGENCIA
if (
btnEmergencia == LOW &&
anteriorEmergencia == HIGH &&
millis() - ultimoClick > debounce
) {
ultimoClick = millis();
emergenciaSistema();
}
// actualizar estados anteriores
anteriorExpandir = btnExpandir;
anteriorRetraer = btnRetraer;
anteriorElevador = btnElevador;
anteriorEmergencia = btnEmergencia;
}