// Definición de pines
const int PIN_BOTON = 15; // GPIO4 para el botón
enum PINSLED{
R=16,
Y=17,
G=18
};
// Constantes
const unsigned long TIMEOUT = 400; // Tiempo máximo entre pulsaciones (ms)
// Definición de estados de la máquina
enum Estado {
ESPERA,
PRIMERA_PULSACION,
SEGUNDA_PULSACION,
TERCERA_PULSACION,
ESPERA_ACCION,
ESPERA_ACCION2
};
PINSLED LED_Actual;
PINSLED LED_Refresh(int pinR, int pinY, int pinG, PINSLED Actual, int direction=1){
PINSLED Next = Actual;
switch(Actual){
case Y:
if (direction == 1) {
digitalWrite(Y,0);
digitalWrite(G,0);
digitalWrite(R,1);
Next=R;
}
else{
digitalWrite(Y,0);
digitalWrite(G,1);
digitalWrite(R,0);
Next=G;
}
break;
case R:
if (direction == 1){
digitalWrite(Y,0);
digitalWrite(G,1);
digitalWrite(R,0);
Next=G;
}
else{
digitalWrite(Y,1);
digitalWrite(G,0);
digitalWrite(R,0);
Next=Y;
}
break;
case G:
if (direction == 1) {
digitalWrite(Y,1);
digitalWrite(G,0);
digitalWrite(R,0);
Next=Y;
}
else{
digitalWrite(Y,0);
digitalWrite(G,0);
digitalWrite(R,1);
Next=R;
}
break;
}
return Next;
}
// Variables globales
Estado estadoActual = ESPERA;
bool estadoBotonAnterior = HIGH; // Con resistencia pull-up, nivel alto cuando no está presionado
unsigned long tiempoUltimaPulsacion = 0;
void setup() {
// Inicializar comunicación serial
Serial.begin(115200);
// Configurar pines
pinMode(PIN_BOTON, INPUT_PULLUP); // Botón con resistencia pull-up interna
pinMode(Y, OUTPUT);
pinMode(G, OUTPUT);
pinMode(R, OUTPUT);
digitalWrite(Y,HIGH);
digitalWrite(G,LOW);
digitalWrite(R,LOW);
LED_Actual = Y;
Serial.println("Sistema iniciado - Control de Música");
}
void loop() {
// Leer estado actual del botón
bool estadoBotonActual = digitalRead(PIN_BOTON);
// Detectar evento (flanco descendente - presión del botón)
bool botonPresionado = (estadoBotonActual == LOW && estadoBotonAnterior == HIGH);
// Tiempo actual
unsigned long tiempoActual = millis();
// Máquina de estados
switch (estadoActual) {
case ESPERA:
if (botonPresionado) {
tiempoUltimaPulsacion = tiempoActual;
estadoActual = PRIMERA_PULSACION;
Serial.println("Primera pulsación detectada");
}
break;
case PRIMERA_PULSACION:
// Verificar si ha habido una segunda pulsación
if (botonPresionado) {
// Verificar si estamos dentro del tiempo permitido
if (tiempoActual - tiempoUltimaPulsacion < TIMEOUT) {
tiempoUltimaPulsacion = tiempoActual;
estadoActual = SEGUNDA_PULSACION;
Serial.println("Segunda pulsación detectada");
} else {
// Si ha pasado demasiado tiempo, reiniciar el contador
tiempoUltimaPulsacion = tiempoActual;
Serial.println("Timeout - Reiniciando con primera pulsación");
}
}
// Verificar si ha pasado demasiado tiempo desde la primera pulsación
else if (tiempoActual - tiempoUltimaPulsacion > TIMEOUT) {
estadoActual = ESPERA;
Serial.println("Timeout - Volviendo a espera");
}
break;
case SEGUNDA_PULSACION:
// Verificar si ha habido una tercera pulsación
if (botonPresionado) {
// Verificar si estamos dentro del tiempo permitido
if (tiempoActual - tiempoUltimaPulsacion < TIMEOUT) {
tiempoUltimaPulsacion = tiempoActual;
estadoActual = TERCERA_PULSACION;
Serial.println("Tercera pulsación detectada");
} else {
// Si ha pasado demasiado tiempo, reiniciar el contador
tiempoUltimaPulsacion = tiempoActual;
estadoActual = PRIMERA_PULSACION;
Serial.println("Timeout - Reiniciando con primera pulsación");
}
}
// Verificar si ha pasado el tiempo suficiente para considerar que solo fueron 2 clics
else if (tiempoActual - tiempoUltimaPulsacion > TIMEOUT) {
estadoActual = ESPERA_ACCION;
Serial.println("Doble click completo - Ejecutando acción");
}
break;
case TERCERA_PULSACION:
// Después de la tercera pulsación, esperamos el timeout para confirmar
if (tiempoActual - tiempoUltimaPulsacion > TIMEOUT) {
estadoActual = ESPERA_ACCION2;
Serial.println("Triple click completo - Ejecutando acción");
}
break;
case ESPERA_ACCION:
// Realizar acción para doble click
LED_Actual=LED_Refresh(R, Y, G,LED_Actual,-1 );
Serial.println(">>> NEXT SONG <<<");
estadoActual = ESPERA;
break;
case ESPERA_ACCION2:
// Realizar acción para triple click
LED_Actual=LED_Refresh(R, Y, G, LED_Actual,1);
Serial.println(">>> PREVIOUS SONG <<<");
estadoActual = ESPERA;
break;
}
// Actualizar estado anterior del botón
estadoBotonAnterior = estadoBotonActual;
// Pequeña pausa para estabilidad
delay(10);
}