// Pines del motor
const int motor_A = 23;
const int motor_B = 22;
const int motor_C = 19;
const int motor_D = 18;
const int ledMarcha = 21;
const int ledEmergencia = 15;
// Control de velocidad e iluminación del LED correspondiente
#define ledVelocidad 25
#define pinPotencia 34
// Variables globales
int adcVal; // Valor digital del ADC (potenciómetro)
int retardo = 20000; // Retardo inicial (en microsegundos)
float tensionDAC; // Tensión calculada a partir del ADC
#define NUMSEC 4 // 4 u 8 líneas de secuencia de movimiento
int tabla_pasos[NUMSEC][4] = { // A B C D
{HIGH, HIGH, LOW, LOW},
{LOW, HIGH, HIGH, LOW},
{LOW, LOW, HIGH, HIGH},
{HIGH, LOW, LOW, HIGH}
};
#define NPASOS_VUELTA_INTERNA 32 // 32 pasos completo, 64 semipasos
#define RELACION_VUELTAS_ENGRANAJE 64 // Vueltas internas para hacer 1 vuelta externa
int npasos = 0; // Llega a NPASOS_VUELTA_INTERNA y cuenta vuelta interna++
int nvueltas_internas = 0; // Llega a RELACION_VUELTAS_ENGRANAJE y cuenta vuelta externa++
int nvueltas_externas = 0; // Lleva la cuenta de vueltas del eje externo
// Variables del temporizador
hw_timer_t* timer = NULL; // Puntero a la estructura del temporizador
volatile bool timerFlag = false; // Bandera para la señal del temporizador
// Función para el siguiente paso
void sgte_paso() {
static int idsec = 0; // Va recorriendo la tabla
// Escribimos los valores nuevos de la tabla en los pines ABCD
digitalWrite(motor_A, tabla_pasos[idsec][0]);
digitalWrite(motor_B, tabla_pasos[idsec][1]);
digitalWrite(motor_C, tabla_pasos[idsec][2]);
digitalWrite(motor_D, tabla_pasos[idsec][3]);
if ((++idsec) == NUMSEC) idsec = 0;
}
// Interrupción del temporizador
void IRAM_ATTR finTimer() {
timerFlag = true; // Señal para realizar el paso en el loop principal
}
void setup() {
// Pines de salida del motor
pinMode(motor_A, OUTPUT);
pinMode(motor_B, OUTPUT);
pinMode(motor_C, OUTPUT);
pinMode(motor_D, OUTPUT);
// Configuración LEDs
pinMode(ledMarcha, OUTPUT);
pinMode(ledEmergencia, OUTPUT);
// Configuración del ADC
analogReadResolution(12); // Resolución de 12 bits (0-4095)
analogSetAttenuation(ADC_11db); // Rango de 150 mV a 3100 mV
// Inicializamos el puerto serie
Serial.begin(115200);
delay(100);
Serial.println("----------------");
Serial.println("Comienzo programa control motor paso a paso");
delay(1000);
// Configuración del temporizador
timer = timerBegin(1000000); // Configuración con frecuencia de 1 MHz
timerAttachInterrupt(timer, &finTimer); // Asocia la ISR al temporizador
timerAlarm(timer, retardo, true, 0); // Configura la alarma con un retardo inicial
timerStart(timer); // Inicia el temporizador
}
unsigned long t1 = 0;
void loop() {
digitalWrite(ledMarcha, HIGH);
// Leer el potenciómetro y calcular potencia
adcVal = analogRead(pinPotencia);
// Calcular la tensión del ADC (convertida a rango 0-3.3V)
float voltageADC = adcVal / 4095.0 * 3.3;
// Calcular el nuevo retardo (2 ms a 20 ms) según la lógica dada
float minRetardo = 2000.0; // Retardo mínimo (máxima velocidad)
float maxRetardo = 20000.0; // Retardo máximo (mínima velocidad)
retardo = minRetardo + (maxRetardo - minRetardo) * (adcVal / 4095.0);
// Si el retardo cambia, actualiza el temporizador
static int retardoPrevio = 0;
if (abs(retardo - retardoPrevio) > 10) { // Actualiza solo si hay un cambio significativo
retardoPrevio = retardo;
timerStop(timer); // Detén el temporizador
timerWrite(timer, 0); // Reinicia el contador
timerAlarm(timer, retardo, true, 0); // Reconfigura la alarma con el nuevo retardo
timerStart(timer); // Reinicia el temporizador
}
// Calcular el brillo del LED inversamente proporcional al retardo
int brilloLed = 255.0 * (1.0 - (adcVal / 4095.0)); // Inverso al valor del potenciómetro
dacWrite(ledVelocidad, brilloLed); // Ajustar la luminosidad del LED
// Control del motor en función de la bandera del temporizador
if (timerFlag) {
timerFlag = false; // Reinicia la bandera
npasos++;
if (npasos == NPASOS_VUELTA_INTERNA) {
npasos = 0;
nvueltas_internas++;
if (nvueltas_internas == RELACION_VUELTAS_ENGRANAJE) {
nvueltas_internas = 0;
nvueltas_externas++;
}
}
sgte_paso(); // Ejecuta el siguiente paso del motor
}
// Imprimir información del estado del motor cada segundo
if (millis() > t1 + 1000) {
t1 = millis();
Serial.printf("Vueltas externas: %d, internas: %d, npasos: %d, retardo: %d us, brillo LED: %d, ADC: %d\n",
nvueltas_externas, nvueltas_internas, npasos, retardo, brilloLed, adcVal);
}
}