Erro ao bloquear tag não cadastrado - RFID RC522

Boa tarde pessoal. Fiz um sistema de trava eletrônica usando o RFID RC522.

O problema que ocorre, é que o sistema, ao ler uma tag não cadastrada no código, ele bloqueia a passagem, porém, se eu passar uma tag cadastrada (obviamente que a porta abre), e logo depois desta tag cadastrada eu passar uma outra não cadastrada, ela libera o acesso da mesma forma, de vez em quando. Depende do tempo que se passa, isso não ocorre. Acho que ela grava o code da tag anterior (tag cadastrada) e acaba usando para a tag não cadastrada.

Aqui abaixo consta o code que usei para este sistema:

// inclusão das bilibotecas
#include <SPI.h>
#include <RFID.h>
#include <Wire.h>

// definição do RFID
RFID rfid(10,5);
byte tag[5] = {0x33,0x09,0x8F,0xF4,0x41};
// coloque aqui seus outros cartões permitidos

byte serNum[5];
byte data[5];

// definição das melodias de acesso/boas vindas e rejeição/erro


// definição dos pinos do LED, Buzzer e Rele
int LED_access = 2;
int LED_intruder = 3;

int rele = 9;


void setup(){
  Serial.begin(9600);
  SPI.begin(); // inicialização da comunicação SPI para o RFID
  rfid.init(); // inicialização do RFID
  pinMode(LED_access,OUTPUT);
  pinMode(LED_intruder,OUTPUT);
  pinMode(rele,OUTPUT);
}
 
void loop(){
  // aqui voce vai criar uma variável para cada usuário
  // INICIALDONOME_card ou CODIGO_card
  boolean tag_card = true; // tag
  
  if (rfid.isCard()){ // encontrado cartão válido
    if (rfid.readCardSerial()){ // faz a leitura do cartão
      data[0] = rfid.serNum[0]; // armazena o número serial
      data[1] = rfid.serNum[1];
      data[2] = rfid.serNum[2];
      data[3] = rfid.serNum[3];
      data[4] = rfid.serNum[4];

    }
  
  //rfid.halt(); // RFID para standby
 
  for(int i=0; i<5; i++){
    if(data[i] != tag[i]) tag_card = false;
    // aqui você pode verificar os outros cartões permitidos
  }
  if (tag_card){// adicione os outros usuários com um ou logico ||
    Serial.println("Bem vindo!");
    digitalWrite(rele, HIGH); // libera porta
    delay(250); // espera
    digitalWrite(rele, LOW); // trava porta
  }
  else{ // se um cartão desconhecido foi encontrado
    Serial.println("Cartao nao reconhecido!");
    Serial.println("Contacte o administrador!"); // imprime mensagem
    digitalWrite(LED_intruder, HIGH); // acende LED vermelho
    for (int i = 0; i < 6; i++){ // toca música de rejeição de usuário
      
    }
    delay(1000);
    digitalWrite(LED_intruder, LOW); // apaga LED vermelho
  }

  delay(200);
  rfid.halt();
  }  
}

[ResAgradeço qualquer ajuda.

Não gosto deste bloco:

  for(int i=0; i<5; i++){
    if(data[i] != tag[i]) tag_card = false;
    // aqui você pode verificar os outros cartões permitidos
  }

O que acontece se todos os dígitos forem diferentes menos o último?

Outra coisa que não gosto é que não vejo lógica no que acontece se for detectado um cartão, ou seja, se o resultado deste teste for positivo:

  if (rfid.isCard()){ // encontrado cartão válido

mas não se conseguir ler o código desse cartão, ou seja, se o resultado deste teste for negativo:

    if (rfid.readCardSerial()){ // faz a leitura do cartão

Não daria esse problema que está a descrever?

Não ficaria melhor assim?

// inclusão das bilibotecas
#include <SPI.h>
#include <RFID.h>
#include <Wire.h>

// definição do RFID
RFID rfid(10,5);
byte tag[5] = {0x33,0x09,0x8F,0xF4,0x41};
// coloque aqui seus outros cartões permitidos

byte serNum[5];
byte data[5];

// definição das melodias de acesso/boas vindas e rejeição/erro


// definição dos pinos do LED, Buzzer e Rele
int LED_access = 2;
int LED_intruder = 3;

int rele = 9;


void setup(){
  Serial.begin(9600);
  SPI.begin(); // inicialização da comunicação SPI para o RFID
  rfid.init(); // inicialização do RFID
  pinMode(LED_access,OUTPUT);
  pinMode(LED_intruder,OUTPUT);
  pinMode(rele,OUTPUT);
}
 
void loop(){
  // aqui voce vai criar uma variável para cada usuário
  // INICIALDONOME_card ou CODIGO_card
  boolean tag_card = false; // tag
  
  if (rfid.isCard()){ // encontrado cartão válido
    if (rfid.readCardSerial()){ // faz a leitura do cartão
      data[0] = rfid.serNum[0]; // armazena o número serial
      data[1] = rfid.serNum[1];
      data[2] = rfid.serNum[2];
      data[3] = rfid.serNum[3];
      data[4] = rfid.serNum[4];

      for(int i=0; i<5; i++){
        // aqui você pode verificar os outros cartões permitidos
        if(data[i] == tag[i]){
           tag_card = true;
        }
        else {
           tag_card = false;
           break;
        }
      }
    }
  
  //rfid.halt(); // RFID para standby
 
  if (tag_card){// adicione os outros usuários com um ou logico ||
    Serial.println("Bem vindo!");
    digitalWrite(rele, HIGH); // libera porta
    delay(250); // espera
    digitalWrite(rele, LOW); // trava porta
  }
  else{ // se um cartão desconhecido foi encontrado
    Serial.println("Cartao nao reconhecido!");
    Serial.println("Contacte o administrador!"); // imprime mensagem
    digitalWrite(LED_intruder, HIGH); // acende LED vermelho
    for (int i = 0; i < 6; i++){ // toca música de rejeição de usuário
      
    }
    delay(1000);
    digitalWrite(LED_intruder, LOW); // apaga LED vermelho
  }

  delay(200);
  rfid.halt();
  }  
}

Agora, passado um tempo, ocorre outro problema (não sei porque veio a acontecer, mas é a segunda vez que ligo a placa) O rele fica piscando até que se passe uma tag não cadastrada. Enquanto ele estiver sem tag, ou com tag cadastrada, o rele fica piscando incessantemente, mas ao passar uma tag não cadastrada, ele para o rele.

Estou analisando o código, mas a princípio, não encontro nada errado!

Define a variável tag_card como false e isso passa.

Talvez, uma coisa assim, resulte:

// inclusão das bilibotecas
#include <SPI.h>
#include <RFID.h>
#include <Wire.h>

// definição do RFID
RFID rfid(10,5);
byte tag[5] = {0x33,0x09,0x8F,0xF4,0x41};
// coloque aqui seus outros cartões permitidos

byte serNum[5];
byte data[5];

// definição das melodias de acesso/boas vindas e rejeição/erro


// definição dos pinos do LED, Buzzer e Rele
int LED_access = 2;
int LED_intruder = 3;

int rele = 9;


void setup(){
  Serial.begin(9600);
  SPI.begin(); // inicialização da comunicação SPI para o RFID
  rfid.init(); // inicialização do RFID
  pinMode(LED_access,OUTPUT);
  pinMode(LED_intruder,OUTPUT);
  pinMode(rele,OUTPUT);
  digitalWrite(rele, LOW); // trava porta
}
 
void loop(){
  // aqui voce vai criar uma variável para cada usuário
  // INICIALDONOME_card ou CODIGO_card
  boolean tag_card = false; // tag
  
  if (rfid.isCard()){ // encontrado cartão válido
    if (rfid.readCardSerial()){ // faz a leitura do cartão
      data[0] = rfid.serNum[0]; // armazena o número serial
      data[1] = rfid.serNum[1];
      data[2] = rfid.serNum[2];
      data[3] = rfid.serNum[3];
      data[4] = rfid.serNum[4];

      for(int i=0; i<5; i++){
        // aqui você pode verificar os outros cartões permitidos
        if(data[i] == tag[i]){
           tag_card = true;
        }
        else {
           tag_card = false;
           break;
        }
      }
    }
  
  //rfid.halt(); // RFID para standby
 
  if (tag_card){// adicione os outros usuários com um ou logico ||
    Serial.println("Bem vindo!");
    digitalWrite(rele, HIGH); // libera porta
    delay(250); // espera
    digitalWrite(rele, LOW); // trava porta
  }
  else{ // se um cartão desconhecido foi encontrado
    Serial.println("Cartao nao reconhecido!");
    Serial.println("Contacte o administrador!"); // imprime mensagem
    digitalWrite(LED_intruder, HIGH); // acende LED vermelho
    for (int i = 0; i < 6; i++){ // toca música de rejeição de usuário
      
    }
    delay(1000);
    digitalWrite(LED_intruder, LOW); // apaga LED vermelho
  }

  delay(200);
  rfid.halt();
  }  
}

@bubulindo,

acho que estavas a falar disto:

boolean tag_card = false; // tag

isso foi definido no loop

@luisilva,

uma solução tão óbvia rsrs. Vou testar, mas acho que isso sana o problema!

yago4xd:
@bubulindo,

acho que estavas a falar disto:

boolean tag_card = false; // tag

Por acaso estava a falar disto:

  boolean tag_card = true; // tag

:wink:

@bubulindo: Penso que isso era um dos problemas do programa original. Também não estou a ver porque funcionaria.