Haciendo pruebas me encuentro con el siguiente detalle al ejecutar una interrupcion
He aqui el codigo que supuestamente aplicaremos para un lavavajillas:
volatile int vaciado = 8;
volatile int llenado = 6;
volatile int bobinaA = 10;
volatile int bobinaT = 11;
int puerta = 2;
void setup() {
Serial.begin(9600);
pinMode(vaciado, OUTPUT);
pinMode(llenado, OUTPUT);
pinMode(bobinaA, OUTPUT);
pinMode(bobinaT, OUTPUT);
attachInterrupt(digitalPinToInterrupt(puerta), PuertaAbierta, LOW);
}
void PuertaAbierta() {
digitalWrite(bobinaT, LOW); //detenemos bobina trabajo
digitalWrite(bobinaA, LOW); //detenemos bobina arranque
digitalWrite(llenado, LOW); //paramos carga de agua
digitalWrite(vaciado, LOW); //paramos vaciado
}
void loop() {
//////////////////////////////////////////////////////////////////////////////////// VACIADO
for (int a = 0; a<=100; a++){ //bucle de vaciado
digitalWrite(vaciado, HIGH); //vaciamos agua
Serial.println ("Vaciado");
delay (250); //tiempo de vaciado
}
digitalWrite(vaciado, LOW); //paramos vaciado de agua
Serial.println ("Paramos vaciado");
delay (2000);
//////////////////////////////////////////////////////////////////////////////////// LLENADO
for (int a = 0; a<=140; a++){ //bucle de llenado
digitalWrite(llenado, HIGH); //cargamos de agua
Serial.println ("Llenado");
delay (250); //tiempo de llenado
}
digitalWrite(llenado, LOW); //paramos carga de agua
Serial.println ("Paramos llenado");
delay (2000);
//////////////////////////////////////////////////////////////////////////////////// BOBINAS MOTOR
for (int i = 0; i<=50; i++){ //bucle de prelavado
digitalWrite(bobinaT, HIGH); //arrancamos bomba
Serial.println ("Arracamos BT");
digitalWrite(bobinaA, HIGH); //arrancamos bomba
Serial.println ("Arrancamos BA");
delay (250);
}
digitalWrite(bobinaT, LOW); //paramos bomba
digitalWrite(bobinaA, LOW); //paramos bomba
Serial.println ("Paramos bomba");
}
Tal cual tenemos el codigo al ejecutar la interrupcion los digitalWrite de la interrucion se ejecutan pero los bucles "for" que se encuentran en el loop se siguen ejecutando, avanzando el codigo el el loop.
Como cosa curiosa si le coloco un Serial.println dentro de la interrupcion esta se ejecuta correctamente.
void PuertaAbierta() {
digitalWrite(bobinaT, LOW); //detenemos bobina trabajo
digitalWrite(bobinaA, LOW); //detenemos bobina arranque
digitalWrite(llenado, LOW); //paramos carga de agua
digitalWrite(vaciado, LOW); //paramos vaciado
Serial.println ("ParadaEmergencia");
}
Detalle a comentar que si por ejemplo en la interrupcion eliminio uno o mas de los digitalWrite (de los cuatro que hay) ya se ejecuta esta correctamente.
Mi tampoco entender.
A ver si no digo ninguna burrada, cuando entra la interrupción, se ejecuta PuertaAbierta, una vez termina los 4 digitalWrite el programa sigue por donde se encontraba.
Entonces los las salidas digitales que tienes en loop te cambian a HIGH cuando les toca ya que el programa continúa.
Igual tu crees que no se ejecuta correctamente pero el problema es que cambian demasiado rápido y crees que no se ha ejecutado la interrupción correctamente.
Te propongo un cambio, y si dentro de la interrupción miras como está la entrada que la causa y si sigue activa no dejas al programa que salga del PuertaAbierta??
Sería algo así:
volatile int vaciado = 8;
volatile int llenado = 6;
volatile int bobinaA = 10;
volatile int bobinaT = 11;
int puerta = 2;
int abierta = 0;
void setup() {
Serial.begin(9600);
pinMode(vaciado, OUTPUT);
pinMode(llenado, OUTPUT);
pinMode(bobinaA, OUTPUT);
pinMode(bobinaT, OUTPUT);
attachInterrupt(digitalPinToInterrupt(puerta), PuertaAbierta, LOW);
}
void PuertaAbierta() {
abierta = digitalRead(puerta);
digitalWrite(bobinaT, LOW); //detenemos bobina trabajo
digitalWrite(bobinaA, LOW); //detenemos bobina arranque
digitalWrite(llenado, LOW); //paramos carga de agua
digitalWrite(vaciado, LOW); //paramos vaciado
if (abierta == HIGH)
{
PuertaAbierta();
}
}
void loop() {
//////////////////////////////////////////////////////////////////////////////////// VACIADO
for (int a = 0; a<=100; a++){ //bucle de vaciado
digitalWrite(vaciado, HIGH); //vaciamos agua
Serial.println ("Vaciado");
delay (250); //tiempo de vaciado
}
digitalWrite(vaciado, LOW); //paramos vaciado de agua
Serial.println ("Paramos vaciado");
delay (2000);
//////////////////////////////////////////////////////////////////////////////////// LLENADO
for (int a = 0; a<=140; a++){ //bucle de llenado
digitalWrite(llenado, HIGH); //cargamos de agua
Serial.println ("Llenado");
delay (250); //tiempo de llenado
}
digitalWrite(llenado, LOW); //paramos carga de agua
Serial.println ("Paramos llenado");
delay (2000);
//////////////////////////////////////////////////////////////////////////////////// BOBINAS MOTOR
for (int i = 0; i<=50; i++){ //bucle de prelavado
digitalWrite(bobinaT, HIGH); //arrancamos bomba
Serial.println ("Arracamos BT");
digitalWrite(bobinaA, HIGH); //arrancamos bomba
Serial.println ("Arrancamos BA");
delay (250);
}
digitalWrite(bobinaT, LOW); //paramos bomba
digitalWrite(bobinaA, LOW); //paramos bomba
Serial.println ("Paramos bomba");
}
No veo uno o varios pulsadores, o un encoder, tampoco una pantalla lcd o de 7 segmentos.
Olvida la interrupción porque tu código no es un programa de lavavajillas mas o menos logrado.
Deberías solicitar ayuda desde cero, pero ofreciendo todo el material necesario para saber como funciona lavadora suponiendo que lo que intentas hacer es reconstruir una vieja máquina lavaplatos.
Recientemente he reconstruido a nuevo una lavadora de ropas Siemens de 18 años, reemplazando el programador mecánico por un arduino. El cambio de giro, o centrifugado, como la válvula de agua y bomba de desagote se activan con relay. La jabonera se maneja con un servo.
Para que veas como he hecho el soft con dos programa de lavado, ropa normal y delicada, con las opciones de centrifugar, flotar y temperatura del agua te dejo el skech donde la interrupción la uso para detectar el fallo de energía y poder retomar en el mismo lugar por donde iba el programa de lavado.
Básicamente "el programa de lavado" consta de dos datos mediante un arreglo de pasos. Un dato es un número que traducido a binario interpreta el estado de los relay y el otro dato es la cantidad de segundos que mediante un multiplicador "por default 1000" nos dice la cantidad de milisegundos entre un paso y el siguiente. Es con el uso de millis() como deberías escribir tu soft.
Yo creo que int puerta = 2; es correcto ya que llama a la interrución con: digitalPinToInterrupt(puerta)
osea que esta le está diciendo que utilice la interrupción "0".
surbyte:
Usar una interrupción no tiene sentido a menos que no sepas programar (es mi opinión y claro que pueden no compartirla).
As dado en el clavo... me resulta mucho mas comodo la interrupcion dado mi desconocimiento en programacion
Lo que estoy usando es arduino UNO. Perdon, para la proxima lo pongo desde el principio.
attiny128:
No veo uno o varios pulsadores, o un encoder, tampoco una pantalla lcd o de 7 segmentos.
Olvida la interrupción porque tu código no es un programa de lavavajillas mas o menos logrado.
El programa se que esta imcompleto pero solo pego la parte donde tengo el problema. Es por ponerlo mas simple.
Sereno:
Mi tampoco entender.
A ver si no digo ninguna burrada, cuando entra la interrupción, se ejecuta PuertaAbierta, una vez termina los 4 digitalWrite el programa sigue por donde se encontraba.
Entonces los las salidas digitales que tienes en loop te cambian a HIGH cuando les toca ya que el programa continúa.
Igual tu crees que no se ejecuta correctamente pero el problema es que cambian demasiado rápido y crees que no se ha ejecutado la interrupción correctamente.
Voy intentar explicarlo bien, cuando pulso el interruptor de la interrupcion (queda pulsado) entra la interrupcion permanentemente hasta que yo actue otra vez en el interruptor. Mientras este activado se deberia ejecutar en bucle el codigo de la interrupcion, y ningun otro codigo mas.
Esto sucede asi pues los digitalWrite pasan de HIGH a LOW, no obtante el codigo del void loop me sigue avanzado. Es decir, que cuando yo "despulso" el interruptor para desactivar la interrupcion No me empieza donde se produjo la interrupcion.... si no mas adelante.
No se si me explico bien.
Muchas gracias a todos por responder. Soy consciente del uso de delay y de los antirebotes. Para el proximo sketch los aplicare. Me resulta todo un poco complicado.
Gracias otra vez
ArduMyth:
No sé de donde has ido cogiendo la información pero es que ya de entrada con ver los pines declarados cómo volatile hacen saltar las alarmas... si ahorro de memoria querías usa #define... y es que además dichos valores no los vas a modificar. Lo suyo es que sean constantes usando const unsigned int o const byte o #defiine.
Habia leeido en unos tutos que cuando se usan variables tanto el el loop como en la interrpcion pues que era recomendable declararlas asi.
Esta claro que de programacion ni idea... lo hago sacando cosasa de aqui y alla.