#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 SLIDE_SWITCH_PIN 4 // Pin al que está conectado el slide switch (PB4)
#define LED1_PIN 1 // Pin del primer LED (PB1)
#define LED2_PIN 2 // Pin del segundo LED (PB2)
#define DEBOUNCE_DELAY 200 // Retardo para debouncing en milisegundos
#define BLINK_INTERVAL 300 // Intervalo de parpadeo para los LEDs
// Array de pines de LEDs
int led_pins[] = {LED1_PIN, LED2_PIN};
// Array de tiempos asociados a cada LED
int led_times[] = {1000, 5000}; // 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 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
bool process_active = false; // Indica si el proceso está activo
bool last_slide_switch_state = true; // Estado anterior del slide switch (activo por defecto)
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
pinMode(SLIDE_SWITCH_PIN, INPUT_PULLUP); // Configura el slide switch con resistencia de pull-up interna
for (int i = 0; i < 2; 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 y del slide switch
bool button_state = digitalRead(BUTTON_PIN) == LOW;
bool slide_switch_state = digitalRead(SLIDE_SWITCH_PIN) == LOW; // Ajustado para switch activo en 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 && !process_active) {
// Apaga el LED actual
digitalWrite(led_pins[current_led], LOW);
// Cambia al siguiente LED
current_led = (current_led + 1) % 2;
// 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];
}
}
// Verifica si el slide switch ha cambiado de estado
if (slide_switch_state && !last_slide_switch_state) {
// Transición del estado del slide switch de inactivo a activo
if (!process_active) {
// Inicia el proceso solo si no está activo
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
process_active = true; // Marca el proceso como activo
}
}
// Verifica si el slide switch ha cambiado de estado (desactivado a activado)
if (!slide_switch_state && last_slide_switch_state) {
// Transición del estado del slide switch de activo a inactivo
if (process_active) {
// Reinicia el proceso sólo si estaba activo
process_active = false; // Marca el proceso como inactivo
waiting_for_selection = true; // Reanuda la espera para una nueva selección
// Apaga todos los LEDs al finalizar la secuencia
for (int i = 0; i < 2; i++) {
digitalWrite(led_pins[i], LOW);
}
// Regresa el servo a la posición inicial si estaba en movimiento
myServo.write(initial_position);
servo_active = false; // Desactiva el estado del servo
servo_moved = false; // Resetea el estado del servo
}
}
// Actualiza el estado anterior del slide switch
last_slide_switch_state = slide_switch_state;
// 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)) % 2; // Cambia el LED cada 300 ms
for (int i = 0; i < 2; 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
process_active = false; // Marca el proceso como inactivo
waiting_for_selection = true; // Reanuda la espera para una nueva selección
// Apaga todos los LEDs al finalizar la secuencia
for (int i = 0; i < 2; i++) {
digitalWrite(led_pins[i], LOW);
}
}
// Actualiza el servo continuamente para asegurar que se mueva correctamente
myServo.refresh();
}