Problema con un largoDelay (Proyecto de Arte - Muy novato y en un gran problema)

Hola a todos. Mi nombre es Martín, antes que nada les agradezco por toda la información que van posteando y que me ha sacado de mil apuros (me colgaría comentando lo feliz que me pone a veces ver a tanta gente compartiendo información de manera tan desinteresada, pero no quiero ser tan extenso).

Resulta que vengo hace días descifrando códigos y no he logrado comprender una sola línea (Me prometí tomar un curso luego de esta tormenta)

Mi proyecto es de una máquina que se activa con un motor Paso a Paso, elegí este sistema para lograr fuerza, evitar el ruido y tener posibilidad control en revoluciones lentas. Así entré en este mundo alucinante de la robótica (aunque lo mío es sólo mover un motor).

Dispongo de:

-Arduino UNO
-CNC Shield
-DRV8825
-Stepper 23HS 1314 (8 cables, conectado bipolar en serie por lo que me quedan A1-A2-B1-B2).
-Sensor PIR

Lo que intento lograr es:

Que la máquina se mueva a una velocidad muy lenta y suavemente (1 vuelta por minuto aprox), y que cuando el sensor detecte movimiento, la maquina gire más rapido (1 vuelta por minuto aprox).

He logrado acoplar driver, CNC Shield, Arduino y he puenteado los pines de CNC Shield para trabajar con micropasos a 1/32 (todo esto a partir de muchos tutoriales).

Después de buscar códigos para lograr al menos mover el motor, sin éxito, finalmente logré conseguir un código con respuesta y lo modifiqué todo lo que pude para que haga lo que busco (o casi todo):

#define EN        8  

//Direction pin
#define Z_DIR     7

//Step pin
#define Z_STP     4 

byte sensorpir = 2;

//DRV8825
int delayTime=120; //Delay between each pause (uS)
int stps=1;// Steps to move



void step(boolean dir, byte dirPin, byte stepperPin, int steps)

{

  digitalWrite(dirPin, dir);


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

    digitalWrite(stepperPin, HIGH);

    delayMicroseconds(delayTime); 

    digitalWrite(stepperPin, LOW);

    delayMicroseconds(delayTime); 

  }

}

void setup(){

pinMode(sensorpir,INPUT);
  pinMode(Z_DIR, OUTPUT); 
  pinMode(Z_STP, OUTPUT);
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);

}


void loop(){


   if(digitalRead(sensorpir) == LOW)

{
  
  step(false, Z_DIR, Z_STP, delayTime=14000); //Z, Clockwise


 }
  
  if(digitalRead(sensorpir) == HIGH)

{
  
  step(false, Z_DIR, Z_STP, delayTime=120); //Z, Clockwise
 

 }

}

Con esto logré lo que buscaba (que el movimiento lento no provoque un ruido molesto, ya que a 14000 el ruido parece un ronroneo casi inaudible), y es que la máquina está como en reposo pero moviendo poco a poco y muy suavemente para que vaya modificándose con el tiempo; y cuando se mueve a 120 microsegundos no me molesta el sonido.

El gran problema es que ese larguísimo “Delay” se toma todo su tiempo hasta que finalmente responde al “HIGH” del Sensor. Imposible y aburrido esperarlo.

Bueno… el tema es que como ya no me queda tiempo, este sábado entrego la obra, esto es sólo un manotazo de ahogado para ver si alguien me sugiere una solución.

Quisiera interrumpir ese delay cuando el sensor entra en HIGH. He leido mucho sobre “interrupt”, “millis()”, etc., pero cómo entender un lenguaje que nunca he hablado…?

Bueno, muchísimas gracias.

Espero haberme adecuando a las normas del foro.

Martin

Hola Rope, he visto tu código. No luce mal;

Esta sería una posible solución, solo demoras 14mseg en reaccionar ya que 14000 useg son 14 mseg.

#define EN        8  
#define Z_DIR     7         //Direction pin
#define Z_STP     4         //Step pin

byte sensorpir      = 2;

//DRV8825
int delayTime       = 120; //Delay between each pause (uS)
int stps            = 1;// Steps to move


void step(boolean dir, byte dirPin, byte stepperPin, int steps, boolean estado) {
  int i = 0;
  digitalWrite(dirPin, dir);
  while ( i < steps ) {
      digitalWrite(stepperPin, HIGH);
      delayMicroseconds(delayTime); 
      if (digitalRead(sensorpir) == estado) 
          break;
      digitalWrite(stepperPin, LOW);
      delayMicroseconds(delayTime); 
      if (digitalRead(sensorpir) == estado) 
          break;
      i++;
  }
}

void setup(){

  pinMode(sensorpir,INPUT);
  pinMode(Z_DIR, OUTPUT); 
  pinMode(Z_STP, OUTPUT);
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);
}


void loop(){

    step(false, Z_DIR, Z_STP, delayTime = 14000, LOW); //Z, Clockwise
    step(false, Z_DIR, Z_STP, delayTime = 120, HIGH); //Z, Clockwise
}

Hola,
Prueba sustituir delayMicroseconds(delayTime);
Por esto otro.

long tiempo = millis();
// Se quedara dando vueltas mientras no se cumpla el tiempo  o el pin deseado este en low
do
{
// No hago nada el programa se queda aquí como un delay
} while (digitalRead(pin a comprobar)== LOW || (millis() - tiempo) < delayTime) // delayTime es el intervalo deseado.

Espero haber llegado a tiempo.
Un saludo.

[quote author=rodripelto link=msg=3322120 date=1498900680]
Hola, 
Prueba sustituir delayMicroseconds(delayTime);
Por esto otro.

Para el caso de 14000 useg estoy de acuerdo pero para 120 useg dime como hace tu código para reemplazar a

un delayMicroseconds(120)?

porque lo mínimo que puede poner es 1mseg y eso es casi 1000/120 = 8.33 veces mayor.

Para el caso de 14000 useg estoy de acuerdo pero para 120 useg dime como hace tu código para reemplazar a un delayMicroseconds(120)?

Pues tienes razón, pero creo que la idea es buena y con sustituir millis(), por micro() ya estaría solucionado, ya solo depende del tiempo de proceso de arduino si es suficientemente rápido para cumplirlo.
Un saludo.