Problema Proyecto Apertura NFC

Buenas noches,

me encuentro realizando un proyecto mediante un sensor NFC el cual abrirá dos puertas diferentes mediante el id de dos tarjetas (cada una abre una puerta).

Quiero que cada puerta se distinga de la otra en el proyecto mediante un pulsador par cada una. Así si pulsas el boton 1, se queda en bucle el código de apertura/fallo de la puerta 1 y si pulsas el boton 2, se quede en bucle el codigo para la puerta 2.

El problema es que no consigo hacer que cada botón haga que se quede en bucle el codigo de una puerta hasta que se pulse el pulsador de la otra puerta.

Este es el código que he conseguido hasta ahora y que me está dando problemas porque se me encienden los leds de las dos puertas nada más iniciarse el programa…

#include <PN532.h>

#define SCK         13
#define MOSI        11
#define SS          10
#define MISO        12

#define ID_TARJETA  717972443
#define ID_TARJETA2 445404892

PN532 nfc(SCK, MISO, MOSI, SS);
int ledPin1 = 5;    // Led de lectura
int ledPin2 = 9;     // Led de fallo
int ledPin3 = 6;     // Led Apertura
int ledAzul = 3;

int Boton1 = 2;
int Boton2 = 8;

// variables
int IDCounter = 0;   // contador para el numero de veces el id es falso
int puerta = 0;
int ledState = LOW;   // ledState se usará para establecer el estado del LED

long tempo = 2000;
long previousMillis = 0;
long interval = 1000;




void setup()
{
   Serial.begin(9600);
   nfc.begin();
   nfc.SAMConfig();
   
   // inicializa el LED de apertura como pin de entrada
  pinMode(ledPin1, OUTPUT);
  // inicializa el LED de fallo como pin de salida
  pinMode(ledPin2, OUTPUT);
  pinMode(Boton1, INPUT);
  pinMode(Boton2, INPUT);
  // inicializa la comunicación serial
  Serial.begin(9600);
}


void loop()
{

   
if (digitalRead(Boton1) == HIGH){
  puerta = 1;
  }
  
  if (puerta == 1)
  {
    digitalWrite(ledPin1, HIGH);
    
  uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  
// Si el ID leido coincide con el de la constante "ID_TARJETA"...
   if( id == ID_TARJETA )
   {
      IDCounter = 0;
      digitalWrite(ledPin3, HIGH); 
      delay(4000);
      digitalWrite(ledPin3, LOW);
     
      }
  
    
  // el LED de fallo se enciende cada 3 lecturas de la tarjeta equivocada
  
  IDCounter == 0;
  
   if( id != 0 && id != 717972443 ) {
    IDCounter ++ ;
    delay(1000);
  }
  if (IDCounter == 3) {
unsigned long currentMillis = millis();    // Se toma el tiempo actual

if (currentMillis - previousMillis > interval){


previousMillis = currentMillis;

// Y ahora cambiamos de estado el LED, si está encendido a apagado o viceversa.
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

digitalWrite(ledPin2, ledState);   // Hacemos que el contenido de la variable llegue al LED
  
}
  }
    }
    
if (digitalRead(Boton2) == HIGH){
  puerta = 2;
  }
  
  if (puerta = 2){
    digitalWrite(ledAzul, HIGH);
    
  uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  
// Si el ID leido coincide con el de la constante "ID_TARJETA"...
   if( id == ID_TARJETA2 )
   {
      IDCounter = 0;
      digitalWrite(ledPin3, HIGH); 
      delay(4000);
      digitalWrite(ledPin3, LOW);
     
      }
  
    
  // el LED de fallo se enciende cada 3 lecturas de la tarjeta equivocada
  
  IDCounter == 0;
  
   if( id != 0 && id != 445404892 ) {
    IDCounter ++ ;
    delay(1000);
  }
  if (IDCounter == 3) {
unsigned long currentMillis = millis();    // Se toma el tiempo actual

if (currentMillis - previousMillis > interval){


previousMillis = currentMillis;

// Y ahora cambiamos de estado el LED, si está encendido a apagado o viceversa.
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

digitalWrite(ledPin2, ledState);   // Hacemos que el contenido de la variable llegue al LED
  
}
  }
    }
    
}

Muchas gracias de antemano!!!

P.D: Lo que en las declaraciones es nombrado como Led de lectura y led azul son los leds que indican la puerta 1 y la 2 respectivamente. No me he dado cuenta y no lo he cambiado aún .

Prueba esto a ver si funciona mejor.

void loop() {
  
    if (digitalRead(Boton1) == HIGH) {
        //puerta = 1;

        digitalWrite(ledPin1, HIGH);
        uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  
        // Si el ID leido coincide con el de la constante "ID_TARJETA"...
        if (id == ID_TARJETA ) {
           IDCounter = 0;
           digitalWrite(ledPin3, HIGH); 
           delay(4000);
           digitalWrite(ledPin3, LOW);
        }
  
        // el LED de fallo se enciende cada 3 lecturas de la tarjeta equivocada
  
       IDCounter == 0;
       if (id != 0 && id != ID_TARJETA) {
            IDCounter ++ ;
            delay(1000);
        }
        if (IDCounter == 3) {
            unsigned long currentMillis = millis();    // Se toma el tiempo actual
            if (currentMillis - previousMillis > interval){
                previousMillis = currentMillis;

                // Y ahora cambiamos de estado el LED, si está encendido a apagado o viceversa.
                if (ledState == LOW)
                ledState = HIGH;
                else
                ledState = LOW;

                digitalWrite(ledPin2, ledState);   // Hacemos que el contenido de la variable llegue al LED
      
            }
        }
    }
        
    if (digitalRead(Boton2) == HIGH){
        //puerta = 2;
    //}
      
    //if (puerta = 2) {
        digitalWrite(ledAzul, HIGH);
        
        uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
      
        // Si el ID leido coincide con el de la constante "ID_TARJETA"...
        if (id == ID_TARJETA2)  {
             IDCounter = 0;
             digitalWrite(ledPin3, HIGH); 
             delay(4000);
             digitalWrite(ledPin3, LOW);
        }
        
        // el LED de fallo se enciende cada 3 lecturas de la tarjeta equivocada
      
       IDCounter == 0;
      
        if (id != 0 && id != ID_TARJETA2) {
          IDCounter ++ ;
            delay(1000);
        }
        if (IDCounter == 3) {
            unsigned long currentMillis = millis();    // Se toma el tiempo actual

            if (currentMillis - previousMillis > interval){
                previousMillis = currentMillis;

                // Y ahora cambiamos de estado el LED, si está encendido a apagado o viceversa.
                if (ledState == LOW)
                    ledState = HIGH;
                else
                    ledState = LOW;

                digitalWrite(ledPin2, ledState);   // Hacemos que el contenido de la variable llegue al LED
      
            }
       }
    }
}

surbyte: Prueba esto a ver si funciona mejor.

void loop() {
  
    if (digitalRead(Boton1) == HIGH) {
        //puerta = 1;

        digitalWrite(ledPin1, HIGH);         uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);           // Si el ID leido coincide con el de la constante "ID_TARJETA"...         if (id == ID_TARJETA ) {       IDCounter = 0;       digitalWrite(ledPin3, HIGH);       delay(4000);       digitalWrite(ledPin3, LOW);         }           // el LED de fallo se enciende cada 3 lecturas de la tarjeta equivocada         IDCounter == 0;       if (id != 0 && id != ID_TARJETA) {         IDCounter ++ ;         delay(1000);     }     if (IDCounter == 3) { unsigned long currentMillis = millis();    // Se toma el tiempo actual if (currentMillis - previousMillis > interval){ previousMillis = currentMillis;

            // Y ahora cambiamos de estado el LED, si está encendido a apagado o viceversa.
            if (ledState == LOW)
            ledState = HIGH;
            else
            ledState = LOW;

            digitalWrite(ledPin2, ledState);   // Hacemos que el contenido de la variable llegue al LED
  
        }
    }
}
    
if (digitalRead(Boton2) == HIGH){
    //puerta = 2;
//}
  
//if (puerta = 2) {
    digitalWrite(ledAzul, HIGH);
    
    uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  
    // Si el ID leido coincide con el de la constante "ID_TARJETA"...
    if (id == ID_TARJETA2)  {
         IDCounter = 0;
         digitalWrite(ledPin3, HIGH); 
         delay(4000);
         digitalWrite(ledPin3, LOW);
    }
    
    // el LED de fallo se enciende cada 3 lecturas de la tarjeta equivocada
  
   IDCounter == 0;
  
    if (id != 0 && id != ID_TARJETA2) {
      IDCounter ++ ;
        delay(1000);
    }
    if (IDCounter == 3) {
        unsigned long currentMillis = millis();    // Se toma el tiempo actual

        if (currentMillis - previousMillis > interval){
            previousMillis = currentMillis;

            // Y ahora cambiamos de estado el LED, si está encendido a apagado o viceversa.
            if (ledState == LOW)
                ledState = HIGH;
            else
                ledState = LOW;

            digitalWrite(ledPin2, ledState);   // Hacemos que el contenido de la variable llegue al LED
  
        }

  }     } }

Así funciona a medias, quería que usara la variable 'puerta' para que sólo funcione uno de los codigos a la vez y que siga funcionando aunque hayas dejado de pulsarlo.

Gracias por las molestias Surbyte!!

Y no termino de enteder que funcionaba mal en tu código? Explica mejor lo de los bucles

Buenos días, tengo dudas sobre el funcionamiento de este sistema. Según entiendo un sistema NFC es para abrir la puerta por proximidad, es decir, al pasar o leer la tarjeta con el sensor, éste abrirá la puerta que debe abrir o para la cual esta autorizada el ID de esa tarjeta. No termino de entender para que son los pulsadores???

surbyte: Y no termino de enteder que funcionaba mal en tu código? Explica mejor lo de los bucles

Lo explico mejor.

El programa tiene dos 'if' principales y dentro del primero se encuentra el código para abrir o que de error en una supuesta puerta 1 y en el segundo if se encuentra el código para lo mismo en una supuesta puerta 2. Cada puerta tiene un único id de una tarjeta asignado para la apertura y otro para el fallo.

Para elegir entre el código de apertura/error de una puerta u otra, se han de pulsar un pulsador u otro. Al haber pulsado uno de los pulsadores, una variable llamada 'puerta', se pone a 1 y con el otro pulsador se pone a 2. Así al estar la variable, se queda en bucle leyendo siempre el código de apertura/fallo de una única puerta hasta que es pulsado el otro pulsador que pasa a estar en bucle en el código de la otra.

El problema que tenía era que yo había puesto dos leds, uno para que se viera qué codigo de apertura/fallo estaba en bucle en ese momento y se me encienden los 2 leds nada más empezar el programa.

Espero haberme explicado mejor...

Veamos los problemas de tu código. Lo enciendes con puerta 1 y como lo apagas? Puerta 1 no cambia hasta que sea puerta 2 toda la vida... y nunca estan las dos puertas cerradas? Los leds si encienden prendidos pues apagalos en el setup. Simple como eso.

surbyte: Veamos los problemas de tu código. Lo enciendes con puerta 1 y como lo apagas? Puerta 1 no cambia hasta que sea puerta 2 toda la vida... y nunca estan las dos puertas cerradas? Los leds si encienden prendidos pues apagalos en el setup. Simple como eso.

Te pongo una explicación más tipo diagrama de flujo.

1) Si boton 1 es pulsado, la variable puerta se pone a 1. -Si puerta es 1: Se enciende el led 1 y se reproduce el codigo 1

2) Si boton 2 es pulsado, la variable puerta se pone a 2. -Si puerta es 2: Se enciende el led 2 y se reproduce el codigo 2

Las condiciones 1 y 2 están al mismo nivel porque nunca pueden estar funcionando al mismo tiempo, de ahí que haya puesto la variable además de para que el codigo 1 o el codigo 2, no se reproduzcan al mismo tiempo sino que o se reproduzca una en bucle, o la otra.

Ok pero puerta = 1 o puerta = 2 nunca pasan a puerta = 0 de modo que siempre tendras un bucle activo, eso es lo que quieres?

Tienes dos leds definidos en el setup y 3 leds en el código. para puerta 1 y puerta 2 usas ledPin3 no definido en setup

       digitalWrite(ledPin3, HIGH); 
       delay(4000);
       digitalWrite(ledPin3, LOW);

Tienes dos

Serial.begin(9600); en el setup // otro error a corregir.

y para terminar tanto puerta 1 como puerta 2 activan el mismo led que es led2

 if (ledState == LOW)
        ledState = HIGH;
        else
        ledState = LOW;

        digitalWrite(ledPin2, ledState);   // Hacemos que el contenido de la variable llegue al LED

Esto tomado de TU código. usa Led1 en puerta 1 y led2 en puerta 2. Define en setup a Led3 Quita el Serial.begin(9600) de mas.

surbyte:
Ok pero puerta = 1 o puerta = 2 nunca pasan a puerta = 0 de modo que siempre tendras un bucle activo, eso es lo que quieres?

Sí, eso es. Quiero tener siempre un bucle activo. O el codigo 1 o el 2, pero siempre uno activo.

surbyte:
Ok pero puerta = 1 o puerta = 2 nunca pasan a puerta = 0 de modo que siempre tendras un bucle activo, eso es lo que quieres?

Tienes dos leds definidos en el setup y 3 leds en el código.
para puerta 1 y puerta 2 usas ledPin3 no definido en setup

       digitalWrite(ledPin3, HIGH); 

delay(4000);
      digitalWrite(ledPin3, LOW);



Tienes dos 


Serial.begin(9600); en el setup // otro error a corregir.





y para terminar tanto puerta 1 como puerta 2 activan el mismo led que es led2


if (ledState == LOW)
        ledState = HIGH;
        else
        ledState = LOW;

digitalWrite(ledPin2, ledState);  // Hacemos que el contenido de la variable llegue al LED




Esto tomado de TU código.
usa Led1 en puerta 1 y led2 en puerta 2.
Define en setup a Led3
Quita el Serial.begin(9600) de mas.

Haciendo eso sigue igual… se encienden los leds de puerta 1 y puerta 2 a la vez nada más comenzar el programa.

#include <PN532.h>

#define SCK         13
#define MOSI        11
#define SS          10
#define MISO        12

#define ID_TARJETA  717972443
#define ID_TARJETA2 445404892

PN532 nfc(SCK, MISO, MOSI, SS);
int ledPin1 = 5;    // Led Puerta 2
int ledPin2 = 9;     // Led de fallo
int ledPin3 = 6;     // Led Apertura
int ledPin4 = 3;    //Led Puerta 1

int Boton1 = 2;
int Boton2 = 8;

// variables
int IDCounter = 0;   // contador para el numero de veces el id es falso
int puerta = 0;
int ledState = LOW;   // ledState se usará para establecer el estado del LED

long previousMillis = 0;
long interval = 1000;




void setup()
{
   Serial.begin(9600);
   nfc.begin();
   nfc.SAMConfig();
   
  
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
  
  pinMode(Boton1, INPUT);
  pinMode(Boton2, INPUT);
}

void loop()
{

   
if (digitalRead(Boton1) == HIGH){
  puerta = 0;
  }
  
  if (puerta == 0)
  {
    digitalWrite(ledPin1, HIGH);
    
  uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  
// Si el ID leido coincide con el de la constante "ID_TARJETA"...
   if( id == ID_TARJETA )
   {
      IDCounter = 0;
      digitalWrite(ledPin3, HIGH); 
      delay(4000);
      digitalWrite(ledPin3, LOW);
     
      }
  
    
  // el LED de fallo se enciende cada 3 lecturas de la tarjeta equivocada
  
  IDCounter == 0;
  
   if( id != 0 && id != 717972443 ) {
    IDCounter ++ ;
    delay(1000);
  }
  if (IDCounter == 3) {
unsigned long currentMillis = millis();    // Se toma el tiempo actual

if (currentMillis - previousMillis > interval){


previousMillis = currentMillis;

// Y ahora cambiamos de estado el LED, si está encendido a apagado o viceversa.
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

digitalWrite(ledPin2, ledState);   // Hacemos que el contenido de la variable llegue al LED
  
}
  }
    }
    
if (digitalRead(Boton2) == HIGH){
  puerta = 1;
  }
  
  if (puerta = 1){
    digitalWrite(ledPin4, HIGH);
    
  uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  
// Si el ID leido coincide con el de la constante "ID_TARJETA"...
   if( id == ID_TARJETA2 )
   {
      IDCounter = 0;
      digitalWrite(ledPin3, HIGH); 
      delay(4000);
      digitalWrite(ledPin3, LOW);
     
      }
  
    
  // el LED de fallo se enciende cada 3 lecturas de la tarjeta equivocada
  
  IDCounter == 0;
  
   if( id != 0 && id != 445404892 ) {
    IDCounter ++ ;
    delay(1000);
  }
  if (IDCounter == 3) {
unsigned long currentMillis = millis();    // Se toma el tiempo actual

if (currentMillis - previousMillis > interval){


previousMillis = currentMillis;

// Y ahora cambiamos de estado el LED, si está encendido a apagado o viceversa.
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

digitalWrite(ledPin2, ledState);   // Hacemos que el contenido de la variable llegue al LED
  
}
  }
    }
    
}

Muchas gracias por tu tiempo Surbyte

SOLUCIONADO!

#include <PN532.h>

#define SCK         13
#define MOSI        11
#define SS          10
#define MISO        12

#define ID_TARJETA  717972443
#define ID_TARJETA2 445404892

PN532 nfc(SCK, MISO, MOSI, SS);

int b = 7;    //Boton elige puerta 1

int b3 = 8;   //Boton elige puerta 2

int led1 = 3; //Led puerta 1
int led2 = 5; //Led puerta 2
int led3 = 6; //Led apertura
int led4 = 9; //Led fallo

int IDCounter = 0;  //Variable para el contador de fallos


void setup() {

  Serial.begin(9600);
   nfc.begin();
   nfc.SAMConfig();
   
pinMode(b, INPUT);
pinMode(b3, INPUT);

pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
}
void puerta1(){   //Codigo de apertura de la puerta 1

  uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  
  if( id == ID_TARJETA ) //Apertura de la puerta si el id coincide
   {
      IDCounter = 0;
      digitalWrite(led3, HIGH); 
      delay(3000);
      digitalWrite(led3, LOW);
     
      }
  
    
  // el LED de fallo se enciende cada 3 lecturas de la tarjeta equivocada
  
  IDCounter == 0;
  
   if( id != 0 && id != 717972443 ) {
    IDCounter ++ ;
    delay(1000);
  }
      if (IDCounter == 3) {
digitalWrite(led4, HIGH);
delay(200);
digitalWrite(led4, LOW);
delay(200);
digitalWrite(led4, HIGH);
delay(200);
digitalWrite(led4, LOW);
delay(200);
digitalWrite(led4, HIGH);
delay(200);
digitalWrite(led4, LOW);
delay(3000);
digitalWrite(led4, LOW);
IDCounter = 0;
  }
      }
      


void puerta2() {    //Codigo de apertura de la puerta 2

uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
  

  if( id == ID_TARJETA2 ) //Apertura de la puerta si el id coincide
   {
      IDCounter = 0;
      digitalWrite(led3, HIGH); 
      delay(3000);
      digitalWrite(led3, LOW);
     
      }
  
    
  // el LED de fallo se enciende cada 3 lecturas de la tarjeta equivocada
  
  IDCounter == 0;
  
   if( id != 0 && id != 445404892 ) {
    IDCounter ++ ;
    delay(1000);
  }
      if (IDCounter == 3) {
digitalWrite(led4, HIGH);
delay(200);
digitalWrite(led4, LOW);
delay(200);
digitalWrite(led4, HIGH);
delay(200);
digitalWrite(led4, LOW);
delay(200);
digitalWrite(led4, HIGH);
delay(200);
digitalWrite(led4, LOW);
delay(3000);
digitalWrite(led4, LOW);
IDCounter = 0;
      }
}

void loop() {
  
if (digitalRead (b) == HIGH) { //Elección de puerta 1
  digitalWrite (led1, HIGH);
  digitalWrite(led2, LOW);
}

if (digitalRead (b3) == HIGH) { //Elección puerta 2
  digitalWrite (led2, HIGH);
  digitalWrite(led1, LOW);
}

if (digitalRead(led1) == HIGH){
  puerta1(); //Llamamos al código de apertura de la puerta 1
}
if (digitalRead(led2) == HIGH)
{
   puerta2(); //Llamamos al código de apertura de la puerta 2
  

}
}

Al final he usado este código y funciona como yo quiero en su mayor parte (sólo pasa que al iniciar no hay ninguna puerta seleccionada) Lo dejo aquí por si alguien necesita algo parecido.

Gracias a todos por las respuestas!

Bueno, pero no has leído ni implementado ninguna de las sugerencias que te di. Me alegro de todos modos que lo resolvieras.

Agrega solucionado a tu titulo para poder cerrarlo.