#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Pines de LEDs
#define ROJO1 1
#define ROJO2 2
#define AZUL1 42
#define AZUL2 41
#define VERDE1 40
#define VERDE2 39
// Pines de botones
#define BOTON_ENC 15
#define BOTON_CAMBIAR 3
#define BOTON_SELECCION 12
// Pines de sensor ultrasónico
#define ECHO_PIN 17
#define TRIG_PIN 16
// Buzzer
#define BUZZER_PIN 6
// OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Intensidad LED
int intensidad = 150;
bool dispositivoEncendido = false;
// Variables menú
int padecimientoSeleccionado = 0;
const int numPadecimientos = 5;
// Tiempos (segundos)
int tiempos[] = {10, 8, 10, 15, 12};
String nombres[] = {"ACNE", "DERMATITIS", "PSORIASIS", "FOTOENVEJECIMIENTO", "HIPERPIGMENTACION"};
String recomendaciones[] = {
"3-5 veces/sem, 4-10 min",
"2-3 veces/sem, 5-8 min",
"3 veces/sem, 6-10 min",
"2-3 veces/sem, 10-15 min",
"2-3 veces/sem, 8-12 min"
};
void sonarAlarma(int duracionMs, int veces);
void ejecutarProtocolo(int indice, float distInicio);
float medirDistancia();
void encenderLEDs(int r1,int r2,int a1,int a2,int v1,int v2);
void apagarTodos();
void mostrarMenu(String linea1, String linea2);
void setup() {
// LEDs
pinMode(ROJO1, OUTPUT); pinMode(ROJO2, OUTPUT);
pinMode(AZUL1, OUTPUT); pinMode(AZUL2, OUTPUT);
pinMode(VERDE1, OUTPUT); pinMode(VERDE2, OUTPUT);
// Botones
pinMode(BOTON_ENC, INPUT_PULLUP);
pinMode(BOTON_CAMBIAR, INPUT_PULLUP);
pinMode(BOTON_SELECCION, INPUT_PULLUP);
// Sensor Ultrasónico
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
// Buzzer
pinMode(BUZZER_PIN, OUTPUT);
// OLED
Wire.begin(5,4); // SDA, SCL
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
for(;;); // Si falla la pantalla, queda colgado
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
apagarTodos();
mostrarMenu("Dispositivo APAGADO", "");
}
void loop() {
float distanciaActual = -1; // Inicializamos a un valor fuera de rango
// Botón ENCENDER/APAGAR
if(digitalRead(BOTON_ENC) == LOW){
dispositivoEncendido = !dispositivoEncendido;
apagarTodos();
if(dispositivoEncendido) {
distanciaActual = medirDistancia();
if(distanciaActual >= 0 && distanciaActual <= 200) {
mostrarMenu("Dispositivo ENCENDIDO", nombres[padecimientoSeleccionado]);
} else {
mostrarMenu("¡ACERQUE DISPOSITIVO!", "Dist: " + String(distanciaActual, 1) + " cm");
}
} else {
mostrarMenu("Dispositivo APAGADO", "");
}
delay(500);
}
if(dispositivoEncendido){
distanciaActual = medirDistancia();
// Verificar si la distancia está en el rango permitido (0 cm a 200 cm)
bool distanciaValida = (distanciaActual >= 0 && distanciaActual <= 200);
if (distanciaValida) {
// Muestra el menú normal si el usuario no está presionando botones
if(digitalRead(BOTON_CAMBIAR) == HIGH && digitalRead(BOTON_SELECCION) == HIGH) {
mostrarMenu("Seleccionar padecimiento", nombres[padecimientoSeleccionado] + " (" + String(distanciaActual, 1) + "cm)");
}
// Botón CAMBIAR (Solo accesible con distancia válida)
if(digitalRead(BOTON_CAMBIAR) == LOW){
padecimientoSeleccionado = (padecimientoSeleccionado + 1) % numPadecimientos;
mostrarMenu("Seleccionar padecimiento", nombres[padecimientoSeleccionado] + " (" + String(distanciaActual, 1) + "cm)");
delay(500);
}
// Botón SELECCION (Solo accesible con distancia válida)
if(digitalRead(BOTON_SELECCION) == LOW){
ejecutarProtocolo(padecimientoSeleccionado, distanciaActual);
// Después de ejecutar, vuelve al menú, releyendo la distancia
distanciaActual = medirDistancia();
if(distanciaActual >= 0 && distanciaActual <= 200) {
mostrarMenu("Regresando al menu", nombres[padecimientoSeleccionado] + " (" + String(distanciaActual, 1) + "cm)");
} else {
mostrarMenu("¡ACERQUE DISPOSITIVO!", "Dist: " + String(distanciaActual, 1) + " cm");
}
delay(500);
}
} else {
// Si la distancia es inválida, muestra un mensaje de advertencia
mostrarMenu("¡ACERQUE DISPOSITIVO!", "Dist: " + String(distanciaActual, 1) + " cm");
}
}
}
// Función para sonar alarma
void sonarAlarma(int duracionMs, int veces){
for(int i = 0; i < veces; i++){
tone(BUZZER_PIN, 1500, duracionMs); // Frecuencia de 1500 Hz
delay(duracionMs + 50); // Tiempo de sonido más un pequeño silencio
}
noTone(BUZZER_PIN); // Asegura que el buzzer se apague
}
// Función para medir distancia en cm
float medirDistancia() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duracion = pulseIn(ECHO_PIN, HIGH);
float distancia = duracion * 0.0343 / 2;
return distancia;
}
// Función para ejecutar protocolo
void ejecutarProtocolo(int indice, float distInicio){
int tiempo = tiempos[indice];
String padecimiento = nombres[indice];
String recomendacion = recomendaciones[indice];
// ALARMA DE INICIO (3 pitidos cortos)
sonarAlarma(100, 3);
// Encender LEDs según padecimiento
switch(indice){
case 0: encenderLEDs(ROJO1, ROJO2, AZUL1, AZUL2, -1, -1); break;
case 1: encenderLEDs(ROJO1, ROJO2, -1, -1, -1, -1); break;
case 2: encenderLEDs(ROJO1, ROJO2, -1, -1, -1, -1); break;
case 3: encenderLEDs(ROJO1, ROJO2, -1, -1, -1, -1); break;
case 4: encenderLEDs(ROJO1, ROJO2, -1, -1, VERDE1, VERDE2); break;
}
float distActual;
for(int i=tiempo; i>0; i--){
distActual = medirDistancia();
if (distActual < 0 || distActual > 200) {
apagarTodos();
mostrarMenu("PROTOCOLO INTERRUMPIDO", "Distancia fuera de rango!");
sonarAlarma(500, 1); // Alarma de interrupción (1 pitido largo)
delay(2000);
return; // Sale del protocolo
}
display.clearDisplay();
display.setCursor(0,0);
display.println("Protocolo: " + padecimiento);
display.println("Segundos restantes: " + String(i));
display.println("Uso recomendado:");
display.println(recomendacion);
display.println("Distancia: " + String(distActual, 1) + " cm");
display.display();
delay(1000);
}
// ALARMA DE FIN (2 pitidos largos)
sonarAlarma(300, 2);
apagarTodos();
}
// Función para encender LEDs
void encenderLEDs(int r1,int r2,int a1,int a2,int v1,int v2){
if(r1!=-1) analogWrite(r1,intensidad);
if(r2!=-1) analogWrite(r2,intensidad);
if(a1!=-1) analogWrite(a1,intensidad);
if(a2!=-1) analogWrite(a2,intensidad);
if(v1!=-1) analogWrite(v1,intensidad);
if(v2!=-1) analogWrite(v2,intensidad);
}
// Función para apagar LEDs
void apagarTodos(){
analogWrite(ROJO1,0); analogWrite(ROJO2,0);
analogWrite(AZUL1,0); analogWrite(AZUL2,0);
analogWrite(VERDE1,0); analogWrite(VERDE2,0);
}
// Función para mostrar menú en OLED
void mostrarMenu(String linea1, String linea2){
display.clearDisplay();
display.setCursor(0,0);
display.println(linea1);
display.println(linea2);
display.display();
}