Proyecto 10.3 - MC3479 Stepper Motor Driver. Part 2

14 de agosto de 2016

Segunda parte del tutorial sobre el driver MC3479P. En el tutorial anterior vimos como conectar un motor paso a paso y programamos un sencillo sketch para comprobar su funcionamiento.

La interfaz con Arduino consta de dos señales de control, STEP y DIR, lo que significa que se podrían controlar hasta siete motores con un solo Arduino, o diez si usamos también los pines analógicos como salidas.

En el siguiente tutorial vamos a ver como controlar cinco motores paso a paso. Lo siento, solo dispongo de cinco drivers y cinco steppers :-) 

En los ejemplos anteriores, la función ENABLE/DISABLE se controlaba con Arduino, mediante el transistor 2N2222 y la resistencia RB de 100K conectada en el pin nº 6 BIAS/SET.

En el caso de que quisiéramos controlar diez motores, necesitaríamos un driver más por cada motor y añadir la función correspondiente en el sketch. Al no disponer de salidas libres para la señal ENABLE, tendríamos que llevar a masa a través de RB, el pin nº6 BIAS/SET de cada uno de los drivers. Ver la imagen siguiente.

Esquema

Como veis en el esquema, he utilizado tres motores distintos, de ahí que cada uno se conecte de manera diferente.

En realidad los motores son iguales, del tipo unipolar, sólo que cada fabricante emplea colores distintos en el cableado. 

Dadas las características de las bobinas, también se pueden conectar como motores bipolares (así están en el esquema) usando dos de las bobinas, en lugar de cuatro.

Para saber más sobre motores paso a paso, en la página de Adafruit hay un PDF de recomendable lectura, titulado: All about stepper motors.

Volvamos al esquema. La resistencia R8 es del tipo pull-up. La señal ENABLE es común para los cinco drivers, y se controla a través del transistor 2N2222 conectado en el pin D9 del Arduino.

Las resistencias RB colocadas en los pines nº 6 de cada driver, son para limitar la corriente que circula por las bobinas de los motores. 

En el tutorial 10.2 explico como calcular su valor.

La velocidad de giro se ajusta mediante el potenciómetro P1. También se puede prescindir de él y asignar el valor de la velocidad a una variable. 

Las resistencias conectadas en los pines 7 y 10 son del tipo pull-down.

Todos los motores funcionan a 12V, por lo que aprovechamos esos 12V para alimentar el Arduino a través del pin VIN.

Con los 5V que proporciona el regulador del Arduino, llevamos a nivel alto la señal FULL/HALF STEP.

Sketch

El sketch es similar al del tutorial 10.2. Tan solo hay que añadir una función por cada motor que queramos controlar.

/* 

  MC3479 Stepper Motor Diver

  Running Five Steppers one-by-one

    

  Based on the original sketch by Lewis Loflin

  http://www.bristolwatch.com/arduino/arduino5.htm

  

  Modified by Angel M.

  https://sites.google.com/site/angmuz/

  

*/

//  Outputs

#define Stepper1_clk 10 // connect to Driver 1 pin 7 STEP

#define Stepper1_dir 11 // connect to Driver 1 pin 10 DIR

#define Stepper2_clk 8  // connect to Driver 4 pin 7 STEP

#define Stepper2_dir 7  // connect to Driver 4 pin 10 DIR

#define Stepper3_clk 12 // connect to Driver 2 pin 7 STEP

#define Stepper3_dir 13 // connect to Driver 2 pin 10 DIR

#define Stepper4_clk 6  // connect to Driver 5 pin 7 STEP

#define Stepper4_dir 5  // connect to Driver 5 pin 10 DIR

#define Stepper5_clk 4  // connect to Driver 3 pin 7 STEP

#define Stepper5_dir 3  // connect to Driver 3 pin 10 DIR

#define Steppers_enable 9

int stepperSpeed = 4; // 0 = max speed; 1023 = min speed

int temp;

void   setup() {

     pinMode(Stepper1_clk, OUTPUT);

     pinMode(Stepper1_dir, OUTPUT);

     pinMode(Stepper2_clk, OUTPUT);

     pinMode(Stepper2_dir, OUTPUT);

     pinMode(Stepper3_clk, OUTPUT);

     pinMode(Stepper3_dir, OUTPUT);

     pinMode(Stepper4_clk, OUTPUT);

     pinMode(Stepper4_dir, OUTPUT);

     pinMode(Stepper5_clk, OUTPUT);

     pinMode(Stepper5_dir, OUTPUT);

     pinMode(Steppers_enable, OUTPUT);

     

     digitalWrite(Stepper1_clk, LOW);

     digitalWrite(Stepper1_dir, LOW);

     digitalWrite(Stepper2_clk, LOW);

     digitalWrite(Stepper2_dir, LOW);

     digitalWrite(Stepper3_clk, LOW);

     digitalWrite(Stepper3_dir, LOW);

     digitalWrite(Stepper4_clk, LOW);

     digitalWrite(Stepper4_dir, LOW);

     digitalWrite(Stepper5_clk, LOW);

     digitalWrite(Stepper5_dir, LOW);

     digitalWrite(Steppers_enable, HIGH); // Motors Enable

     

   }

   

   void loop()   {

     

     

     temp = stepperSpeed / 2; 

     toggle(Stepper1_clk);

     toggle(Stepper2_clk);

     toggle(Stepper3_clk);

     toggle(Stepper4_clk);

     toggle(Stepper5_clk);

     delay(3);

     toggle(Stepper1_clk);

     toggle(Stepper2_clk);

     toggle(Stepper3_clk);

     toggle(Stepper4_clk);

     toggle(Stepper5_clk);

     delay(temp);

     

    // Stepper1 

      digitalWrite(Stepper1_dir, HIGH); // CWW

      stepsStepper1(96);

      delay(200);

      digitalWrite(Stepper1_dir, LOW); // CW

      stepsStepper1(96);                

    

    // Stepper2

    

      digitalWrite(Stepper2_dir, HIGH); // CWW

      stepsStepper2(96);

      delay(200);

      digitalWrite(Stepper2_dir, LOW); // CW

      stepsStepper2(96);        

      

    // Stepper3

      digitalWrite(Stepper3_dir, HIGH); // CWW

      stepsStepper3(96);

      delay(200);

      digitalWrite(Stepper3_dir, LOW); // CW

      stepsStepper3(96);            

    

    // Stepper4

    

      digitalWrite(Stepper4_dir, HIGH); // CWW

      stepsStepper4(96);

      delay(200);

      digitalWrite(Stepper4_dir, LOW); // CW

      stepsStepper4(96);   

   

    // Stepper5

    

      digitalWrite(Stepper5_dir, HIGH); // CWW

      stepsStepper5(96);

      delay(200);

      digitalWrite(Stepper5_dir, LOW); // CW

      stepsStepper5(96);    

}

  

  

// Stepper1 

  void stepsStepper1(int j) {

    for(int i=0; i<j; i++)  {

      digitalWrite(Stepper1_clk,1);

      delay(3);

      digitalWrite(Stepper1_clk,0);

      delay(stepperSpeed / 2);

    }  // end for

    

  }  // end steps

  

// Stepper2 

  void stepsStepper2(int j) {

    for(int i=0; i<j; i++)  {

      digitalWrite(Stepper2_clk,1);

      delay(3);

      digitalWrite(Stepper2_clk,0);

      delay(stepperSpeed / 2);

    }  // end for

       

  } // end steps 

// Stepper3 

  void stepsStepper3(int j) {

    for(int i=0; i<j; i++)  {

      digitalWrite(Stepper3_clk,1);

      delay(3);

      digitalWrite(Stepper3_clk,0);

      delay(stepperSpeed / 2);

    }  // end for

        

  }  // end steps

// Stepper4

  void stepsStepper4(int j) {

    for(int i=0; i<j; i++)  {

      digitalWrite(Stepper4_clk,1);

      delay(3);

      digitalWrite(Stepper4_clk,0);

      delay(stepperSpeed / 2);

    }  // end for

       

  } // end steps 

 

 // Stepper5

  void stepsStepper5(int j) {

    for(int i=0; i<j; i++)  {

      digitalWrite(Stepper5_clk,1);

      delay(3);

      digitalWrite(Stepper5_clk,0);

      delay(stepperSpeed / 2);

    }  // end for

       

  } // end steps  

    

 void toggle(int pinNum) {  

  int pinState = digitalRead(pinNum);

  pinState = !pinState;

  digitalWrite(pinNum, pinState); 

}


Part 3. Control three steppers using analog pins

 Para terminar el tutorial vamos a ver como controlar tres motores paso a paso usando los pines analógicos.

Las entradas analógicas del Arduino también se pueden usar como E/S digitales. Tan sólo hay que configurarlas como tales en el sketch. La entrada A0 sería en pin 14; A1, el 15; y así sucesivamente hasta A5 el 19.

Esquema

El esquema es similar al anterior y no presenta ninguna dificultad. Los drivers se conectan igual, solo que ahora las señales STEP y DIR se llevan a los pines analógicos del Arduino.

He prescindido del potenciómetro. Ahora la velocidad de giro se selecciona mediante la variable stepperSpeed en el sketch.

Sketch

/* 

  MC3479 Stepper Motor Diver

  Driving Three Steppers with Analog Inputs

    

  Based on the original sketch by Lewis Loflin

  http://www.bristolwatch.com/arduino/arduino5.htm

  

  Modified by Angel M.

  https://sites.google.com/site/angmuz/

  

*/

//  Outputs

#define Stepper1_clk 15 // connect to Driver 3 pin 7 STEP

#define Stepper1_dir 14 // connect to Driver 3 pin 10 DIR

#define Stepper2_clk 17 // connect to Driver 2 pin 7 STEP

#define Stepper2_dir 16 // connect to Driver 2 pin 10 DIR

#define Stepper3_clk 19 // connect to Driver 1 pin 7 STEP

#define Stepper3_dir 18 // connect to Driver 1 pin 10 DIR

#define Steppers_enable 3

int stepperSpeed = 4; // 0 = max speed; 1023 = min speed

int temp;

void   setup() {

     pinMode(Stepper1_clk, OUTPUT);

     pinMode(Stepper1_dir, OUTPUT);

     pinMode(Stepper2_clk, OUTPUT);

     pinMode(Stepper2_dir, OUTPUT);

     pinMode(Stepper3_clk, OUTPUT);

     pinMode(Stepper3_dir, OUTPUT);

     pinMode(Steppers_enable, OUTPUT);

     

     digitalWrite(Stepper1_clk, LOW);

     digitalWrite(Stepper1_dir, LOW);

     digitalWrite(Stepper2_clk, LOW);

     digitalWrite(Stepper2_dir, LOW);

     digitalWrite(Stepper3_clk, LOW);

     digitalWrite(Stepper3_dir, LOW);

     digitalWrite(Steppers_enable, HIGH); // Motors Enable

     

   }

   

   void loop()   {

     

     

     temp = stepperSpeed / 2; 

     toggle(Stepper1_clk);

     toggle(Stepper2_clk);

     toggle(Stepper3_clk);

     delay(3);

     toggle(Stepper1_clk);

     toggle(Stepper2_clk);

     toggle(Stepper3_clk);

     delay(temp);

     

    // Stepper1 

      digitalWrite(Stepper1_dir, HIGH); // CWW

      stepsStepper1(96);

      delay(200);

      digitalWrite(Stepper1_dir, LOW); // CW

      stepsStepper1(96);                

    

    // Stepper2

    

      digitalWrite(Stepper2_dir, HIGH); // CWW

      stepsStepper2(96);

      delay(200);

      digitalWrite(Stepper2_dir, LOW); // CW

      stepsStepper2(96);        

      

    // Stepper3

      digitalWrite(Stepper3_dir, HIGH); // CWW

      stepsStepper3(96);

      delay(200);

      digitalWrite(Stepper3_dir, LOW); // CW

      stepsStepper3(96);    

}

  

  

// Stepper1 

  void stepsStepper1(int j) {

    for(int i=0; i<j; i++)  {

      digitalWrite(Stepper1_clk,1);

      delay(3);

      digitalWrite(Stepper1_clk,0);

      delay(stepperSpeed / 2);

    }  // end for

    

  }  // end steps

  

// Stepper2 

  void stepsStepper2(int j) {

    for(int i=0; i<j; i++)  {

      digitalWrite(Stepper2_clk,1);

      delay(3);

      digitalWrite(Stepper2_clk,0);

      delay(stepperSpeed / 2);

    }  // end for

       

  } // end steps 

// Stepper3 

  void stepsStepper3(int j) {

    for(int i=0; i<j; i++)  {

      digitalWrite(Stepper3_clk,1);

      delay(3);

      digitalWrite(Stepper3_clk,0);

      delay(stepperSpeed / 2);

    }  // end for

        

  }  // end steps

void toggle(int pinNum) {  

  int pinState = digitalRead(pinNum);

  pinState = !pinState;

  digitalWrite(pinNum, pinState); 

}


Links

Arduino Interface MC3479 Stepper Motor Controller by Lewis Loflin. http://www.bristolwatch.com/arduino/arduino5.htm

Adafruit, All about stepper motors