Control Digital de Inversión de Giro con Transición Segura para Motor DC

 Control Digital de Inversión de Giro con Transición Segura para Motor DC

En esta publicación llevamos el control del motor DC un paso más allá: implementaremos el cambio de sentido de giro mediante un pulsador, utilizando dos salidas PWM independientes desde el NodeMCU (ESP8266) hacia el puente H y agregando una pausa de seguridad antes de la inversión.

1. Esquema del Circuito y Adaptación de Nivel



Para controlar ambas ramas del puente H de manera independiente, se duplica el circuito adaptador de nivel con transistor NPN (2N2222 en configuración emisor común):

  • Salida PWM1 (Pin D3 / GPIO0): Controla el transistor Q5 (2N2222) a través de R9 (1 kΩ) para activar la primera rama del puente H.

  • Salida R10(1) (Pin D5 / GPIO14): Controla el transistor Q6 (2N2222) a través de R11 (1 kΩ) para activar la rama opuesta del puente H.

  • Pulsador de Control: Conectado al pin D2 (GPIO4) configurado con resistencia interna pull-up. El otro extremo del pulsador va directamente a GND.

Como se aprecia en las imágenes de la simulación:

  • Estado 1 (Giro a la Derecha): La señal PWM1 se encuentra activa conmuntando voltaje (V = 1.28 V promedio en la sonda), mientras que la línea opuesta R10(1) permanece en nivel alto sostenido (V = 12 V) manteniendo la rama inactiva.

  • Estado 2 (Giro a la Izquierda): Tras presionar el pulsador, las salidas se invierten de forma transparente. Ahora PWM1 pasa a reposo (V = 12.10 V) y R10(1) conmuta la señal PWM (V = 1.29 V promedio), haciendo que el motor gire en sentido contrario.



2. Código en Arduino IDE

C++
// Pines de salida PWM conectados al Puente H
const int pinGiroA = 3; // Salida PWM Sentido A (D3 / GPIO0)
const int pinGiroB = 5; // Salida PWM Sentido B (D5 / GPIO14)

// Pin de entrada para el pulsador de cambio de sentido
const int pinPulsador = 2; // Pulsador conectado en D2 (GPIO4) y GND

// Configuración de la señal PWM (500 Hz -> Período = 2000 microsegundos)
const unsigned long periodoTotalUs = 2000; 
int valorPWM = 70; // Ciclo de trabajo (0 a 255)

// Variables de tiempo para PWM
unsigned long tiempoON = 0;
unsigned long ultimoTiempoMicros = 0;

// Estado del sistema y antirrebote del pulsador
bool sentidoActual = true; // true = Giro A, false = Giro B
bool estadoAnteriorPulsador = HIGH;

void setup() {
  pinMode(pinGiroA, OUTPUT);
  pinMode(pinGiroB, OUTPUT);
  
  // Configuración del puerto como entrada con Pull-Up interna
  pinMode(pinPulsador, INPUT_PULLUP);

  // Calcular el tiempo activo de la señal
  tiempoON = (periodoTotalUs * valorPWM) / 255;
}

void loop() {
  // --- LECTURA Y DETECCIÓN DEL PULSADOR ---
  bool estadoPulsador = digitalRead(pinPulsador);

  // Detectar flanco de bajada (cuando se presiona el pulsador pasa de HIGH a LOW)
  if (estadoAnteriorPulsador == HIGH && estadoPulsador == LOW) {
    // 1. Apagar ambas salidas para frenar el motor
    digitalWrite(pinGiroA, LOW);
    digitalWrite(pinGiroB, LOW);

    // 2. Pausa de seguridad (500 ms) para disipar picos de corriente
    delay(500);

    // 3. Invertir la variable de sentido
    sentidoActual = !sentidoActual;

    // 4. Sincronizar el temporizador de microsegundos
    ultimoTiempoMicros = micros();
  }
  estadoAnteriorPulsador = estadoPulsador;

  // --- GENERACIÓN DE PWM NO BLOQUEANTE SEGÚN EL SENTIDO SELECCIONADO ---
  unsigned long tiempoActual = micros();
  unsigned long tiempoTranscurrido = tiempoActual - ultimoTiempoMicros;

  if (sentidoActual) {
    // Sentido A Activo, Sentido B Apagado
    digitalWrite(pinGiroB, LOW);

    if (tiempoTranscurrido < tiempoON) {
      digitalWrite(pinGiroA, HIGH);
    } else if (tiempoTranscurrido < periodoTotalUs) {
      digitalWrite(pinGiroA, LOW);
    } else {
      ultimoTiempoMicros = tiempoActual;
    }
  } else {
    // Sentido B Activo, Sentido A Apagado
    digitalWrite(pinGiroA, LOW);

    if (tiempoTranscurrido < tiempoON) {
      digitalWrite(pinGiroB, HIGH);
    } else if (tiempoTranscurrido < periodoTotalUs) {
      digitalWrite(pinGiroB, LOW);
    } else {
      ultimoTiempoMicros = tiempoActual;
    }
  }
}

3. Aspectos Clave de la Implementación

  • Entrada con Resistencia Pull-Up Interna: Al usar INPUT_PULLUP, evitamos colocar una resistencia física externa para el pulsador. El pin se mantiene en 3.3 V (HIGH) por defecto y pasa a 0 V (LOW) solo cuando el usuario lo presiona.

  • Detección por Flanco de Bajada: El programa detecta la transición de HIGH a LOW. Esto garantiza que la inversión ocurra una sola vez por cada pulsación, independientemente del tiempo que el usuario mantenga presionado el botón.

  • Importancia de la Pausa de Seguridad (delay(500)): Invertir la polaridad de un motor DC en pleno movimiento genera un pico de corriente extremadamente alto debido a la fuerza electromotriz de retorno (f.e.m.). Apagar ambas salidas durante 500 ms permite que la inercia del motor disminuya, protegiendo los transistores TIP32 y TIP41 de destruirse por sobrecorriente.

Comentarios

Entradas populares de este blog

FUENTE DC CON PROTECCIÓN ELECTRÓNICA E INDICADORES LED

Control de velocidad y sentido de giro de un motor de corriente continua

Controlador de giro para motor paso a paso unipolar mediante 555, contador y lógica combinacional