Control de Motor a Pasos con LabVIEW y ESP32

Objetivos

  • Configurar comunicación serial entre LabVIEW y ESP32

  • Controlar velocidad y dirección de un motor a pasos

  • Implementar modos de operación: pasos completos, medios pasos

  • Crear una interfaz gráfica profesional en LabVIEW

Materiales Requeridos

Hardware:

  • ESP32 Dev Board

  • Motor a pasos bipolar (ej: NEMA 17)

  • Driver de motor a pasos (DRV8825 o A4988)

  • Fuente de alimentación 12V para el motor

  • Cables y protoboard

  • Condensadores (100µF y 0.1µF)

Software:

  • LabVIEW

  • Arduino IDE

  • VI Package Manager (VIPM)

  • LIFA (LabVIEW Interface for Arduino)


Parte 1: Conexiones Hardware

Esquema de Conexiones:

text
ESP32 ↔ Driver DRV8825 ↔ Motor a pasos

ESP32       DRV8825      Motor a pasos
-----       -------      -------------
GPIO12  →   STEP
GPIO13  →   DIR
GPIO14  →   ENABLE
3.3V    →   VDD
GND     →   GND

DRV8825 Externa:
VMOT   →  12V externo
GND    →  GND externo
A1, A2 →  Bobina A motor
B1, B2 →  Bobina B motor

Configuración del Driver:

  • VREF: Ajustar según corriente del motor (ej: 0.8V para 1.5A)

  • Microstepping: MS1, MS2, MS3 a GND para pasos completos


Parte 2: Programación del ESP32

Código Arduino para ESP32:

cpp
// Pines de control del motor
#define STEP_PIN 12
#define DIR_PIN 13
#define ENABLE_PIN 14

// Variables de control
int stepsPerRevolution = 200;  // Para motor 1.8°
int stepDelay = 1000;          // Microsegundos
bool motorEnabled = false;
String inputString = "";
bool stringComplete = false;

void setup() {
  // Configurar pines
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIR_PIN, OUTPUT);
  pinMode(ENABLE_PIN, OUTPUT);
  
  // Inicialmente motor deshabilitado
  digitalWrite(ENABLE_PIN, HIGH);  // HIGH deshabilita en DRV8825
  digitalWrite(STEP_PIN, LOW);
  
  // Comunicación serial
  Serial.begin(115200);
  Serial.println("ESP32 Stepper Motor Controller Ready");
  Serial.println("Comandos: ENABLE, DISABLE, STEPS=xxx, DELAY=xxx, DIR=CW, DIR=CCW");
}

void loop() {
  // Procesar comandos seriales
  if (stringComplete) {
    processCommand(inputString);
    inputString = "";
    stringComplete = false;
  }
}

void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

void processCommand(String command) {
  command.trim();
  
  if (command == "ENABLE") {
    enableMotor();
  }
  else if (command == "DISABLE") {
    disableMotor();
  }
  else if (command.startsWith("STEPS=")) {
    int steps = command.substring(6).toInt();
    moveSteps(steps);
  }
  else if (command.startsWith("DELAY=")) {
    stepDelay = command.substring(6).toInt();
    Serial.print("Delay set to: ");
    Serial.println(stepDelay);
  }
  else if (command == "DIR=CW") {
    digitalWrite(DIR_PIN, HIGH);
    Serial.println("Direction: Clockwise");
  }
  else if (command == "DIR=CCW") {
    digitalWrite(DIR_PIN, LOW);
    Serial.println("Direction: Counter-Clockwise");
  }
  else if (command == "STATUS") {
    sendStatus();
  }
  else {
    Serial.println("ERROR: Comando no reconocido");
  }
}

void enableMotor() {
  digitalWrite(ENABLE_PIN, LOW);  // LOW habilita en DRV8825
  motorEnabled = true;
  Serial.println("Motor ENABLED");
}

void disableMotor() {
  digitalWrite(ENABLE_PIN, HIGH);
  motorEnabled = false;
  Serial.println("Motor DISABLED");
}

void moveSteps(int steps) {
  if (!motorEnabled) {
    Serial.println("ERROR: Motor no habilitado");
    return;
  }
  
  Serial.print("Moving ");
  Serial.print(steps);
  Serial.println(" steps");
  
  for(int i = 0; i < steps; i++) {
    digitalWrite(STEP_PIN, HIGH);
    delayMicroseconds(stepDelay);
    digitalWrite(STEP_PIN, LOW);
    delayMicroseconds(stepDelay);
  }
  
  Serial.println("Movement completed");
}

void sendStatus() {
  Serial.println("=== MOTOR STATUS ===");
  Serial.print("Enabled: ");
  Serial.println(motorEnabled ? "YES" : "NO");
  Serial.print("Step Delay: ");
  Serial.println(stepDelay);
  Serial.print("Direction: ");
  Serial.println(digitalRead(DIR_PIN) ? "CW" : "CCW");
  Serial.println("===================");
}

Parte 3: Programación en LabVIEW

VI Principal: Control de Motor a Pasos

Front Panel:

text
Grupo: Configuración Motor
- Puerto Serial (String)
- Baud Rate (Numérico) - 115200
- Steps por Revolución (Numérico) - 200

Grupo: Control de Movimiento
- Número de Pasos (Numérico)
- Velocidad (Dial) - 1-100%
- Dirección (Selector) - CW/CCW
- Botón: Mover Pasos
- Botón: Habilitar Motor
- Botón: Deshabilitar Motor

Grupo: Monitor
- Indicador: Estado Conexión (LED)
- Indicador: Estado Motor (LED)
- Indicador: Pasos Realizados (Numérico)
- Terminal de Mensajes (String)

Diagrama de Bloques:

labview
// Estructura principal
While Loop con control de Stop

Dentro del loop:
1. Inicialización Serial (primera iteración)
   - VISA Configure Serial Port
   - Timeout: 10000 ms

2. Procesamiento de Comandos
   - Case Structure para botones:
     * Habilitar Motor: Enviar "ENABLE\n"
     * Deshabilitar Motor: Enviar "DISABLE\n"
     * Mover Pasos: 
        Calcular delay = map(100-Velocidad, 0, 100, 100, 5000)
        Enviar "DELAY=" + delay + "\n"
        Enviar "DIR=" + dirección + "\n"
        Enviar "STEPS=" + pasos + "\n"

3. Lectura Serial
   - VISA Bytes at Serial Port
   - Si bytes > 0: VISA Read → Terminal de Mensajes

4. Control de Errores
   - Simple Error Handler
   - LED indicador de error

SubVI: Configuración de Comunicación Serial

labview
// Inputs: Puerto, Baud Rate
// Outputs: VISA Resource, Error Out

VISA Configure Serial Port:
  Resource Name: Puerto
  Baud Rate: Baud Rate
  Data Bits: 8
  Parity: None
  Stop Bits: 1
  Flow Control: None

SubVI: Envío de Comandos

labview
// Inputs: Comando, VISA Resource
// Outputs: VISA Resource Out, Error Out

VISA Write:
  Buffer: Comando + "\n"

Parte 4: Implementación Paso a Paso

Paso 1: Preparación del ESP32

  1. Conectar el ESP32 al computador

  2. Cargar el código Arduino proporcionado

  3. Verificar en Monitor Serial que responda a comandos

Paso 2: Creación del VI en LabVIEW

  1. Nuevo VI

    • Crear nuevo Virtual Instrument

    • Guardar como «Control_Motor_Pasos.vi»

  2. Diseño del Front Panel

    labview
    // Agregar controles:
    - String Control: "COMX" (puerto serial)
    - Numeric Control: "115200" (baud rate)
    - Numeric Control: "200" (steps/rev)
    - Numeric Control: "100" (número de pasos)
    - Dial: "Velocidad" (0-100)
    - Ring: "Dirección" (CW, CCW)
    - Boolean Buttons: "Habilitar", "Deshabilitar", "Mover"
    - Stop Button
    
    // Agregar indicadores:
    - LED: "Conexión"
    - LED: "Motor Habilitado"
    - Numeric Indicator: "Pasos Realizados"
    - String Indicator: "Mensajes"
  3. Programación del Diagrama de Bloques

    labview
    // Estructura principal:
    While Loop con [Stop] button
     
    // Inicialización serial (primera vez):
    Case Structure: First Call? → VISA Configure Serial Port
     
    // Procesamiento de eventos:
    Event Structure dentro del While Loop
      - Value Change: Botón Habilitar
      - Value Change: Botón Deshabilitar
      - Value Change: Botón Mover
    
    // Envío de comandos:
    Case Structure para cada botón → VISA Write
    
    // Lectura de respuestas:
    VISA Bytes at Serial Port → If bytes > 0 → VISA Read → Concatenar en Mensajes

Paso 3: Pruebas y Calibración

  1. Prueba de Comunicación

    • Verificar que LabVIEW detecte el puerto correcto

    • Probar comando «STATUS» manualmente

  2. Prueba de Movimiento

    • Comenzar con pocos pasos (10-50)

    • Probar diferentes velocidades

    • Verificar cambio de dirección

  3. Optimización

    • Ajustar delays para movimiento suave

    • Calibrar corriente del motor


Parte 5: Funcionalidades Avanzadas

Modo Medio Paso (Modificar código ESP32):

cpp
// Agregar al código ESP32
void moveHalfSteps(int steps) {
  bool stepState = false;
  for(int i = 0; i < steps; i++) {
    stepState = !stepState;
    digitalWrite(STEP_PIN, stepState ? HIGH : LOW);
    delayMicroseconds(stepDelay/2);
  }
}

Control de Aceleración (LabVIEW):

labview
// SubVI para movimiento acelerado
For Loop con i = 0 to pasos
  Delay actual = delay_inicial + (i * incremento)
  Enviar pulso con delay actual

Interfaz Mejorada en LabVIEW:

labview
// Agregar:
- Selector de modo (Full Step, Half Step, Quarter Step)
- Control de aceleración (Checkbox)
- Gráfico de velocidad en tiempo real
- Contador de revoluciones
- Posicionamiento absoluto

Parte 6: Solución de Problemas

Problemas Comunes:

  1. Motor no se mueve

    • Verificar alimentación 12V

    • Revisar conexiones de bobinas

    • Ajustar VREF del driver

  2. Comunicación serial falla

    • Verificar puerto COM correcto

    • Revisar baud rate (115200)

    • Reiniciar ESP32

  3. Movimiento errático

    • Añadir condensadores de desacople

    • Verificar puesta a tierra

    • Reducir velocidad

Mejoras de Estabilidad:

  1. En el código ESP32:

    cpp
    // Agregar watchdog timer
    #include <esp_task_wdt.h>
    esp_task_wdt_init(5, true);  // Timeout 5 segundos
  2. En LabVIEW:

    • Implementar timeout en VISA Read

    • Agregar reintentos automáticos

    • Log de errores a archivo


Evaluación de la Práctica

Criterios de Evaluación:

  • ✅ Comunicación serial estable

  • ✅ Control preciso de pasos y dirección

  • ✅ Interfaz intuitiva en LabVIEW

  • ✅ Manejo adecuado de errores

  • ✅ Documentación del código

Entregables:

  1. Código Arduino completo

  2. VI de LabVIEW funcionando

  3. Diagrama de conexiones

  4. Video demostrativo del funcionamiento

Esta práctica proporciona una base sólida para el control de motores a pasos con LabVIEW y ESP32, permitiendo expandir funcionalidades según necesidades específicas. ¿Te gustaría que profundice en alguna parte específica o que agregue alguna funcionalidad adicional?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *