Proyecto 10.3 - MC3479 Stepper Motor Driver. Part 2
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