Problema con los Whiles

Hola buenas noches, estoy haciendo un proyecto el cual se basa en hacer una cortina industrial en maqueta, para esto estamos usando arduino, pero al momento de programar se me está dificultando un poco, esta cortina cuenta con 3 sensores, uno que está arriba el cual detecta cuando la cortina ya subió todo lo que debía, otro abajo el cual detecta cuando la cortina ya alcanzó su punto más bajo y el último sensor que detecta cuando bajo la cortina hay algún objeto , con este último sensor lo que se quiere lograr es que si la cortina está bajando y este sensor detecta algo, la cortina vuelva a subir y después a bajar.
En el código, ya logré hacer que cuando presiono un botón, la cortina empiece a subir hasta el límite superior, después bajé hasta el límite inferior, pero al momento de tratar de poner la condición del sensor de objetos bajo la cortina, no puedo implementarlo porque los whiles se hacen de manera en como están escritos, es decir se si primero pongo un while del sensor de abajo, el while del sensor de objetos no va a funcionar, también intenté con una interrupción, pero dentro de la interrupción no puedes poner delays ni whiles, lo cual me hizo imposible realizar el ciclo de emergencia dentro de la interrupción, entonces les pido su ayuda para encontrar la manera de que se puedan realizar dos whiles sin importar el orden de escritura o si alguno tiene otra solución, me encantaría escucharla, muchas gracias.

void autom() {

  if (digitalRead(button) == HIGH) { 
    digitalWrite(in1, HIGH); //aqui va para un lado
    digitalWrite(in2, LOW);

    while (digitalRead(sensorarriba) == LOW) {
    } //no se porque el codigo funciona con los corchetes asi y cuando los
    //pongo normales no funciona
    digitalWrite(in1, LOW);
    digitalWrite(in2, 0);
    delay(2000);
    digitalWrite(in1, LOW);
    digitalWrite(in2, 1);
  
    while (digitalRead(sensorabajo) == 1) {
    }
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);

    while (digitalRead(sensorobjetos) == 1) {
    }
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    delay(2000)
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    delay(2000)
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);
    delay(2000)
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    delay(2000)
    //El problema esta en que primero lee el while del sensor de abajo
    //haciendo imposible que lea este while
  }
}

Su publicacion se MUEVE a su ubicacion actual ya que es mas adecuada.

1 Like

Lo que hace esto es esperar a que la condición sea falsa. Igual con tus otros while.


Tu proyecto es apropiado para una máquina de estados. Esta técnica simplifica enormemente tu proceso de desarrollo. Busca en Internet o en este foro "maquina de estados" o "finite sate machine". Aquí un adelanto:

En esta máquina de estados, la transición entre estados se activa si y sólo si se oprime el botón o se activa un sensor, como se muestra. Al cambiar de estado se energizan los motores apropiados y continúan así hasta el siguiente cambio de estado.

enum Estados {ESPERANDO, SUBIENDO, BAJANDO);

Estados estado = ESPERANDO;

void autom() {
  switch (estado) {
    case ESPERANDO:
      if (digitalRead(button) == HIGH) {
      	// energizar aqui motores de subida
      	estado=SUBIENDO;
      }
      break;

    case SUBIENDO:
      if (digitalRead(sensorarriba) == LOW) {
      	// energizar aqui motores de bajada
      	estado=BAJANDO
      }
      break;

    case BAJANDO:
      if (digitalRead(sensorabajo) == HIGH) {
      	// detener aqui motores
      	estado=ESPERANDO;
      }
      if (digitalRead(sensorobjetos) == HIGH) {
      	// energizar aqui motores de subida
      	estado=SUBIENDO;
      } 
      break;
  }
}

Dependiendo de tu proyecto es posible que debas agregar código para manejar los rebotes de los botones y sensores de límite (debouncing)


Recuerda siempre: corregir los errores de compilación antes de subir tu código, y asegurarte de subir el código completo.

Y evita al máximo el uso de delay() dentro de loop()

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.