Control Interactivo de Motor Paso a Paso con NodeMCU/Arduino - Programación No Bloqueante, Inversión de Giro y Control de Velocidad
Control Interactivo de Motor Paso a Paso con NodeMCU/Arduino - Programación No Bloqueante, Inversión de Giro y Control de Velocidad
En esta entrega evolucionaremos nuestro sistema de control para motores paso a paso unipolares. Migraremos de una secuencia rígida hacia una interfaz interactiva y multitarea, utilizando la función millis() para evitar el uso de funciones bloqueantes como delay(). Esto permitirá al microcontrolador atender en tiempo real las peticiones de 4 pulsadores físicos mientras mantiene el motor en movimiento continuo.
1. Interfaz de Usuario e Integración en Protoboard
Para esta práctica se incorporan 4 pulsadores táctiles conectados a las entradas D0, D1, D2 y D3 del NodeMCU (o pines digitales 0, 1, 2 y 3 en entornos genéricos). Cada entrada se configura mediante la resistencia interna de pull-up (INPUT_PULLUP), requiriendo únicamente conectar el otro extremo del pulsador a masa (GND):
D0 (S-GIRO): Invierte el sentido de giro del motor (Horario / Antihorario). Para evitar daños mecánicos o brincos bruscos de corriente en el driver, el programa realiza una pausa de seguridad de 300 ms antes de conmutar la secuencia.
D1 (+VEL): Incrementa la velocidad de rotación reduciendo el intervalo de tiempo entre pasos (
pasoDelay).D2 (-VEL): Disminuye la velocidad de rotación aumentando el intervalo entre pasos.
D3 (ON-OFF): Activa o pausa la marcha del motor de forma inmediata, apagando todas las fases para evitar consumo innecesario en reposo.
Filtro Anti-rebote (Debounce): Implementado por software con un temporizador de 200 ms, garantizando que cada pulsación sea leída una sola vez sin falsos disparos provocados por el rebote mecánico.
2. Mapeo de Conexiones y Display de Estados
Entradas de Control: Conectar los 4 pulsadores entre los pines D0, D1, D2, D3 y la línea común de GND.
Display de LEDs: Mantener la etapa de visualización con 4 LEDs (D5, D6, D7, D8) y sus resistencias limitadoras de 330 ohms conectados en paralelo a las salidas de fase A, B, C y D.
Driver de Potencia: Conectar las líneas de control A, B, C y D hacia la tira de pines del driver discreto (transistores NPN 2N2222 y diodos 1N4007).
Alimentación y Masa Común: Alimentar el driver a través de la bornera azul e interconectar obligatoriamente la masa (GND) de la fuente de alimentación, del microcontrolador y del protoboard.
3. Código Fuente Completo (Multitarea No Bloqueante)
// --- PINES DE SALIDA PARA FASES DEL MOTOR (D5, D6, D7, D8) ---
const int motorPins[4] = {5, 6, 7, 8};
// --- PINES DE ENTRADA PARA PULSADORES (D0, D1, D2, D3) ---
const int pinInvertir = 0; // D0: Invertir sentido de giro
const int pinVelMas = 1; // D1: Incrementar velocidad
const int pinVelMenos = 2; // D2: Decrementar velocidad
const int pinStartStop = 3; // D3: Marcha / Parada
// --- MATRIZ DE SECUENCIA WAVE DRIVE ---
const int waveDrive[4][4] = {
{HIGH, LOW, LOW, LOW}, // Paso 0
{LOW, HIGH, LOW, LOW}, // Paso 1
{LOW, LOW, HIGH, LOW}, // Paso 2
{LOW, LOW, LOW, HIGH} // Paso 3
};
// --- CONTROL DE VELOCIDAD Y ESTADO ---
int pasoDelay = 100; // Tiempo inicial por paso (100 ms)
const int pasoDelayMin = 10; // Velocidad máxima (10 ms entre pasos)
const int pasoDelayMax = 500; // Velocidad mínima (500 ms entre pasos)
const int pasoDelta = 15; // Factor de cambio de velocidad (15 ms)
int pasoActual = 0;
bool sentidoHorario = true;
bool motorActivo = true;
// --- VARIABLES DE TIEMPO (MILLIS) ---
unsigned long ultimoTiempoPaso = 0;
unsigned long ultimoTiempoBtn = 0;
const unsigned long tiempoDebounceMs = 200; // Anti-rebote por software
void apagarMotor() {
for (int i = 0; i < 4; i++) {
digitalWrite(motorPins[i], LOW);
}
}
void aplicarPaso(int paso) {
for (int i = 0; i < 4; i++) {
digitalWrite(motorPins[i], waveDrive[paso][i]);
}
}
void setup() {
// Configurar las 4 salidas del motor
for (int i = 0; i < 4; i++) {
pinMode(motorPins[i], OUTPUT);
}
apagarMotor();
// Configurar las 4 entradas con Pull-up interna
pinMode(pinInvertir, INPUT_PULLUP);
pinMode(pinVelMas, INPUT_PULLUP);
pinMode(pinVelMenos, INPUT_PULLUP);
pinMode(pinStartStop, INPUT_PULLUP);
}
void loop() {
unsigned long tiempoActual = millis();
// =========================================================
// 1. LECTURA Y PROCESAMIENTO DE PULSADORES (ANTI-REBOTE)
// =========================================================
if (tiempoActual - ultimoTiempoBtn >= tiempoDebounceMs) {
// --- PULSADOR D0: INVERTIR SENTIDO DE GIRO ---
if (digitalRead(pinInvertir) == LOW) {
motorActivo = false; // Pausa temporal
apagarMotor();
delay(300); // Pausa de seguridad (300 ms)
sentidoHorario = !sentidoHorario; // Cambiar sentido
motorActivo = true;
ultimoTiempoBtn = tiempoActual;
}
// --- PULSADOR D1: INCREMENTAR VELOCIDAD ---
else if (digitalRead(pinVelMas) == LOW) {
pasoDelay -= pasoDelta;
if (pasoDelay < pasoDelayMin) pasoDelay = pasoDelayMin;
ultimoTiempoBtn = tiempoActual;
}
// --- PULSADOR D2: DECREMENTAR VELOCIDAD ---
else if (digitalRead(pinVelMenos) == LOW) {
pasoDelay += pasoDelta;
if (pasoDelay > pasoDelayMax) pasoDelay = pasoDelayMax;
ultimoTiempoBtn = tiempoActual;
}
// --- PULSADOR D3: MARCHA / PARADA ---
else if (digitalRead(pinStartStop) == LOW) {
motorActivo = !motorActivo;
if (!motorActivo) apagarMotor();
ultimoTiempoBtn = tiempoActual;
}
}
// =========================================================
// 2. GENERACIÓN DE SECUENCIA NO BLOQUEANTE PARA EL MOTOR
// =========================================================
if (motorActivo && (tiempoActual - ultimoTiempoPaso >= (unsigned long)pasoDelay)) {
ultimoTiempoPaso = tiempoActual;
// Incrementar o decrementar el paso según el sentido de giro
if (sentidoHorario) {
pasoActual = (pasoActual + 1) % 4;
} else {
pasoActual = (pasoActual - 1 + 4) % 4;
}
aplicarPaso(pasoActual);
}
}
4. Análisis de Funcionamiento
Al ejecutar la simulación en Proteus o en el circuito físico:
El temporizador basado en
millis()compara continuamente el tiempo transcurrido, permitiendo que la lectura de las entradas sea instantánea sin interrumpir la secuencia de conmutación.Pulsar S-GIRO conmuta la dirección de barrido de la matriz (Paso 0->1->2->3 o Paso 3->2->1->0), invirtiendo el giro físico del motor.
Los pulsadores +VEL y -VEL ajustan dinámicamente la variable
pasoDelayentre sus límites configurados (10 ms a 500 ms), acelerando o ralentizando la secuencia visualizada en el banco de LEDs.El pulsador ON-OFF ofrece control de parada inmediata desenergizando todas las bobinas para proteger los transistores en periodos de inactividad.
Comentarios
Publicar un comentario