Problema con interrupcion

Hola:
Al ejecutar la interrupcion con un pulsador enciende el led durante unos 3 seg. (ping 2)
En el void loop con un pulsador hago que se cumpla la condicion de (pulsacion corta+pulsacion corta+pulsacion larga = Led encendido durante 3 seg. (ping 3)

El problema es que entran los dos en conflicto(interrupcion y void loop), me salta la interrupcion cuando le da la gana.
Es decir pulsando el pulsador corresconpiende al ping 3 (void loop) a veces me entra la interrupcion

#define TcortoMin 100
#define TcortoMax 250
#define TlargoMin 1000
#define TlargoMax 2000
#define Tdelay    150



const byte led            = 13;
const byte boton          = 2;

const byte botonIn          = 3;


unsigned long  timeout1 = 3000;
unsigned long  timeout2 = 3000;
unsigned long  timeout3 = 5000;
unsigned long  duracion    = 0;
void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);    
  pinMode(boton, INPUT);
  pinMode(botonIn, INPUT); 
  attachInterrupt(1,abrirPuerta,RISING); // digital pin 3 // up
}

Interrupcion

void abrirPuerta()
{
   digitalWrite (led, HIGH);                              //encender led
     for (int i=0;i<3000;i++)   {
        delayMicroseconds(1000); 
     }
                                                         //retardo de 3 segundos
     digitalWrite (led, LOW);                            //apagamos el led
     Serial.println("Se ha pulsado boton interior!!!");

 }

void loop

void loop() {
  
   duracion = pulseIn(boton, HIGH, timeout1*1000 )/1000;

  
   if (duracion){
      Serial.print("Se ha pulsado durante ");
      Serial.print(duracion );
      Serial.println(" ms");

      if (duracion > TcortoMin && duracion < TcortoMax) { 
         Serial.println("La duracion entra en margen 1");
         delay (Tdelay);
         duracion = pulseIn(boton, HIGH, timeout2*1000)/1000;
        
         if (duracion){
            Serial.print("Se ha pulsado por segunda vez durante ");
            Serial.print(duracion );
            Serial.println(" ms");

            if (duracion > TcortoMin && duracion < TcortoMax) { 
              Serial.println("La duracion entra en margen 2");
  
              delay (Tdelay);

              duracion = pulseIn(boton, HIGH, timeout3*1000) /1000;

              if (duracion){
                Serial.print("Se ha pulsado por tercera vez durante ");
                Serial.print(duracion );
                Serial.println(" ms");
               
                if (duracion > TlargoMin && duracion < TlargoMax){    //si la duración esta entre los valores establecidos
                  Serial.println("Pulsacion LARGA. Encendemos LED");
                 
                  digitalWrite (led, HIGH);                           //encender led
                  delay (3000);                                       //retardo de 3 segundos
                  digitalWrite (led, LOW);                            //apagamos el led
                } else  Serial.println("Duracion no valida. Salimos!");    
              }else  Serial.println(" No se ha pulsado. Salimos!");
            }else  Serial.println("Duracion no valida. Salimos!");
          }else    Serial.println("Salimos");
      }else  Serial.println("Duracion no valida. Salimos!");
   }//else  Serial.println(" No se ha pulsado. Salimos!");

}

Algun cosejo, muchas gracias

Mi estimado pepoye. Las cosas no ocurren cuando se le da la gana como dices, sino porque cometemos errores en este caso seguramente tienes el pin sin ninguna resistencia a masa, me equivoco?

Aunque bien pudiera ser también lo que dices, surbyte, evidentemente no has visto la rutina de interrupción que ha puesto el amigo pepoye.

Pepoye: olvídate de la interrupción, pues no la necesitas. Si no utilizas delay, para lo que deberás conocer el uso de millis, en tu loop puedes perfectamente repasar todos los pulsadores, si se detecta pulsación apuntar la "hora" en que se comenzó a pulsar, y si se detecta que se dejó de pulsar apuntar la hora en que se dejó de pulsar, restar y calcular cuánto tiempo estuvo pulsado y obrar en consecuencia.

Te refieres a esto

void abrirPuerta()
{
   digitalWrite (led, HIGH);                              //encender led
     for (int i=0;i<3000;i++)   {
        delayMicroseconds(1000); 
     }
                                                         //retardo de 3 segundos
     digitalWrite (led, LOW);                            //apagamos el led
     Serial.println("Se ha pulsado boton interior!!!");

 }

pues la verdad no. Pero no hace falta.
Un pulsador manejado por interrupción es algo que no se quien ha estado metiendo en la cabeza de quienes recién empiezan. Y es el contrasentido mas grande que existe!!

Para no decir mucho mas: solo diré que interrupciones y delay del tipo que sea… no se llevan.
Una interrupción es algo rápido. Sin enviar datos por Serial. sin delay, ni while(1) ni ninguna cosa semejante.

surbyte:
Mi estimado pepoye. Las cosas no ocurren cuando se le da la gana como dices, sino porque cometemos errores en este caso seguramente tienes el pin sin ninguna resistencia a masa, me equivoco?

Hola;
Tengo los dos pulsadores con resistencia a masa de 10K, cada uno de los pulsadores.

noter:
Aunque bien pudiera ser también lo que dices, surbyte, evidentemente no has visto la rutina de interrupción que ha puesto el amigo pepoye.

Pepoye: olvídate de la interrupción, pues no la necesitas. Si no utilizas delay, para lo que deberás conocer el uso de millis, en tu loop puedes perfectamente repasar todos los pulsadores, si se detecta pulsación apuntar la "hora" en que se comenzó a pulsar, y si se detecta que se dejó de pulsar apuntar la hora en que se dejó de pulsar, restar y calcular cuánto tiempo estuvo pulsado y obrar en consecuencia.

Pues intentare quitar la interrupcion y usar millis en el loop. Ya os contare.

Muchisimas gracias a los dos, un saludo

hola:
He descubierto una cosa.
Uso dos pulsadores los cuales van conectados a sus respectivos pines.
Pues bien, si conecto los dos pines juntos, ej: (pin 2 y pin 3) o (pin 3 y pin 4), es cuando me da problemas la interrupcion.
En cambio si dejo un ping o mas en el medio (ej: pin 3 y ping 7) funciona todo correcto.
..me da a mi que es mas un problema de hardware que de software ¿no?

Un saludo

PD- He probrado en varios arduinos Uno, tanto chinos como originales.

Dibuja un esquema, no se entiende lo que dices.
Hazlo a mano alzada, toma una foto, la subes y luego usa ese enlace para presetar debidamente la foto.
SI no sabes preguntame por privado.

Hola:
Muchas gracias por responder

sube
Tal y como esta en la imagen funciona bien
La interrupcion esta en el pin 2( podria ponerlo tambien en el pin 3)
El otro pulsador esta el el pin 5 ( en este caso).

Pero si cambio el pin 5 al pin 3 (es decir, que queden pegados los dos) me da problemas.
El tema es muy facil:
Si los dos pines de entrada que se usan estan juntos FUNCIONA MAL
Si hay un pin libre(o mas) en el medio de los dos pines de entrada FUNCIONA BIEN

@pepoye

Dices que:

pepoye:
... Tal y como esta en la imagen funciona bien
La interrupcion esta en el pin 2( podria ponerlo tambien en el pin 3)
El otro pulsador esta el el pin 5 ( en este caso).

sin embargo tu código dice:

void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);   
  pinMode(boton, INPUT);
  pinMode(botonIn, INPUT);

//..... aqui defines la interrupcion
  attachInterrupt(1,abrirPuerta,RISING); // digital pin 3 // up
}

No tendras un problema derivado de la confusion en la asignacion de los pines??

Alfaville tiene razón.
INT0 es pin2
INT1 es pin3

Si perdonad, lo puse mal en el dibujo. Pero solo en el dibujo. En el arduino lo conecto bien.
El tema es el siguiente:
Si los dos pines de entrada que se usan estan juntos FUNCIONA MAL
Si hay un pin libre(o mas) en el medio de los dos pines de entrada FUNCIONA BIEN

pepoye, el problema que te comenté no era del dibujo. Creo que tienes una confusion en la realizacion del circuito.

pepoye:
Hola:
Al ejecutar la interrupcion con un pulsador enciende el led durante unos 3 seg. (ping 2)
En el void loop con un pulsador hago que se cumpla la condicion de (pulsacion corta+pulsacion corta+pulsacion larga = Led encendido durante 3 seg. (ping 3)

La interrupcion que defines:

attachInterrupt(1,abrirPuerta,RISING); // digital pin 3 // up

se dispara mediante el pin 3 (botonIn)

Comentas también:

El problema es que entran los dos en conflicto(interrupcion y void loop), me salta la interrupcion cuando le da la gana.
Es decir pulsando el pulsador corresconpiende al ping 3 (void loop) a veces me entra la interrupcion

pues claro, si precisamente ese es el pin que has definido para la interrupcion !!!

Mira, esta familia de MCU, está por todo el mundo con millones de unidades operativas (entre ellas la mia), y lo que comentas de los pines contiguos seria un error catastrófico de diseño.

Si descartamos el fallo del diseño, ¿ que nos queda ?... el error en tu proyecto.

Revisa con calma la correspondencia software-hardware, la existencia de resistencias pullup o pulldown donde se necesiten, y acabaras encontrando el problema.

Saludos.

cuando activas la interrupción tienes un for desde 0 a 3000 o sea 3000 loops de 1mseg total, 3 seg
Por eso entra cuando se le da la gana.

Post#6 te hice la advertencia. delays del tipo que sean e interrupciones no se llevan bien.

gracias chicos, voy revisar el codigo. Ya os cuento que tal.
Un millon