#include <AccelStepper.h>

// Pines del driver ULN2003 conectados al ESP32
const int IN1 = 19;
const int IN2 = 18;
const int IN3 = 5;
const int IN4 = 17;

// Pin del potenciómetro
const int pinPot = 34;

// Pasos para una vuelta completa del 28BYJ-48
// En modo medio paso se suelen usar aproximadamente 4096 pasos
const int pasosPorVuelta = 4096;

// Creamos el objeto motor
// HALF4WIRE significa motor de 4 hilos en modo medio paso
// El orden IN1, IN3, IN2, IN4 suele funcionar bien con el 28BYJ-48 + ULN2003
AccelStepper motor(AccelStepper::HALF4WIRE, IN1, IN3, IN2, IN4);

void setup() {
  Serial.begin(115200);

  // Configuramos la lectura analógica a 12 bits: 0 a 4095
  analogReadResolution(12);

  // Velocidad máxima en pasos por segundo
  motor.setMaxSpeed(800);

  // Aceleración en pasos por segundo al cuadrado
  motor.setAcceleration(400);

  Serial.println("28BYJ-48 controlado con potenciometro usando AccelStepper");
}

void loop() {
  // Leer el potenciómetro
  int valorPot = analogRead(pinPot);

  // Convertir lectura del potenciómetro a una posición entre 0 y 4096 pasos
  long posicionObjetivo = map(valorPot, 0, 4095, 0, pasosPorVuelta);

  // Mandamos al motor moverse hacia esa posición
  motor.moveTo(posicionObjetivo);

  // Esta función debe ejecutarse continuamente
  // Hace que el motor avance poco a poco hacia la posición objetivo
  motor.run();

  // Mostrar datos cada 300 ms
  static unsigned long tiempoAnterior = 0;

  if (millis() - tiempoAnterior > 300) {
    tiempoAnterior = millis();

    float angulo = motor.currentPosition() * 360.0 / pasosPorVuelta;

    Serial.print("Potenciometro: ");
    Serial.print(valorPot);
    Serial.print(" | Posicion objetivo: ");
    Serial.print(posicionObjetivo);
    Serial.print(" | Posicion actual: ");
    Serial.print(motor.currentPosition());
    Serial.print(" | Angulo aproximado: ");
    Serial.println(angulo);
  }
}
