Usando una función dentro de una función

1

Hola, soy un principiante en el uso de motores paso a paso, y estoy aprendiendo a medida que avanzo.

Sin embargo, me preguntaba si habría una manera de retrasar los pasos entre cada paso en mi motor paso a paso sin usar la demora, porque entiendo que usar la demora pone todo el programa en espera. En el futuro, me gustaría poder que el usuario ingrese un número diferente de pasos para cada paso a paso. O bien, coloque la pata del pulgar de ps2 conectada para que los motores de pasos puedan moverse simultáneamente en los ejes x e y (ya que estoy haciendo un cnc), lo que resulta en una línea diagonal.

A pesar de la demora en que los steppers se ejecutan al mismo tiempo, vibran muy mal. Sin embargo, indivdualmente son suaves, por lo que sospecho que puede ser debido a la demora.

Entonces, ¿algún pensamiento? Aquí está el código.

     int IN1 = 5; 
     int IN2 = 4; 
     int IN3 = 3; 
     int IN4 = 2;  
     int IN1_1 = 9; 
     int IN2_1 = 8; 
     int IN3_1 = 7; 
     int IN4_1 = 6;  
     int delay_time= 5;  
     int count = 0; 
     int i = 1;
     void setup(){ 
     pinMode(IN1, OUTPUT); 
     pinMode(IN2, OUTPUT); 
     pinMode(IN3, OUTPUT); 
     pinMode(IN4,OUTPUT);   
     pinMode(IN1_1, OUTPUT); 
     pinMode(IN2_1, OUTPUT); 
     pinMode(IN3_1, OUTPUT); 
     pinMode(IN4_1,OUTPUT);
     Serial.begin(9600);
   } 
   void loop(){   
   int s = 200; 
   int x = 0; 
   //Function that rotates the first stepper motor
   step_one();
  // Fucntion that rotates the second stepper motor
   step_two();
   }


 //definition of these functions  
 void step_one(){
 digitalWrite(IN1, LOW); 
 digitalWrite(IN2, HIGH); 
 digitalWrite(IN3, HIGH); 
 digitalWrite(IN4, LOW); 
 delay(delay_time);
 digitalWrite(IN1, LOW); 
 digitalWrite(IN2, HIGH); 
 digitalWrite(IN3, LOW); 
 digitalWrite(IN4, HIGH); 
 delay(delay_time); 
 //I want something else to be able to replace these delays
 digitalWrite(IN1, HIGH); 
 digitalWrite(IN2, LOW); 
 digitalWrite(IN3, LOW); 
 digitalWrite(IN4, HIGH);  
 delay(delay_time); 
 digitalWrite(IN1, HIGH); 
 digitalWrite(IN2, LOW); 
digitalWrite(IN3, HIGH); 
digitalWrite(IN4, LOW);  
delay(delay_time); 
}

void step_two(){
digitalWrite(IN1_1, LOW); 
digitalWrite(IN2_1, HIGH); 
digitalWrite(IN3_1, HIGH); 
digitalWrite(IN4_1, LOW); 
delay(delay_time);
digitalWrite(IN1_1, LOW); 
digitalWrite(IN2_1, HIGH); 
digitalWrite(IN3_1, LOW); 
digitalWrite(IN4_1, HIGH); 
delay(delay_time);
digitalWrite(IN1_1, HIGH); 
digitalWrite(IN2_1, LOW); 
digitalWrite(IN3_1, LOW); 
digitalWrite(IN4_1, HIGH);  
delay(delay_time); 
digitalWrite(IN1_1, HIGH); 
digitalWrite(IN2_1, LOW); 
digitalWrite(IN3_1, HIGH); 
digitalWrite(IN4_1, LOW);  
delay(delay_time); 
}
    
pregunta Redrachet2

2 respuestas

1

Ha encontrado uno de los problemas más importantes en la programación integrada, algo que separa a los principiantes de los programadores más avanzados: bloqueo frente a no bloqueo.

Los programas básicos de Arduino son como scripts que solo se repiten una y otra vez: realiza el paso 1, sigue el paso 2, realiza el tercer paso, regresa al 1, etc. como paso: haga el paso 1, espere 10 ms, haga el paso 2, etc. El problema que ha visto es que mientras Arduino está esperando nada , puede suceder algo más, esto se denomina retraso de bloqueo. El bloqueo se usa también en otras situaciones. Si, por ejemplo, está esperando que llegue un byte en serie, muchas bibliotecas simplemente se sentarán y verán cómo el UART recibe el registro hasta que llegue algo, y no hará nada por nada hasta que llegue. En general, las bibliotecas como esta tendrán una función de tiempo de espera: si no llegan datos en X milisegundos, se detendrán y no informarán datos. El bloqueo se usa a menudo en computadoras más grandes con sistemas operativos, pero es un problema menor. En esa situación, puede tener varios subprocesos, de modo que cuando un subproceso está esperando en los datos de UART, el sistema operativo suspenderá esa tarea y dejará que se ejecute otro mientras espera. Los sistemas integrados sin un sistema operativo (como el Arduino) necesitan una biblioteca u otro código para generar un retardo de no bloqueo de una manera diferente. Lamentablemente, el Arduino no tiene esta capacidad incorporada, debe desarrollarla usted mismo o encontrar una biblioteca que la implemente (como sugirió mpflaga).

Implementar una demora sin bloqueo no es un proceso de un solo paso. No se trata de cambiar una llamada de función por otra o cambiar una configuración en la GUI. La arquitectura completa de su programa necesita ser cambiada para soportarlo.

En general, usará un temporizador que se interrumpirá a una frecuencia predefinida; por lo general, 1 ms es bueno para la mayoría de las aplicaciones. Habrá un entero global que realiza un seguimiento del tiempo transcurrido: cuántos milisegundos han transcurrido desde que se inicia el programa (es decir, cuántas veces se ha ejecutado la interrupción del temporizador). Siempre que desee que una función se ejecute periódicamente en lugar de un retraso, tendrá una variable que realiza un seguimiento del índice de la última vez que ocurrió y consultará el tiempo transcurrido actual. Si la diferencia entre es igual al período al que desea que se llame la función, entonces la llama. De lo contrario, no haces nada. En este paradigma, no puede utilizar ninguna declaraciones de retardo en su programa. Cualquier declaración de demora hará que pierdas el tiempo.

Para su aplicación, parece que usted quiere hacer funcionar sus motores cada 5 ms, por lo que ese sería su período de tiempo. Tendrá que hacer un seguimiento del estado de cada uno de los motores para que sepa qué entradas aplicar a ellos a continuación. Puede hacer un seguimiento de esto en sus funciones step_one y step_two con variables estáticas de función y puede usar un conmutador para manejar cada estado. En cada estado, establecerá las entradas al motor paso a paso y luego asignará la variable de estado al siguiente estado: 0- > 1, 1- > 2, 2- > 3, 3- > 0

Eventualmente, puedes modificar las funciones step_one y step_two para tomar un argumento de dirección para que puedas mover los motores en ambas direcciones o mantenerlos quietos.

    
respondido por el AngryEE
1

Podrías echar un vistazo a las interrupciones, creo. Interrupts on arduino wiki

Pero por lo que sé, no puedes multihilo tu código fácilmente. Una de las estrategias podría ser desarrollar un pequeño administrador de tareas que administrará la ejecución de múltiples tareas en la misma MCU y dará la impresión de una ejecución de parralel. Pero, de hecho, es solo una ejecución secuencial, pero en lugar de ejecutar una tarea completa de principio a fin, los hará progresar un poco uno detrás del otro y ... sí, ese es el comienzo de un programador de procesos del sistema operativo. Bastante complicado para el arduino ATMega 328, pero si tienes tiempo, no es imposible.

    
respondido por el Emmanuel Istace

Lea otras preguntas en las etiquetas