Control manual de tres motores paso a paso con ESP32.

OBJETIVO: Comprobar como las salidas PWM del ESP32 pueden controlar motores Nema17 con drivers TMC2209 utilizando un control manual con potenciometros conectados a pines ADC al mismo tiempo que monitorizamos la freq. aplicada y la velocidar en rpm en una pantalla tft.

COMPONENTES:

Estos componentes estan expuestos en el blog.

  • ESP32 wroom 32- (38 pines)
  • Módulo drivers(x3 )TMC2209
  • Pantalla tft(ili 9341)-320*240
  • Tres potenciometros B2K
  • Tres interruptores pulsadores
  • Tres tipos de motores paso a paso
  • Fuente regulable entre 5-12Vdc

Distribución de pines:

Conexionado potenciometros e interruptores con indicación led.

Como ire explicacndo,los potenciometros alimentados con 3V3 del ESP32, se conectaran con las “solo entradas”, pines 36, 39 y 34. Los pulsadores interruptores estan en pull-up y van conectados al módulo de los drivers, corresponden con la señal DIR .Aunque tambien se podrían haber conectado con el ESP32, necesario si se quiere conectar en remoto a traves de wifi.

Los led estan en paralelo con la salida de los potenciometros, asi tendremos visualización directa con cambio de intensidad de luz al aumentar -en nuestro caso- las revoluciones.

Motores Paso a Paso:

Voy a utilizar dos motores Nema 17 de diferente consumo y potencia (17HS13-0404S) y (17hd4800-22B) además del popular 28BYJ-48 (trabajando como bipolar). Todos conectados a l módulo de tres drivers TMC2208 o TMC2209. Este módulo de pruebas tiene dos salidas en paralelo para cada motor y tres entradas con las señales STEP-DIR-ENA. En paralelo con ENA se dispone de un led verde-rojo-amarillo respectivo a cada entrada y que nos servira para su identificación con el hardware asociado y la programación. El led estara encendido mientras ENA este en HIGH, apagandose cuando se active su motor asociado (ENA=LOW)

STEPPER MOTORPASOS/REVFRECUENCIA DE REFERENCIA (1 rpm)
28BYJ-4832768546.13 Hz
NEMA 17 (17HS13-0404S)320053,3 Hz
NEMA 17 -(17hd4800-22B)320053.3 Hz

En la tabla ,y para poder entender la programación, pongo de relieve la frecuencia de referencia a 1 rpm de estos motores, Quere decir que el pulso enviado a la entrada STEP de 53,3 Hz y periodo de 18,75 mseg, va a ser que el motor gire a una v=1 rpm. El incremento de la frecuencia es proporcional al incremento de velocidad. Asi, una freq=533 Hz nos dará una v=10 rpm

<float rpmgreen = (freqgreen / 53.3);>

Los motores NEMA17 giran 1,8 grados por paso, necesitaran 200 pasos para completar una vuelta y al utilizar 1/16 micropasos- cada paso se convierte en 16 micropasos- seran entonces 200×16=3200 micropasos necesarios para completar la vuelta.

Los motores 28BYJ-48 tienen una reducción de 1/64 con un angulo de paso de 5,625 grados, y son unipolares pero lo utilizaremos como bipolares omitiendo el hilo comun de color rojo, entonces pasaremos de 4 medias bobinas a dos bobinados completos, importante de tener en cuenta porque la reducción ahora equivaldrá a 1/32, entonces el calculo de los pasos / vuelta será:

360/5,625*32=2048

y al utilizar 1/16 micropasos

2048×16=32768 pasos/vuelta

La freq de referencia será el resultado de dividir el número de pasos entre 60.

Rango de frecuencias a utilizar.

Esto dependera del limite de rpm maximo que pueda alcanzar cada tipo de motor. En un estudio preliminar se vio que Los Nema17 pueden llegar hasta las 200 rpm,lo que implica una freq= 53,33*200= 10660 Hz.

En el caso del 28BYJ-48 alcanzan hasta 20 rpm, freq=546,13*20= 10922,6 Hz

Salidas PWM como generador de frecuencia.

Gracias a la configuración PWM en el ESP32, y su módulo LEDC podremos generar los pulsos necesarios a la frecuencia requerida para mover nuestros motores. Para esta función será irrelevante la RESOLUCION y el DUTY CYCLE, aunque estableceremos como constantes:

int dutyCycle = 127;

const int resolution = 8;

Así obtendremos una señal de onda cuadrada perfecta.

MONITORIZACIÓN EN PANTALLA TFT

tft.begin(); // inicializa pantalla
tft.setRotation(3); // establece posicion horizontal con pines IZQUIERDA
tft.fillScreen(TFT_BLACK);// Utilizaremos esta llamada para refrescar la pantalla-

Para identificar los motores y dado que el módulo de los drivers dispone de tres leds -verde.rojo y amarillo, se configura la impresión para representar la frecuencia y la velocidad del motor de cada color .

UTILIZACION DEL ADC COMO DIAL DE FRECUENCIAS:

Si conecto tres potenciometros a las entradas ADC 39,36 y 34 y conociendo su resolución de 8 bits, resulta que podré utilizar hasta 4095 valores numéricos como variables de Freq que utilizaré para decirle a las salidas PWM elegidas la freq que quiero me generen.

int freqgreen = (2.6 * analogRead(36));
int freqred = (2.6 * analogRead(39));
int freqyellow = (2.6 * analogRead (34));

El factor de multiplicacion 2.6 lo utilizaré para generar de 0 a mas de 10000 Hz en el caso de necesitar que los motores giren a su máxima velocidad pero tambien podré reducir el márgen todo lo que quiera así:

int freqgreen = ( analogRead(36) / n);

siendo n un numero divisor calculado para trabajar con frecuencias bajas y poder obter un mejor control dela velocidad a bajas revoluciones

CONTROL DE PARO Y SENTIDO DE GIRO DE LOS MOTORES:

 if (freqgreen >= 10) {
    digitalWrite(4, LOW);
    ledcSetup(ledChannelgreen, freqgreen, resolution);
    ledcWrite(ledChannelgreen, dutyCycle);
    delay(100);
  }
  else {
    digitalWrite(4, HIGH);
  }

  if (freqred >= 10) {
    digitalWrite(16, LOW);
    ledcSetup(ledChannelred, freqred, resolution);
    ledcWrite(ledChannelred, dutyCycle);
    delay(100);
  }
  else {
    digitalWrite(16, HIGH);
  }

  if (freqyellow >= 300) {
    digitalWrite(19, LOW);
    ledcSetup(ledChannelyellow, freqyellow, resolution);
    ledcWrite(ledChannelyellow, dutyCycle);
    delay(100);
  }
  else {
    digitalWrite(19, HIGH);
  }

Para activar y desactivar los motores utilizaremos las salidas de los pines 4,16 y 19 que pasaran a LOW cuando la freq sea nferior a 10 para los motrores conectados a “green” y “red” y menor que 300para “yellow”.

Para invertir el sentido de giro se utilizan pulsadores con retención que enviaran un LOW a cada linea DIR al ser pulsados y un HIGH sin pulsar, ya que estan “en pull up”.

SKETCH COMPLETO


#include "SPI.h"
#include "TFT_eSPI.h"
#define TFT_GREY 0x7BEF
TFT_eSPI tft = TFT_eSPI();

const int ledPingreen = 0;
const int ledPinred = 15;
const int ledPinyellow = 17;
int dutyCycle = 127;
// setting PWM properties
const int ledChannelgreen = 0;
const int ledChannelred = 10;
const int ledChannelyellow = 15;
const int resolution = 8;

void setup() {
  tft.begin();        // inicializa pantalla
  tft.setRotation(3);     // establece posicion horizontal con pines derecha
  tft.fillScreen(TFT_BLACK);
  pinMode(4, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(19, OUTPUT);
  digitalWrite(4, HIGH);
  digitalWrite(16, HIGH);
  digitalWrite(19, HIGH);
  ledcAttachPin(ledPingreen, ledChannelgreen);
  ledcAttachPin(ledPinred, ledChannelred);
  ledcAttachPin(ledPinyellow, ledChannelyellow);
}
void loop() {
  int freqgreen = (2.6 * analogRead(36));
  int freqred = (2.6 * analogRead(39));
  int freqyellow = (2.6 * analogRead (34));
  float rpmgreen = (freqgreen / 53.3);
  float rpmred = (freqred / 53.3);
  float rpmyellow = (freqyellow / 546.13);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(ILI9341_GREEN);  // color de texto en VERDE
  tft.setTextSize(2);     // escala de texto en 2
  tft.setCursor(90, 10);
  tft.print("GREEN_MOTOR");
  tft.setCursor(10, 50);
  tft.print(freqgreen);
  tft.setCursor(90, 50);
  tft.print("Hz");
  tft.setCursor(165, 50);
  tft.print(rpmgreen);
  tft.setCursor(280, 50);
  tft.print("rpm");
  tft.drawLine(0, 80, 320, 80, TFT_WHITE);
  tft.drawLine(159, 30, 159, 80, TFT_WHITE);
  delay(10);

  tft.setTextColor(ILI9341_RED);  // color de texto en ROJO
  tft.setTextSize(2);     // escala de texto en 2
  tft.setCursor(90, 85);
  tft.print("RED_MOTOR");
  tft.setCursor(10, 130);
  tft.print(freqred);
  tft.setCursor(90, 130);
  tft.print("Hz");
  tft.setCursor(165, 130);
  tft.print(rpmred);
  tft.setCursor(280, 130);
  tft.print("rpm");
  tft.drawLine(0, 150, 320, 150, TFT_WHITE);
  tft.drawLine(159, 110, 159, 150, TFT_WHITE);
  delay(20);

  tft.setTextColor(ILI9341_YELLOW);  // color de texto en amarillo
  tft.setTextSize(2);     // escala de texto en 2
  tft.setCursor(90, 155);
  tft.print("YELLOW_MOTOR");
  tft.setCursor(10, 200);
  tft.print(freqyellow);
  tft.setCursor(90, 200);
  tft.print("Hz");
  tft.setCursor(165, 200);
  tft.print(rpmyellow);
  tft.setCursor(280, 200);
  tft.print("rpm");
  tft.drawLine(159, 180, 159, 235, TFT_WHITE);
  delay(500);

  if (freqgreen >= 10) {
    digitalWrite(4, LOW);
    ledcSetup(ledChannelgreen, freqgreen, resolution);
    ledcWrite(ledChannelgreen, dutyCycle);
    delay(100);
  }
  else {
    digitalWrite(4, HIGH);
  }

  if (freqred >= 10) {
    digitalWrite(16, LOW);
    ledcSetup(ledChannelred, freqred, resolution);
    ledcWrite(ledChannelred, dutyCycle);
    delay(100);
  }
  else {
    digitalWrite(16, HIGH);
  }

  if (freqyellow >= 300) {
    digitalWrite(19, LOW);
    ledcSetup(ledChannelyellow, freqyellow, resolution);
    ledcWrite(ledChannelyellow, dutyCycle);
    delay(100);
  }
  else {
    digitalWrite(19, HIGH);
  }

 }

RESUMEN:

Con este pequeño proyecto se han puesto en práctica el uso de una pantalla tft para monitorizar las lecturas digitales de tres entradas analógicas que se utilizaran como valores variables de frecuencia que entregamos al modulo LEDC que generaran pulsos enviados a los drivers TMC2209

int freqgreen = (2.6 * analogRead(36));

ledcSetup(ledChannelred, freqred, resolution);
    ledcWrite(ledChannelred, dutyCycle);

Deja una respuesta

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

Translate »