Dudas sobre motores paso a paso

Hola a todos y todas…

He empezado a curiosear sobre el uso de motores PAP y me he encontrado con un inconveniente.

Tengo un motor Sanyo, unipolar, 1,8º 200 pasos (ver adjunto: 103-770-6) y estoy utilizando un driver unipolar(ver adjunto): http://esteca55.com.ar/proye-dvu4a.html

Mi problema es que no logro que el motor sincronice bien, cada vuelta completa termina en una posición diferente. No se si es por la programación o por el driver.

El scketch es el siguiente:

#define PA 12
#define DIR 8
#define EN 10

void setup(){

 pinMode(PA,OUTPUT); 
 pinMode(DIR,OUTPUT);
 pinMode(EN, OUTPUT);
}
void loop(){
 
 digitalWrite(EN,LOW);
 digitalWrite(EN,HIGH);
 digitalWrite(DIR,HIGH); 
 
 for(int i=0;i<200;i++){ 
   digitalWrite(PA,HIGH);
   delay(1);
   digitalWrite(PA,LOW);
   delay(1);

 delay(2000); 
 }
}

también modifique este ejemplo pero sucede lo mismo:

#define VELOCIDAD 1700


int PA = 13;
int DIR = 9;
int EN = 10;
int pasos = 200;

void setup() {                
 pinMode(PA, OUTPUT); 
 pinMode(DIR, OUTPUT); 
 pinMode(EN, OUTPUT);
}

void loop(){
 
 digitalWrite(EN, LOW);    
 digitalWrite(EN, HIGH);  
 digitalWrite(DIR, HIGH);

 for (int i = 0; i<pasos; i++){       
   digitalWrite(PA, HIGH);  
   digitalWrite(PA, LOW);  
   delayMicroseconds(VELOCIDAD);     
   delay(2000);
 } 
}

Gracias y cualquier aporte u orientación se agradece…

Motores-sanyo.pdf (784 KB)

DVU6A80V.pdf (196 KB)

En el manual del driver pone que hay un jumper ,jp1 ,para regular medios pasos y que por defecto viene configurado asi ,por lo que para dar una vuelta completa requiere 400 impulsos,o 200 quitando ese jumper.con medios pasos se gana en suavidad de funcionamiento y precision.

jose: En el manual del driver pone que hay un jumper ,jp1 ,para regular medios pasos y que por defecto viene configurado asi ,por lo que para dar una vuelta completa requiere 400 impulsos,o 200 quitando ese jumper.con medios pasos se gana en suavidad de funcionamiento y precision.

Si José, es verdad, lo probé con 1/2 paso y tampoco sincroniza bien. Vos no sabrías si el problema puede estar en el shield? viste el código? hay alguna otra forma de controlar la velocidad del motor, a parte de delay o delayMicroseconds?

Gracias

Esto no controla ninguna velocidad

   delayMicroseconds(VELOCIDAD);     
   delay(2000);

O usas algo que controle VELOCIDAD usandola como variable o no le agregas una constante de 2000msegundos

Veamos… supongamo que dices velocidad 50 y son useg
Le sumas 2000 mseg
que te queda

2000.50 en total… que controlas con eso
Cuando le das 49 de velocidad te queda
2000.49

Asi que o usas delayMicroseconds(VELOCIDAD); solamente
O usas delay(VELOCIDAD); solamente
Luego si cada paso de tu stepper demora 2 segundos según esto

 for (int i = 0; i<pasos; i++){       
   digitalWrite(PA, HIGH);  
   digitalWrite(PA, LOW);  
   delayMicroseconds(VELOCIDAD);     
   delay(2000);  // estos 2 segundos de demora quitarlos ponerlos fuera del loop
 }

Comienza por ahi.

Te recomiendo que le eches un vistazo a la libreria accelstepper ,permite aceleraciones/deceleraciones,varios motores funcionando simultaneamente ,etc etc: http://www.airspayce.com/mikem/arduino/AccelStepper/

Gracias José, es verdad lo que decís, entendí eso. Voy a hacer las correcciones y comento que pasó. Revisare esa librería.

Buenas! Apliqué las sugerencias de José y anduvieron los dos ejemplos muy bien. El que estoy utilizando ahora quedó así:

int PA = 10;
int DIR = 12;
int EN = 8;
int pasos = 200; //sin jumper de 1/2 paso en jp1
int VELOCIDAD=1500

void setup() {                
  pinMode(PA, OUTPUT); 
  pinMode(DIR, OUTPUT); 
  pinMode(EN, OUTPUT);
}

void loop(){
  
  digitalWrite(EN, HIGH);
  digitalWrite(EN, LOW);
  digitalWrite(DIR, HIGH);

  for(int i=0;i<pasos;i++){
    digitalWrite(PA, HIGH); 
    digitalWrite(PA, LOW);      
    delayMicroseconds(VELOCIDAD);     
   
  } 
    delay(2000);
}

Funciona muy bien, pero cuando hace los 200 paso nunca queda en la misma posición. Alguien sabe a que puede deberse este problema? hace falta agregar un freno entre vuelta y vuelta?
Este código lo utilizo para mover un motor de un árbol de bombas inyectoras que dosifican 7microlitros. En la prueba que hice hoy funcionó muy bien, pero cada vez que se desplaza esos grados de más, queda una pequeña gota en el inyector lo que modifica el volumen siguiente.

Gracias por los aportes!

y donde usas la librería de josé?

xseqs: Gracias José, es verdad lo que decís, entendí eso. Voy a hacer las correcciones y comento que pasó. Revisare esa librería.

Al cesar lo que es del cesar ,yo solo te recomende la libreria accelstepper porque pedias otras maneras de controlar la velocidad y esa libreria te ahorra bastante trabajo,la modificacion del codigo es de surbyte....

Es verdad, pido disculpas. Gracias Surbyte por la sugerencia (funcionó muy bien). No utilice aun la librería que recomendó José. Lo que necesito ahora es saber porque el motor no para justo a los 360º. es un problema del código o del driver? Es necesario que frene el giro? como lo hago? Cómo siempre gracias

xseqs: Es verdad, pido disculpas. Gracias Surbyte por la sugerencia (funcionó muy bien). No utilice aun la librería que recomendó José. Lo que necesito ahora es saber porque el motor no para justo a los 360º. es un problema del código o del driver? Es necesario que frene el giro? como lo hago? Cómo siempre gracias

me da que estas perdiendo pasos por la velocidad,ten en cuenta que 1 microsegundo es la millonesima parte de un segundo, 1000000/1500= 666.66 pulsos por segundo ,que me parece algo elevado .prueba con delays mas altos ,no se las rpm maximas de tu motor ,pero por ejemplo para 60rpm ,que es una vuelta por segundo ,necesitarias 200 pulsos por segundo :1000 milisegundos / 200 = 5.prueba a cambiar:

delayMicroseconds(VELOCIDAD);

por:

delay(5);

a ver que pasa.

Prueba con la librería de josé y si no funciona hablamos. A ver... no es capricho. No es la librería de José.. sino que el la recomenda y es por experiencia. Tu escribes algo.. que no está probado y tienes una falla, porque seguir en la falla cuando hay algo que esta probado? Si usando una libreía tienes una falla de posicionamiento entonces te pones a analizar todo.

Me comprendes?

Buenas a todos…
Otra vez de regreso. Este fin de semana retome el proyecto y estube trabajando en dos cuestiones:
Por un lado segui intentando mejorar lo que venia haciendo con el Stepper Sanyo Unipolar, y el driver DVU6A80V. Con esta parte quede así:

int PA = 11;
int DIR = 8;
int EN = 10;
int pasos = 200;
int VELOCIDAD = 1100;

void setup() {                
  pinMode(PA, OUTPUT); 
  pinMode(DIR, OUTPUT); 
  pinMode(EN, OUTPUT);
}

void loop(){
  
  digitalWrite(EN, HIGH);
  digitalWrite(EN, LOW);
  digitalWrite(DIR, HIGH);

  for (int i = 0; i<pasos; i++){
    digitalWrite(PA, HIGH);  
    digitalWrite(PA, LOW);  
    delayMicroseconds(VELOCIDAD);     
    
  } 
    delay(2000);
}

Este código funciona bien para lo que quiero, aunque me hubiera gustado tener más flexibilidad a la hora de modificar las velocidades.

Con AccelStepper estube haciendo algo pero sin resultados positivos:

#include <AccelStepper.h>

AccelStepper stepper(3, 8, 10, 12);

void setup()
{  
   stepper.setMaxSpeed(2000);
   stepper.setSpeed(2000);  	
}

void loop(){
  
   stepper.runSpeed();
}

La velocidad que alcanso es bastante considerable pero no me doy cuenta como hacer para que realice la misma rutina que con el otro code: una vuelta completa y parar 1second.

Hoy estube tratando de jugar con algunas cositas pero con el code anterior, es decir, sin la librería AccelStepper:
Le agregue un Pot y dos botones. La idea es regular la variacion de velosidad col el Pot y detener y encender el stepper con los bot. Hice esto:

int PA = 11;//pin pasos
int DIR = 8;//pin dirección
int EN = 10;//pin entrada
int pot;//Potenciometro
int detener=3;//pin boton para detener el stepper
int iniciar=4;//pin boton para encender el stepper
int pasos=200;//pasos de mi stepper(1.8)
int estado;//lo agregue por si las moscas pero no se si cumple alguna función

void setup() {       

  pinMode(detener,INPUT);
  pinMode(iniciar,INPUT);
  pinMode(PA, OUTPUT); 
  pinMode(DIR, OUTPUT); 
  pinMode(EN, OUTPUT);
  
  digitalWrite(PA, LOW);//No se si esto es necesario, pero la idea es que el stepper se inicie parado
  digitalWrite(DIR, LOW);
  digitalWrite(EN, LOW);
  
}

void loop(){
  
  pot = analogRead(A0);                         //Esto funciona de maravilla(mitigue la frustración un poco)
  pot=map(pot, 0, 1023, 600, 1500);
  
  boolean estado=digitalRead(iniciar);//Leemos el estado del pulsador.De acá para abajo no funciona nada
  if(estado==HIGH)//Comparamos estado del pulsador. El boolean no use porque lo vi en algun ejemplo
  
  {
    //digitalWrite(EN, HIGH);
    //digitalWrite(EN, LOW);
    //digitalWrite(DIR, HIGH);
    for (int i = 0; i<pasos; i++)
    digitalWrite(PA, HIGH);  
    digitalWrite(PA, LOW);  
    delayMicroseconds(pot);    
  } 
  bolean estado=digitalRead(detener);//Leemos el estado del pulsador
  if(estado==HIGH)//Comparamos estado del pulsador
  {
    digitalWrite(PA, LOW);  
    digitalWrite(PA, LOW);
  }
 
}

Este lo utilice con algunas leves modificaciones y anda perfecto, pero no funcionan las velocidades:

/*
  www.diymakers.es
  by A.García
  Mover motores paso a paso con Arduino
  Tutorial en: http://diymakers.es/mover-motores-paso-paso-con-arduino/
*/
 
#include <Stepper.h> //Importamos la librería para controlar motores paso a paso
 
#define STEPS 200 //Ponemos el número de pasos que necesita para dar una vuelta. 200 en nuestro caso
 
// Ponemos nombre al motor, el número de pasos y los pins de control
Stepper stepper(STEPS, 8, 10, 9, 11); //Stepper nombre motor (número de pasos por vuelta, pins de control)
 
int pot;  //Variable lectura potenciómetro
int derecha=3;  //Pulsador derecha
int izquierda=4;  //Pulsador izquierda
int direccion;  //Variable para indicar la direccón
 
void setup()
{
  pinMode(derecha,INPUT);
  pinMode(izquierda,INPUT);
}
 
void loop()
{
  pot=analogRead(A0); //Lectura potenciómetro
  pot = map(pot, 0, 1023, 200, 300); //Establecemos la velocidad entre 30 y 150 rpm(?)
 
  stepper.setSpeed(pot); //Indicamos la velocidad al motor
 
  stepper.step(direccion); //Indicamos la dirección al motor
 
  if(digitalRead(izquierda)==HIGH)
  {
     direccion=200;  //Si pulsamos el pulsador izquierdo, el motor se enciende
  }

  
 
  if(digitalRead(derecha)==HIGH)
  {
     direccion=0;  //Si pulsamos el pulsador derecho, el motor se apaga
  }
}

Conclución: La versión sin la librería funcionaría perfecto si pudiera hacer funcionar los botones. Estaría bueno poder aprender como controlar los pasos y los intervalos en la versión con la AccelStepper. Por último, el sketch final sería el optimo si tan solo pudiera saber porque los interbalos de velocidades son tan pequeños(me refiero a que los balores del entorno van de 200 a 300 y funciona muy lento)