Como "romper" un bucle?

Buenos dias
Estoy diseñando un programa que haga básicamente lo siguiente:

Avanzar hacia adelante y al chocar contra un objeto, desplazarse hacia atrás durante un pequeño tiempo (50 pasos), girar levemente sobre una de las ruedas y volver a avanzar. Esta parte funciona correctamente.

Para hacer el programa más completo, quiero que el robot sea capaz de detectar si vuelve a chocar mientras se está desplazando hacia atrás, antes de que se completen los 50 pasos. Entonces debería dejar de retroceder y ejecutar un pequeño desplazamiento hacia adelante, girar sobre si mismo y volver a avanzar (retornando al programa principal)

El robot cuenta con 4 microrruptores. 2 en la parte delantera y 2 en la parte posterior. Los 2 delanteros activan la primera parte del programa. Los 2 traseros deberían romper el bucle de 50 pasos y realizar la función de avanzar y girar.

Os adjunto parte del programa con los comentarios de lo que yo creo que deberían hacer las funciones
Si creeis que es necesario el programa entero, lo coloco!

Muchas gracias


void loop()
{
estat_interrup_ef = digitalRead(interrup_ef); //lectura de los microrruptores
estat_interrup_df = digitalRead(interrup_df);
estat_interrup_ed = digitalRead(interrup_ed);
estat_interrup_dd = digitalRead(interrup_dd);

if (estat_interrup_ef == HIGH ) { //detecta si el microrruptor delantero izquierdo está presionado
enrera(); // activa la función que lo desplaza hacia atrás
delay(15); //
lat_esq(); //activa la funcion que lo hace girar sobre el servo izquierdo y hacia atrás
delay(15); //
}

else { //el robot se dirige hacia adelante cuando no se activa ningún microrruptor
myservo_e.write(horari);
myservo_d.write(antihorari);
digitalWrite(ledpin, LOW);
delay(15);
}}


coloco aquí las funciones aunque en el programa estan donde deben, detrás del void setup


void enrera(){ // se retirará hacia atrás durante 50 pasos
int l=0;
while (l < 50){//condición que limita los 50 pasos
if (estat_interrup_ed == HIGH) { // detecta si el microrruptor trasero izquierdo es activado
delay(5); // esta deteción es la que falla!!
frontal(); // función que debería desplazar al robot hacia adelante durante 20 pasos
gir_dreta(); //función que haría girar al robot sobre si mismo hacia la derecha (sentido horario)
digitalWrite(ledpin, HIGH); // LED puesto para saber si se llega a "leer" esta secuencia de acciones
delay(5);
return;}
else{ //si no se da ninguna de las condiciones anteriores el robot realiza un paso hacia atrás que es lo que pasa siempre!!!!
myservo_e.write(antihorari); //
myservo_d.write(horari);
delay(15);
l++;} // contador de pasos
}return;}

mmmm ¿y cual es tu pregunta?

Ahora que me fijo, la pregunta no queda clara :stuck_out_tongue:

Falla el tercer párrafo. Cuando el robot va hacia atrás y choca activando los microrruptores posteriores, no se realiza la función frontal() que debería dirigir el robot hacia adelante un breve lapso de tiempo, girar y volver a empezar el programa principal.

Muchas gràcies
Carles

Creo que el problema es que, en lugar de analizar el estado de la entrada (con digitalread), lo que haces es analizar el estado de la variable, que contiene la lectura de la entrada digital que hiciste antes de mandarla a la rutina de retroceso. Creo que debes crear una funcion actualizar_entradas, y colocar alli los digitalread, y llamar a esta funcion en cada vuelta del bucle de la funcion enrera.
Lo de separarlo en una funcion,. es por no repetir el codigo en cada sitio.

¿Puede que frontal solo te lo haga cuando esta pulsado el botón trasero?

Cual tarjeta Arduino estas utilizando?

Puedes usar la funciones de interupcion http://arduino.cc/en/Reference/AttachInterrupt . Esas funciones te permiten hacer de manera que, cuando uno de tus captores cambia de estado, se activa una funcion pre determinada.

Con los arduinos duemilanove, puedes usar 2 interrupciones. Con las megas, puedes usar haasta 6.

A parte de eso, lo que puedes hacer es, en vez de escribir

while (l < 50){//condición que limita los 50 pasos

Porque efectivamente, estat_interrup_ed no cambia, puedes escribir lo siguiente

estat_interrup_ed = digitalRead(interrup_ed);
while (l < 50 && estat_interrup_ed != HIGH)
{}
if (l >50)
{return}//Volver al programa principal, porque se cumpliron los 50 pasos
if (estat_interrup_ed == HIGH)
{}//Accion en caso de choco con un objecto.

Suerte!

Buenos días!
Ya funciona XD!

Pofenas ha dado en el clavo. El problema estava en la lectura del digitalRead. La recomendación de la función, actualizar_entradas, la he aplicado y el programa ha quedado muy estructurado!

Respondiendo también a nayma, efectivamente la función frontal solo funcionaba cuando se pulsaba el botón trasero.

No he llegado a provar la propuesta de BobbyWom, pero tomo nota!

Muchas gracias a todos

NOTA: Si alguien quiere el programa completo lo publico.

Hasta la pròxima
Carles

Me alegro que te funcione. :slight_smile: