#include <ezButton.h>
#include <LiquidCrystal.h>

// Definición de pines
const int playButton = 6;
const int increaseButton = 5;
const int decreaseButton = 4;
const int directionPin = 2;
const int pulsePin = 3;

// Pines para LCD1602
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

// Botones con debounce
ezButton playBtn(playButton);
ezButton increaseBtn(increaseButton);
ezButton decreaseBtn(decreaseButton);

// Variables para el motor y vueltas
int pulseCount = 200;
int time = 3000;  // Microsegundos entre pulsos
int selectedTurns = 0;
int remainingTurns = 0;
bool motorRunning = false;
bool motorFinalizado = false;
bool cronometroIniciado = false;

// Temporizador
unsigned long startTime;
unsigned long elapsedTime;

// Función para centrar texto en pantalla
void mostrarTextoCentrado(String texto, int linea) {
  int espacios = (16 - texto.length()) / 2;
  lcd.setCursor(espacios, linea);
  lcd.print(texto);
}

// Función para mostrar vueltas seleccionadas
void mostrarVueltas() {
  lcd.clear();
  mostrarTextoCentrado("Vueltas: " + String(selectedTurns), 0);
}

// Función para actualizar el temporizador en pantalla
void actualizarTemporizador() {
  if (cronometroIniciado) {
    elapsedTime = (millis() - startTime) / 1000;  // Convertir a segundos
    lcd.setCursor(0, 1);  // Segunda línea
    lcd.print("Tiempo: ");
    lcd.print(elapsedTime);
    lcd.print(" seg   ");  // Espacios para limpiar caracteres previos
  }
}

// Secuencia de inicio y final (1 vuelta en octavos)
void secuenciaCabina() {
  for (int i = 0; i < 8; i++) {
    lcd.clear();
    mostrarTextoCentrado("Cabina: " + String(i + 1), 0);

    // Esperar 3 segundos y actualizar temporizador constantemente
    unsigned long esperaInicio = millis();
    while (millis() - esperaInicio < 3000) {
      actualizarTemporizador();
    }

    // Mover el motor 1/8 de vuelta
    for (int j = 0; j < pulseCount / 8; j++) {
      digitalWrite(pulsePin, HIGH);
      delayMicroseconds(time);
      digitalWrite(pulsePin, LOW);
      delayMicroseconds(time);
    }
  }
}

// Función para mover el motor
void moverMotor() {
  startTime = millis();  // Iniciar temporizador al presionar Play
  cronometroIniciado = true;
  secuenciaCabina();     // Secuencia de inicio

  lcd.clear();
  mostrarTextoCentrado("En movimiento", 0);
  remainingTurns = selectedTurns;

  for (int i = 0; i < remainingTurns; i++) {
    lcd.clear();
    mostrarTextoCentrado("Faltan: " + String(remainingTurns - i), 0);

    for (int j = 0; j < pulseCount; j++) {
      if (!motorRunning) return;
      digitalWrite(pulsePin, HIGH);
      delayMicroseconds(time);
      digitalWrite(pulsePin, LOW);
      delayMicroseconds(time);
      actualizarTemporizador();
    }
  }

  secuenciaCabina();  // Secuencia final
  motorRunning = false;
  motorFinalizado = true;
  cronometroIniciado = false;

  // Mostrar mensaje de completado y resetear vueltas
  lcd.clear();
  mostrarTextoCentrado("Completado", 0);
  delay(2000);
  
  // Solo resetear el contador y mostrar "Selecciona vueltas"
  selectedTurns = 0;
  lcd.clear();
  mostrarTextoCentrado("Selecciona vueltas", 0);
}

void setup() {
  pinMode(playButton, INPUT_PULLUP);
  pinMode(increaseButton, INPUT_PULLUP);
  pinMode(decreaseButton, INPUT_PULLUP);
  pinMode(directionPin, OUTPUT);
  pinMode(pulsePin, OUTPUT);

  digitalWrite(directionPin, LOW);
  digitalWrite(pulsePin, LOW);

  playBtn.setDebounceTime(50);
  increaseBtn.setDebounceTime(50);
  decreaseBtn.setDebounceTime(50);

  lcd.begin(16, 2);
  mostrarTextoCentrado("Selecciona vueltas", 0);
}

void loop() {
  playBtn.loop();
  increaseBtn.loop();
  decreaseBtn.loop();

  if (increaseBtn.isPressed()) {
    selectedTurns++;
    mostrarVueltas();
    motorFinalizado = false;
  }

  if (decreaseBtn.isPressed() && selectedTurns > 0) {
    selectedTurns--;
    mostrarVueltas();
    motorFinalizado = false;
  }

  if (playBtn.isPressed() && selectedTurns > 0 && !motorRunning && !motorFinalizado) {
    motorRunning = true;
    digitalWrite(directionPin, LOW);
    moverMotor();
  }

  if (playBtn.isPressed() && selectedTurns == 0 && !motorRunning) {
    mostrarTextoCentrado("Seleccione vueltas", 0);
    delay(2000);
    mostrarVueltas();
  }

  // Mostrar el cronómetro constantemente si está iniciado
  if (cronometroIniciado) {
    actualizarTemporizador();
  }
}
A4988