// Version: 2.9
#include <Arduino.h>
// Pines de conexión
#define STEP_PIN 20
#define DIR_PIN 21
#define INCREASE_PIN 5
#define PLAY_PIN 2
#define STOP_PIN 4
#define CABIN_BUTTON_START 12
#define CABIN_BUTTON_END 19
// Configuración del motor paso a paso
#define STEPS_PER_REV 200
#define CABIN_STEPS 25
#define TOTAL_STEPS 200
// Variables de estado
int currentSteps = 0; // Posición actual en pasos
int targetSteps = 0;
int selectedRevolutions = 0;
bool isRunning = false;
volatile bool stopRequested = false; // Volatile para usar con interrupciones
void IRAM_ATTR handleStop() {
stopRequested = true; // Interrupción para manejar el botón "Stop"
}
void setup() {
Serial.begin(115200);
// Configurar pines
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(INCREASE_PIN, INPUT_PULLUP);
pinMode(PLAY_PIN, INPUT_PULLUP);
pinMode(STOP_PIN, INPUT_PULLUP);
for (int i = CABIN_BUTTON_START; i <= CABIN_BUTTON_END; i++) {
pinMode(i, INPUT_PULLUP);
}
// Configurar interrupción para el botón "Stop"
attachInterrupt(digitalPinToInterrupt(STOP_PIN), handleStop, FALLING);
// Mensaje inicial
Serial.println("Ferris Wheel By Ferdinand Insert Coin");
}
void loop() {
if (digitalRead(INCREASE_PIN) == LOW && !isRunning) {
increaseRevolutions();
delay(200); // Anti-rebote
}
if (digitalRead(PLAY_PIN) == LOW && !isRunning) {
playSequence();
delay(200); // Anti-rebote
}
for (int i = CABIN_BUTTON_START; i <= CABIN_BUTTON_END; i++) {
if (digitalRead(i) == LOW) {
moveToCabin(i - CABIN_BUTTON_START + 1);
delay(200); // Anti-rebote
}
}
// Manejar stop activado y resetear bandera
if (stopRequested) {
emergencyStop();
}
}
void increaseRevolutions() {
selectedRevolutions++;
Serial.print("Revolutions selected: ");
Serial.println(selectedRevolutions);
}
void playSequence() {
if (selectedRevolutions == 0) {
Serial.println("Please insert coin");
return;
}
// Verificar y mover a Cabina 1 antes de iniciar cualquier secuencia
if (currentSteps != 0) {
Serial.println("Returning to Cabin 1 before starting sequence...");
moveToCabin(1);
}
Serial.println("Starting passenger boarding...");
stopRequested = false;
isRunning = true;
// Subida de pasajeros
performBoardingSequence();
// Vueltas completas
performRevolutions();
// Bajada de pasajeros (ahora en sentido horario desde Cabina 1)
performUnboardingSequence();
// Verificar y mover a Cabina 1 al final de la secuencia
if (currentSteps != 0) {
Serial.println("Returning to Cabin 1 after sequence...");
moveToCabin(1);
}
// Reset del sistema
isRunning = false;
selectedRevolutions = 0;
Serial.println("System reset. Ready for new game.");
}
void performBoardingSequence() {
for (int cabin = 1; cabin <= 8; cabin++) {
if (stopRequested) return; // Detener si se solicitó
moveToCabin(cabin);
delay(5000); // Espera en la cabina
}
}
void performRevolutions() {
int totalStepsToMove = selectedRevolutions * TOTAL_STEPS;
for (int i = 0; i < totalStepsToMove; i++) {
if (stopRequested) return; // Detener si se solicitó
stepMotor(true); // Mueve el motor en sentido horario
}
}
void performUnboardingSequence() {
for (int cabin = 1; cabin <= 8; cabin++) {
if (stopRequested) return; // Detener si se solicitó
moveToCabin(cabin);
delay(5000); // Espera en la cabina
}
}
void moveToCabin(int cabin) {
if (stopRequested) {
Serial.println("Motor stopped. Cannot move to cabin.");
return;
}
int target = (cabin - 1) * CABIN_STEPS;
int stepsToMove = calculateShortestPath(target);
moveSteps(stepsToMove);
currentSteps = (currentSteps + stepsToMove + TOTAL_STEPS) % TOTAL_STEPS;
Serial.print("Moved to cabin ");
Serial.println(cabin);
}
int calculateShortestPath(int target) {
int distance = target - currentSteps;
// Asegura la distancia más corta para el movimiento
if (distance > TOTAL_STEPS / 2) {
distance -= TOTAL_STEPS;
} else if (distance < -TOTAL_STEPS / 2) {
distance += TOTAL_STEPS;
}
return distance;
}
void moveSteps(int steps) {
bool direction = steps > 0;
digitalWrite(DIR_PIN, direction);
for (int i = 0; i < abs(steps); i++) {
if (stopRequested) {
Serial.println("Emergency stop requested. Stopping motor.");
return; // Detener la secuencia inmediatamente
}
stepMotor(direction);
}
}
void stepMotor(bool direction) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(500);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(500);
}
void emergencyStop() {
Serial.println("Emergency stop activated. System halted.");
stopRequested = false; // Reset stopRequested
isRunning = false; // Allows future cabin movement
selectedRevolutions = 0; // Clear revolutions
Serial.println("You can now move to a specific cabin or press Play.");
}
// Version: 2.9