#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();
}
}