This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
CONSULTA Controlar bucle con un final de carrera
#1
Hola a todos, me preguntaba si alguien sabe como poner una condición para posicionar un motor en un punto concreto sin que me interrumpa el bucle de rotación de dicho motor. Me explico:
Tengo un motor PAP con el controlador de pololu, con una rueda de colores con un imán y un sensor magnético (int finalCarrera = 8Guiño:
[Imagen: discomotor.jpg]
Lo que intento es:


1º - Girar el disco 360º hasta que el sensor se encuentre con el mán y a partir de ahí empezar la secuencia programada en el loop:
Código:
 for (int x = 0; x < numStepMotor; x++) {
   digitalWrite(pinStep, HIGH);
   delayMicroseconds(velocidad);
   digitalWrite(pinStep, LOW);
   delayMicroseconds(velocidad);

 }
2º - Una vez que encuentre el imán, que se ejecute sin parar el contenido de la función void loop() para que pueda ir cambiando de color uno por uno o en cualquier orden programado:
Código:
void loop() {
 estadofinal = digitalRead(finalCarrera); 

   if( estadofinal == HIGH)                    
 {
 
 digitalWrite(pinDir, HIGH);


 for (int x = 0; x < 25; x++) {
   digitalWrite(pinStep, HIGH);
   delayMicroseconds(velocidad);
   digitalWrite(pinStep, LOW);
   delayMicroseconds(velocidad);
 }
delay(1000);
}
}

Aquí os dejo el código completo por si alguien me puede ayudar:
Código:
const int pinDir = 2;
const int pinStep = 3;

const int numStepMotor = 400; //Es el número de pasos por rotación del motor (puede variar según el modelo)
const long velocidad = 4000; // Velocidad del motor

int finalCarrera = 8;
                         
int estadofinal = 0;

void setup() {

 pinMode(pinStep, OUTPUT);
 pinMode(pinDir, OUTPUT);
 pinMode(finalCarrera, INPUT);                


 digitalWrite(pinDir, HIGH);

 for (int x = 0; x < numStepMotor; x++) {
   digitalWrite(pinStep, HIGH);
   delayMicroseconds(velocidad);
   digitalWrite(pinStep, LOW);
   delayMicroseconds(velocidad);

 }
}
void loop() {
 estadofinal = digitalRead(finalCarrera);
 

   if( estadofinal == HIGH)                    
 {
 
 digitalWrite(pinDir, HIGH);


 for (int x = 0; x < 25; x++) {
   digitalWrite(pinStep, HIGH);
   delayMicroseconds(velocidad);
   digitalWrite(pinStep, LOW);
   delayMicroseconds(velocidad);
 }
delay(1000);
}
}
  Responder
#2
No entiendo lo que quieres hacer con el circulo, ni tampoco entiendo tu codigo... Que asi a simple vista segun leo lo que haces es en el setup dar una vuelta completa, no veo en el codigo nada que lo pare donde el iman...
Luego en el loop pones que si esta en el iman cosa que dudo, avance 25 pasos espere 1 segundo y repita.
Con lo cual si de chorra esta en el iman se va a mover 25 pasos y como luego ya no esta en el iman pararse y en caso de no estar pues ya no se va a mover nada.

Sin saber lo que quieres hacer bien con el circulo, lo que yo haria es primero girarlo despacio para que cuando detecte el iman pararlo y una vez que ya tienes la posicion 0 pues como es un motor paso a paso moverlo posiciones de pasos fijas para que te vaya a cada circulo como quieras. La puñeta es que has puesto 12 y 400/12 no da un numero entero con lo que tambien vas a tener problemas con eso porque a mas vueltas iras perdiendo la posicion y tendras que volver a buscar el cero.

Si explicas un poco mejor que quieres hacerlo con el circulo te podremos ayudar mejor
  Responder
#3
en la rutina setup cambia el => for (int x = 0; x < numStepMotor; x++)
por while (digitalRead(finalCarrera))
así lo mantienes en el bucle hasta que el final de carrera detecte
  Responder
#4
Gracias por vuestra ayuda, PauFerlo me ha dado una idea con la condición "while" y al fin lo he conseguido, como dice Triangulo, no tiene sentido poner el giro del disco dentro del setup, por eso he rectificado el código y lo he puesto de la siguiente manera:

Código:
const int pinDir = 2;
const int pinStep = 3;
const long velocidad = 4000; // Velocidad lenta
const long velocidad2 = 1000; // Velocidad rápida

int finalCarrera = 8;  // Sensor magnético                          
int estadofinal = 0;

void setup() {
 // Preparamos los pines de salida y el de entrada
 pinMode(pinStep, OUTPUT);
 pinMode(pinDir, OUTPUT);
 pinMode(finalCarrera, INPUT);
}
void loop() {
   digitalWrite(pinDir, HIGH);
 for (int x = 0; x < 1; x++) {
   digitalWrite(pinStep, HIGH);
   delayMicroseconds(velocidad);
   digitalWrite(pinStep, LOW);
   delayMicroseconds(velocidad);
 }
 
 estadofinal = digitalRead(finalCarrera);

   while( estadofinal == HIGH)
 {
 delay(2000);
 digitalWrite(pinDir, HIGH);
 for (int x = 0; x < 200; x++) {
   digitalWrite(pinStep, HIGH);
   delayMicroseconds(velocidad);
   digitalWrite(pinStep, LOW);
   delayMicroseconds(velocidad);
 }
delay(1000);

}
}

Saludos y gracias  Clap
  Responder
#5
A pesar de no poner para que es el chisme, (Tengo curiosidad Lengua) viendo el codigo no se si lo escribes y lo pruebas o solo lo escribes porque hay cosas algo incongruentes.

La primera que veo rara es que arriba ponias que una vuelta eran 400 pasos y ahora abajo pones 200. Como no tengo ni idea de los conocimientos que tienes ni de electronica ni de programacion de arduino yo voy a darle unas pinceladas, no se si te sobrara lo que diga o te vendra bien pero bueno Gran sonrisa

Lo primero tienes que tener claro cuantos pasos necesita el motor para dar una vuelta entera, este tipo de motores suelen ser de 1.8 grados por paso o algunos mas precisos de 0.9 . Eso lo ves en la referencia del motor que tengas y buscas por intenet la hoja de caracteristicas, si es de 1.8 pues 360 grados entre 1.8 da los 200 pasos y 360/0.9 pues 400. Eso es lo primero que aclares si una vuelta son 200 o 400.

Luego voy a comentar tu codigo del loop.



   digitalWrite(pinDir, HIGH);      Aqui estableces la direccion


 for (int x = 0; x < 1; x++) {         Aqui avanzas el motor 1 paso para que haces esto?¿? no le veo sentido
   digitalWrite(pinStep, HIGH);
   delayMicroseconds(velocidad);
   digitalWrite(pinStep, LOW);
   delayMicroseconds(velocidad);
 }
 
 estadofinal = digitalRead(finalCarrera);    Lees la señal del detector 

   while( estadofinal == HIGH)         Empiezas un bucle que se ejecuta mientras el detector este en alto
 {                                                          Convendria aclarar si cuando detecta esta en alto o en bajo.
 delay(2000);                                       [b]Esperas dos segundos[/b]
 digitalWrite(pinDir, HIGH);              [b]Aqui estableces la direccion[/b]
 for (int x = 0; x < 200; x++) {          Esto que es¿¿ estas metiendo un bucle dentro de otro 
   digitalWrite(pinStep, HIGH);           
   delayMicroseconds(velocidad);
   digitalWrite(pinStep, LOW);
   delayMicroseconds(velocidad);
 }
delay(1000);

}

Código:
const int pinDir = 2;
[/b]
const int pinStep = 3;
const long velocidad = 4000; // Velocidad lenta
const long velocidad2 = 1000; // Velocidad rápida

int finalCarrera = 8;  // Sensor magnético                          
int estadofinal = 0;
int posicionZero=0;

void setup() {
// Preparamos los pines de salida y el de entrada
pinMode(pinStep, OUTPUT);
pinMode(pinDir, OUTPUT);
pinMode(finalCarrera, INPUT);
}
void loop() {


if (posicionZero== 0) {
estadofinal = digitalRead(finalCarrera);
  while( estadofinal == HIGH)
{
digitalWrite(pinDir, HIGH);
for (int x = 0; x < 200; x++) {   //Suponiendo que el motor es de 200 pasos por vuelta
  digitalWrite(pinStep, HIGH);
  delayMicroseconds(velocidad);
  digitalWrite(pinStep, LOW);
  delayMicroseconds(velocidad);
}
posicionZero=1;
}

MoverYPasos(16);

delay(2000);

}
}

void MoverYPasos(Y int)
{
digitalWrite(pinDir, HIGH);
for (int x = 0; x < Y; x++) {   //Suponiendo que el motor es de 200 pasos por vuelta
  digitalWrite(pinStep, HIGH);
  delayMicroseconds(velocidad2);
  digitalWrite(pinStep, LOW);
  delayMicroseconds(velocidad2);
[b]}



Este codigo de ejemplo lo que haria seria buscar la posicion 0 y apartir de ahi cada dos segundos girar y correr los circulos, pero al poco como te dije en el primer comentario se va a desincronizar porque tienes 12 circulos para 200 pasos, para girar perfecto serian 16,66666 por eso que lo suyo hubiera haber sido poner 10 o algo que al dividir por los pasos diera entero, si fueran 10 cada circulo seria 20 pasos justo y nunca se desincronizaria. bueno siento la parrafada Gran sonrisa
  Responder
#6
Lo que te comenta Triangulo de los bucles es cierto. Lo que yo te quería decir no es anidar el bucle for dentro del bucle while, sino hacer solamente el bucle while.
algo así:

digitalWrite(pinDir, HIGH);
while(digitalread(FinalCarrera))
{
digitalWrite(pinStep, HIGH);
delayMicroseconds(velocidad);
digitalWrite(pinStep, LOW);
delayMicroseconds(velocidad);
}
Y para mi si tiene sentido poner este código únicamente en la rutina Setup, así cada vez que enciendes el Arduino lo primero que hace es situarse en el imán, y a partir de ahí será la rutina loop la que controla donde hay que posicionar. Sería como hacer un home cada vez que enciendes.

Lo que no veo correcto en el código de triangulo es meter el for dentro del while, ya que de esa forma te hará, sí o sí 200 pulsos antes de salir del for, y si inicias supongamos a 50 pulsos del imán se pasará 150 pulsos del imán.

Tampoco creo correcto leer el estado del final de carrera antes del bucle while y almacenarlo en una variable, porque de esa forma el valor de la variable ya no vuelve a cambiar aunque el estado del final de carrera cambie una vez que estás en el bucle.
Evidentemente la línea :
while(digitalread(FinalCarrera))
será:
while(!digitalread(FinalCarrera))
en caso de que el final de carrera de señal uno si no detecta
Saludos

PD: Me ha quedado un poco largo, perdón
  Responder
#7
Pauferlo si correcto tus aclaraciones, lo del bucle dentro del while es lo que le digo que no esta bien en su codigo e hice un copy paste de ese trozo y ya meti todo pa dentro xdd.
Tampoco puse que no estaba bien en el setup lo de buscar el cero sino que no veia donde ponia que parara con el iman pero como el lo cambio al loop por dejar el codigo lo mas parecido al suyo.

De todos modos le pregunto si solo lo escribe o lo prueba tambien porque a mi me pasa que a veces lo escribo y lo voy probando cuando tengo bastante hecho y ves que has puesto cosas mal.
  Responder
#8
Hola de nuevo, ante todo, no estoy muy ducho con la programación de arduino, siento curiosidad e intento aprender con los videotutoriales de Bitwise Ar: (https://www.youtube.com/channel/UC4unPLt...MB3IvaQZaA)  por eso he recurrido a vosotros. El código lo he escrito y lo he probado, va perfectamente. El motor es de 1.8 pero lo tengo a 1/2 paso, (para más resolución) por lo que para dar una vuelta, necesitaría 400 pulsos. Con respecto a avanzar el motor paso por paso...

 for (int x = 0; x < 1; x++) { 

...es porque comprobé que si lo programaba para 360º, si se cruzaba con el detector magnético, hasta que no terminara de girar la vuelta entera, no me pasaría al bucle y lo que yo quería es hacerlo ipso facto, coincidir imán con detector magnético y pasar al bucle:

  digitalWrite(pinDir, HIGH);
  for (int x = 0; x < 200; x++) {
    digitalWrite(pinStep, HIGH);
    delayMicroseconds(velocidad);
    digitalWrite(pinStep, LOW);
    delayMicroseconds(velocidad);
  }


ah, Triangulo, he probado tu código y me da este error: variable or field 'MoverYPasos' declared void
  Responder
#9
Hola te da error al compilar porque en la funcion, donde pone la variable Y esta mal definida primero se pone el tipo que es y luego el nombre, es lo que pasa al escribir sin ni siquiera compilar Gran sonrisa.

Te voy a pasar un codigo que al menos lo compile, asi que errores de compilacion no tendra y en teoria si no pase algo por alto deberia funcionar...

Código:
const int pinDir = 2;

const int pinStep = 3;
const long velocidad = 4000; // Velocidad lenta
const long velocidad2 = 1000; // Velocidad rápida

int finalCarrera = 8;  // Sensor magnético                          
int estadofinal = 0;
int pasosAmover=0;
int ContadorpasosAmover=0;

void setup() {
// Preparamos los pines de salida y el de entrada
   pinMode(pinStep, OUTPUT);
   pinMode(pinDir, OUTPUT);
   pinMode(finalCarrera, INPUT);

digitalWrite(pinDir, HIGH);
while(digitalRead(finalCarrera))
{
digitalWrite(pinStep, HIGH);
delayMicroseconds(velocidad);
digitalWrite(pinStep, LOW);
delayMicroseconds(velocidad);
}
}


void loop() {

//400 pasos dijiste que habia con los micropasos
if (ContadorpasosAmover>=363){
 ContadorpasosAmover=ContadorpasosAmover+33;
 pasosAmover=33;
}
else
{
 pasosAmover=37;
 ContadorpasosAmover=0;
 }

   MoverYPasos(pasosAmover);
   delay(2000);

 
}


 
void MoverYPasos(int Y)
{
   digitalWrite(pinDir, HIGH);
   for (int x = 0; x < Y; x++) {  
       digitalWrite(pinStep, HIGH);
       delayMicroseconds(velocidad2);
       digitalWrite(pinStep, LOW);
       delayMicroseconds(velocidad2);
   }
}

Prueba a ver que te hace y nos dices.
  Responder
#10
Gracias por tu código Triangulo, lo he probado y no me da error pero, no reacciona ante el interruptor magnético y además me avanza de 33 en 33 pulsos y no es lo que necesito, gracias de todos modos.

El código que estoy utilizando me va de muerte, además una vez que empieza el bucle por debajo de la condición "while", si el imán vuelve a encontrarse con el sensor magnético, este no reacciona, sigue con el bucle indefinidamente hasta que lo resetee, que es lo que yo quiero.

Después de este ejercicio quiero hacer un encoder óptico con un optointerruptor, si no he entendido mal, parecido a lo anterior pero más sofisticado.

Saludos!  Clap
  Responder
#11
Bueno yo no se lo que quieres hacer jeje no lo has explicado, el codigo que puse gira indedinidamente girando esos circulos y si, solo reaciona al iman al encenderlo para posicionarse. Pero bueno es un ejemplo sin mas. Si ya te hace lo que quieres perfecto.
  Responder


Posibles temas similares…
Tema Autor Respuestas Vistas Último mensaje
  CONSULTA Switch final de carrera no controla parada Sr. Kowi 3 1,688 14-02-2020, 09:51 PM
Último mensaje: Lepes
  Controlar dos o tres cartuchos calefactores Shikva 1 1,338 23-09-2019, 07:23 AM
Último mensaje: bertonic
  CONTROLAR CUATRO TIRAS LED WS2812B CON ARDUINO NAVIDADES MAFALDA74 10 6,257 28-03-2019, 08:44 AM
Último mensaje: shiryou
  DUDA Finales de carrera Vicente48 1 1,188 17-09-2018, 06:44 PM
Último mensaje: Nullz
  CONSULTA Controlar 3000 leds, ¿cual es la mejor opcion? the_feti 2 1,434 13-08-2018, 10:00 PM
Último mensaje: the_feti