#include <Adafruit_SoftServo.h> // Incluye la librería de Adafruit para controlar el servo
#define BUTTON_PIN 0 // Pin al que está conectado el pulsador (PB0)
#define SERVO_PIN 3 // Pin al que está conectado el servo (PB3)
#define LED1_PIN 1 // Pin del primer LED (PB1)
#define LED2_PIN 2 // Pin del segundo LED (PB2)
#define LED3_PIN 4 // Pin del tercer LED (PB4)
#define DEBOUNCE_DELAY 200 // Retardo para debouncing en milisegundos
#define BLINK_INTERVAL 300 // Intervalo de parpadeo para los LEDs
#define LED_SELECTION_DELAY 5000 // Retardo de 5 segundos después de seleccionar un LED
// Array de pines de LEDs
int led_pins[] = {LED1_PIN, LED2_PIN, LED3_PIN};
// Array de tiempos asociados a cada LED
int led_times[] = {1000, 5000, 10000}; // Ejemplo: tiempos en milisegundos
int current_led = 0; // LED actualmente seleccionado
unsigned long last_press_time = 0; // Último tiempo en que se presionó el botón
unsigned long servo_start_time = 0; // Tiempo en que se activó el servo
unsigned long last_blink_time = 0; // Tiempo del último parpadeo del LED
unsigned long led_selection_time = 0; // Tiempo en que se seleccionó el LED
unsigned long servo_move_time = 0; // Tiempo en el que el servo debe regresar a la posición inicial
int current_time = 0; // Valor de tiempo asociado al LED seleccionado
Adafruit_SoftServo myServo; // Crea una instancia del servo
bool servo_active = false; // Estado del servo
bool servo_moved = false; // Indica si el servo ya se movió a 90 grados
bool waiting_for_selection = true; // Estado de espera para la selección de tiempo
int initial_position = 0; // Posición inicial del servo
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP); // Configura el pulsador con resistencia de pull-up interna
for (int i = 0; i < 3; i++) {
pinMode(led_pins[i], OUTPUT); // Configura los pines de los LEDs como salidas
digitalWrite(led_pins[i], LOW); // Apaga todos los LEDs al inicio
}
digitalWrite(led_pins[current_led], HIGH); // Enciende el primer LED por defecto
current_time = led_times[current_led]; // Guarda el tiempo asociado al primer LED
myServo.attach(SERVO_PIN); // Conecta el servo al pin definido
myServo.write(initial_position); // Inicializa el servo en la posición 0 grados
}
void loop() {
// Lee el estado del botón
bool button_state = digitalRead(BUTTON_PIN) == LOW;
// Obtén el tiempo actual
unsigned long current_time_ms = millis();
// Verifica si el botón ha sido presionado y si ha pasado suficiente tiempo desde la última vez
if (button_state && (current_time_ms - last_press_time) > DEBOUNCE_DELAY) {
last_press_time = current_time_ms; // Actualiza el tiempo del último botón presionado
if (!servo_active) {
// Apaga el LED actual
digitalWrite(led_pins[current_led], LOW);
// Cambia al siguiente LED
current_led = (current_led + 1) % 3;
// Enciende el nuevo LED seleccionado
digitalWrite(led_pins[current_led], HIGH);
// Actualiza el tiempo de espera basado en el LED seleccionado
current_time = led_times[current_led];
// Reinicia el contador para los 5 segundos de retardo
led_selection_time = current_time_ms;
waiting_for_selection = true;
}
}
// Verifica si han pasado 5 segundos desde la última selección de LED
if (waiting_for_selection && (current_time_ms - led_selection_time >= LED_SELECTION_DELAY)) {
// Si han pasado 5 segundos sin cambiar el LED, activa la secuencia de espera
servo_start_time = current_time_ms;
last_blink_time = current_time_ms; // Inicializa el tiempo del parpadeo
servo_active = true;
servo_moved = false;
waiting_for_selection = false; // Deja de esperar la selección
}
// Verifica si el servo está activo pero aún no se ha movido
if (servo_active && !servo_moved) {
// Ejecuta la secuencia de parpadeo secuencial mientras espera mover el servo
if (current_time_ms - last_blink_time >= BLINK_INTERVAL) {
last_blink_time = current_time_ms;
int led_to_blink = (current_led + (current_time_ms / BLINK_INTERVAL)) % 3; // Cambia el LED cada 300 ms
for (int i = 0; i < 3; i++) {
digitalWrite(led_pins[i], i == led_to_blink ? HIGH : LOW); // Enciende solo el LED que corresponde
}
}
// Verifica si ha pasado el tiempo seleccionado y si el servo está activo
if (current_time_ms - servo_start_time >= current_time) {
myServo.write(190); // Mueve el servo a 90 grados
servo_move_time = current_time_ms; // Guarda el tiempo en que el servo se movió
servo_moved = true;
}
}
// Verifica si ha pasado 1 segundo desde que el servo se movió a 90 grados
if (servo_moved && (current_time_ms - servo_move_time >= 1000)) {
myServo.write(initial_position); // Regresa el servo a la posición inicial
servo_active = false; // Desactiva el estado del servo
servo_moved = false; // Resetea el estado del servo
// Apaga todos los LEDs al finalizar la secuencia
for (int i = 0; i < 3; i++) {
digitalWrite(led_pins[i], LOW);
}
// Reanuda la espera para la selección de un nuevo tiempo
waiting_for_selection = true;
led_selection_time = current_time_ms;
}
// Actualiza el servo continuamente para asegurar que se mueva correctamente
myServo.refresh();
}