#include <Arduino.h>
#include <Keypad.h>

// Declaración de los pines del motor paso a paso
const int DIR = 3;
const int STEP = 4;

// Declaración del pin del switch
const int SWITCH_PIN = 5;

// Declaración del pin del potenciómetro
const int POT_PIN = PA0; // Pin analógico A0

// Definir los pines del keypad
#define R1 D6
#define R2 D7
#define R3 D8
#define R4 D9
#define C1 D10
#define C2 D11
#define C3 D12
#define C4 D13

const byte ROWS = 4; // Cuatro filas
const byte COLS = 4; // Cuatro columnas

char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = {R1, R2, R3, R4}; // Conectar a las filas del keypad
byte colPins[COLS] = {C1, C2, C3, C4}; // Conectar a las columnas del keypad

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// Declaración de las variables para la velocidad
int pot_value = 0;
int motor_speed = 0;
int steps_per_rev = 0; // Este valor será actualizado por el keypad
bool distance_entered = false;

void setup() {
  // Configuración inicial
  Serial.begin(115200);
  Serial.println("Hello, STM32!");

  pinMode(STEP, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(POT_PIN, INPUT_ANALOG); // Configurar el pin del potenciómetro como entrada analógica
  pinMode(SWITCH_PIN, INPUT_PULLUP); // Configurar el pin del switch como entrada con pull-up
}

void requestDistance() {
  // Pedir al usuario que ingrese la distancia y presione '#'
  Serial.println("Ingrese la distancia que el motor debe recorrer y presione '#':");

  // Leer la entrada del keypad hasta que se presione '#'
  String input = "";
  while (!distance_entered) {
    char key = keypad.getKey();
    if (key) {
      if (key == '#') {
        steps_per_rev = input.toInt(); // Convertir la entrada a un entero
        Serial.print("Distancia ingresada: ");
        Serial.println(steps_per_rev);
        distance_entered = true; // Indicar que se ha ingresado la distancia
      } else if (key >= '0' && key <= '9') {
        input += key; // Añadir el dígito a la entrada
        Serial.print(key); // Mostrar el dígito en el puerto serie
      }
    }
    delay(50); // Pequeño retraso para estabilizar la lectura del keypad
  }
}

// Función para la activación del motor con control de velocidad y cambio instantáneo de dirección
void activationFAN(int speed, int steps) {
  bool currentDirection = digitalRead(SWITCH_PIN) == LOW;
  digitalWrite(DIR, currentDirection);
  for (int i = 0; i < steps; i++) {
    // Verificar si hay un cambio en la dirección del switch
    bool newDirection = digitalRead(SWITCH_PIN) == LOW;
    if (newDirection != currentDirection) {
      currentDirection = newDirection;
      digitalWrite(DIR, currentDirection);
      if (currentDirection) {
        Serial.println("Girando en sentido horario");
      } else {
        Serial.println("Girando en sentido antihorario");
      }
    }
    digitalWrite(STEP, HIGH);
    delayMicroseconds(speed);
    digitalWrite(STEP, LOW);
    delayMicroseconds(speed);
  }
}

// Función para leer el valor del potenciómetro y calcular la velocidad del motor
int readPotentiometer() {
  pot_value = analogRead(POT_PIN);
  // Mapear el valor del potenciómetro (0-4095) a un rango de velocidad (9000-300 microsegundos)
  motor_speed = map(pot_value, 0, 4095, 300, 9000); // Ajustado para STM32 (resolución de 12 bits)
  return motor_speed;
}

void loop() {
  // Solicitar la distancia si no se ha ingresado aún
  if (!distance_entered) {
    requestDistance();
  }

  // Leer el valor del potenciómetro y ajustar la velocidad del motor
  int speed = readPotentiometer();
  Serial.print("Potentiometer Value: ");
  Serial.print(pot_value);
  Serial.print(" - Motor Speed (us): ");
  Serial.println(speed);

  // Activar el motor con control de velocidad y cambio instantáneo de dirección
  activationFAN(speed, steps_per_rev);

  // Reiniciar el estado para la próxima solicitud de distancia
  distance_entered = false;
}
A4988