Problema con programa para barrera acceso vehiculos

Saludos.

Soy nuevo con esto, soy técnico electrónico y aficionado al DIY, el caso es que estoy realizando una automatización de una barrera para el acceso de vehículos y el funcionamiento que busco seria el siguiente.

Placa: NANO 328
Palca de 8 relés.

Bien uso 2 juegos de 3 relés para hacer la inversión de un motor monofásico, 3 relés para un sentido y tres para otro, ambos juegos se activan con una sola salida cada juego, luego uso otro relé para alimentar el conjunto después de haber activado el modo de inversión.

La necesidad es:

Si la barrera está subiendo y doy un pulso en la interrupción (1), debe parar y volver a bajar.
Si está bajando y pulso, debe parar y subir de nuevo.
Cuando hace la subida y no se le da orden debe esperar el tiempo indicado y volver a bajar, pero si por el contrario se le da un nuevo pulso, debe permanecer parada arriba has recibir un nuevo pulso que la hace bajar sin esperar.

Bien tengo unoardusim con el que simulo el programa y el cual me funciona sin problemas, pero al cargarlo a la placa no hace lo que debe.

A ver si alguien ve en que fallo.

Gracias a todos de ante mano.

//PROGRAMA BARRERA HIDRAULICA

//PROGRAMA BARRERA HIDRAULICA
//Definir pines de salida

#define rldown 4
#define rlup 5
#define rlpow 6
int tsubida = 13;
int tbajada = 10;
volatile int c = 0;
volatile int b = 0;
volatile int state = 1; //state 1=subida, state 2=bajando, state 3=bajada, state 4=subiendo, state 5=parada arriba
int tespera = 30;

void control()
{
 para();
 b = 1;
 c=0;
 
}

void setup()

{
 // put your setup code here, to run once:
 pinMode(rldown, OUTPUT);
 pinMode(rlup, OUTPUT);
 pinMode(rlpow, OUTPUT);
 pinMode(3, INPUT);
 
 digitalWrite(rlpow, HIGH);
 digitalWrite(rldown, HIGH);
 digitalWrite(rlup, HIGH);
 
 state = 1;
 
 attachInterrupt(1, control, FALLING);
 
 
}

void sube()
{
 delay(500);
 digitalWrite(rlup, LOW);  delay(500); digitalWrite(rlpow, LOW);
 
}

void baja()
{
 delay(500);
 digitalWrite(rldown, LOW); delay(500); digitalWrite(rlpow, LOW);
}

void para()
{delay(500);
 digitalWrite(rlpow, HIGH); digitalWrite(rldown, HIGH); digitalWrite(rlup, HIGH);
}


void loop()
// put your main code here, to run repeatedly:

{ delay(500);
 while (state==1)    //subida
 {
 while (b==1)
 {
 state=5; c=1; break;
 }
 while (b==0)
 {
 for (int cuenta=0;cuenta < tespera;cuenta++)
 {
 if (b==0)
 { delay(1000); digitalWrite(13,LOW);}
 else
 { break;}
 
 }
 while (b==0) { baja(); state=2; b=0;break;}  break;
 
 
 }break;
 
 }
 
 while (state==2)    //bajando
 {
 while (b==0)
 {
 for (int tb=0;tb < tbajada;tb++)
 { if (b==0)
 { delay(1000);digitalWrite(13,LOW);}
 else
 { break;}
 }
 while (b==0) { para(); state=3; b=0; c=0;break;} break;
 }
 
 while (b==1)
 {
 para(); delay(1000); sube(); state=4; b=0; break;
 
 
 }
 
 
 }
 
 while (state==3)    //bajada
 {
 while (b==1)
 {
 sube(); state=4; b=0;
 
 
 }break;
 
 
 }
 
 while (state==4)    //subiendo
 {
 while (b==0)
 {
 for (int tb=0;tb<tsubida;tb++)
 { if (b==0)
 { delay(1000);digitalWrite(13,LOW);}
 else
 { break;}
 }
 while (b==0) { para(); state=1;break;}break;
 
 }
 
 while (b==1)
 {
 para(); delay(500); baja();state=2;b=0;break;
 }
 
 
 
 }
 while (state==5)    //parada
 {
 while (c==1)
 { b=0;c=0; break;}
 while (b==1)
 {
 baja(); state=2; b=0;
 for (int tb=0;tb<tbajada;tb++)
 { if (b==0)
 { delay(1000);digitalWrite(13,LOW);}
 else
 { break;}break;
 }
 
 }break;
 }
 
}

Moderador: Editado para que el código sea visible. Los códigos se adjuntan cuando superan los 9000 caracteres.

probada.ino (2.32 KB)

Bien tengo unoardusim con el que simulo el programa y el cual me funciona sin problemas, pero al cargarlo a la placa no hace lo que debe.

Hola,
¿Y qué hace?
Saludos

Pues podría ser eso.

Como he dicho soy electrónico y la programación... :confused:

Ya probé con if (pero no me funciono) buscando y buscando por internet fue lo único que el simulador me dio ok ( y funcionaba), pero en el simulador, en placa como que no, nada de nada, a veces responde otras no, otras hace lo que quiere.

Como lógica para mi pe parece obvio, aunque se ve que para la placa no.

ArduMyth:
¿Por qué usas los whiles() como si de if() se tratasen? ¿De donde viene esa manía últimamente con Arduino?
Aparte de la correspondiente interrupción del resto de código estos están dentro del LOOP que es un bucle infinito. No entiendo esta manía de programar así. No sé de donde salió.

Nunca había visto tanto bucle anidado para algo que se puede hacer con un if()
Yo directamente cambiaría TODO.

No está bien planteado. Lo has complicado de una forma...

Bien, creo que realmente no acabo de comprender el concepto de programación, no haciendo un buen uso de estos parametros, espero que esto me enseñe lo que no estoy haciendo bien.

Ok, creo que voy viendo algo mas de luz (o eso espero), gracias voy a hacer algunos cambios y os cuento.

Bueno si no he entendido mal, creo que podria quedar algo asi, lo he probado en el simulador y parece que va, me queda desplazarme y pasarlo a placa y probar.

Bueno a ver que os parece, por si tengo que tocar (que sera lo mas seguro), esta algo mas limpio y parece mas sencillo.

//PROGRAMA BARRERA HIDRAULICA

//Definir pines de salida

#define rldown 4		//grupo de reles de bajada
#define rlup 5			//grupo de reles de subida
#define rlpow 6			// rele de alimentacion general
int tsubida = 13000;
int tbajada = 10000;
volatile int b = 0;
volatile int state = 1; //state 1=subida, state 2=bajando, state 3=bajada, state 4=subiendo, state 5=parada arriba
int tespera = 30000;
unsigned long tiempo;

void control()
{
	para();
	b = 1;
}

void setup()

{
	// put your setup code here, to run once:
	pinMode(rldown, OUTPUT);
	pinMode(rlup, OUTPUT);
	pinMode(rlpow, OUTPUT);
	pinMode(3, INPUT);
	
	digitalWrite(rlpow, HIGH);
	digitalWrite(rldown, HIGH);
	digitalWrite(rlup, HIGH);
	
	state = 1;
	
	attachInterrupt(1, control, FALLING);	
	
	tiempo=millis();
}



void sube()
{
	
	digitalWrite(rlup, LOW);  delay(500); digitalWrite(rlpow, LOW);
	
}

void baja()
{
	
	digitalWrite(rldown, LOW); delay(500); digitalWrite(rlpow, LOW);
}

void para()
{
	digitalWrite(rlpow, HIGH); digitalWrite(rldown, HIGH); digitalWrite(rlup, HIGH);
}

void loop()

{	
	
	
	
	if (state==1) 	//subida en tiempo de espera
	{
		if (b==1)		//orden de parada
		{
			state=5; b=0;
		}
		if (millis()>tiempo+tespera)
		{
			baja(); state=2;
		}	
	}
	
	if (state==2) 	//bajando
	{
		if (b==1)	//orden de inversion
		{
			b=0; para(); sube(); state=4; tiempo=millis();
		}
		if (millis()>tiempo+tbajada)
		{
			para(); state=3;
		}
	}
	
	if (state==3)	//bajada
	{
		if (b==1)	//orden de subida
		{
			b=0; sube(); state=4;tiempo=millis();
		}
		
	}
	if (state==4)	//subiendo
	{
		if (b==1)	//orden de inversion
		{
			b=0; para(); baja(); state=2; tiempo=millis();
		}
		if (millis()>tiempo+tsubida)
		{
			para(); state=1;
		}
	}
	if (state==5)	//subida en paro permanente
	{
		if (b==1)	//orden de bajada
		{
			baja(); state=2; b=0;tiempo=millis();
		}
	}
	
}

A ver si no la lio subiendo el código.

Gracias de nuevo.

actualizacion.ino (1.97 KB)