Controle de Acesso com Arduino+RFID

O objetivo deste tutorial é mostrar passo a passo a construção de um sistema de controle de acesso (abertura de portas) acionado por cartões RFID. Inicialmente o sistema vem com um cartão master, que ao ser lido inicia o cadastro ou exclusão do próximo cartão lido, se o cartão não for cadastrado, ele é incluso, se for cadastrado, é excluído.

Funcionalidades

  • Liberação de acesso apenas para cartões cadastrados;
  • Inclusão/Exclusão de cartões sem a necessidade de estar conectado com nenhum outro equipamento;
  • Visor de LCD para apresentar as informações;
  • Conjunto de 3 botões para digitar nomes dos cartões incluídos.

Equipamentos
RFID1

  1. Placa Arduino Uno – Que controla todo o equipamento
  2. Leitor RFID RC522– Fazer a leitura dos cartões
  3. Visor LCD I2C – Para exibir informações para o usuário
  4. Placa RTC DS1302– Para manter o tempo atualizado, permitindo que o sistema logue os horários de entrada e saída das pessoas
  5. Botões – Para escrever os nomes nos cartões
  6. LED– Neste caso, utilizamos o LED para indicar que a porta foi aberta, no caso real, o LED deve ser substituído por um relê que abre a porta
  7. Speaker – Para emitir um aviso sonoro quando a porta for aberta

Conexões (clicar nas imagens para visualizar em tamanho maior)
Ligando o modulo RTC
RFID2

Ligando o módulo RFID
RFID3

Ligando o LCD I2C
lcd16x2_i2c_arduino_uno_bb

Ligando o LED

led_arduino_bb
Observação: Inicialmente não colocamos em funcionamento a edição de nomes dos cartões.

Código

Bibliotecas necessárias

Para cada módulo novo instalado, precisamos incluir a biblioteca do mesmo, utilizamos as seguintes:

Como utilizamos a EEPROM para salvar os dados do nosso protótipo, precisamos também dessas bibliotecas abaixo:

Começando o Sistema:

Inicializando as bibliotecas

#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h> 
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>

Inicializando o display LCD no endereço 0x27

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE);

Definindo o leitor RFID nos pinos 10 e 9

#define SS_PIN 10
#define RST_PIN 9

MFRC522 mfrc522(SS_PIN, RST_PIN);

Definindo o LED que indicará se a porta foi aberta ou não:

int led_liberado = 5;

Como o cartão master será definido por nós, precisamos dizer ao sistema qual o seu código, também vamos criar uma String para salvar os cartões cadastrados e um marcador para indicar se o sistema deve ler o cartão de acesso ou cadastrar/apagar se o master tiver sido lido anteriormente.

byte valor;
char st[20];
String cartoesCadastrados = "";
String master = "AE 43 D3 B5";
int marcadorNovoCartao = 0; 

Agora vamos escrever o setup da aplicação para inicializar a serial de comunicação com o LCD, o próprio LCD, o leitor RFID, a mensagem inicial e a função que carregará os cartões já cadastrados.

void setup() 
{
  // inicia a serial
  Serial.begin(9600);
  // define o número de colunas e linhas do LCD:
  lcd.begin (16,2);
  pinMode(led_liberado, OUTPUT);
  // inicia  SPI bus
  SPI.begin();
  // inicia MFRC522
  mfrc522.PCD_Init(); 
  // mensagens iniciais no serial monitor
  Serial.println("Aproxime o seu cartao do leitor...");
  Serial.println();
  mensagemInicial();
  carregarCartoesCadastrados();
}

Na sequência, definiremos a função carregarCartoesCadastrados() para que o sistema dê acesso aos cartões já cadastrados que estão, no nosso caso, armazenados na EEPROM.

  
void carregarCartoesCadastrados(){

  Serial.println("Carregando cartoes cadastrados...");
  
  for(int i = 0; i< 1024; i++){
    int aux = EEPROM.read(i);
    
    if (aux != 255){
      
      String cartao = "";
      char auxChar;
      int espacoBranco = 0;
      
      do{
        auxChar = char(EEPROM.read(i));
        
        cartao = cartao + auxChar;
        
        //Colocar " " (espaço em branco) a cada 2 letras
        espacoBranco ++;
        if (espacoBranco >= 2){
          cartao = cartao + " ";
          espacoBranco = 0;
        }

        
        i++;
      }while(auxChar != ';');
      i--;
      
      Serial.print("Cartao: ");
      Serial.println(cartao);
      
      cartoesCadastrados = cartoesCadastrados + cartao;
      
      Serial.print("Lista de Cartoes: ");
      Serial.println(cartoesCadastrados);

      
    }
  } 
}

Vamos definir a função da mensagem inicial

void mensagemInicial(){
  lcd.clear();
  lcd.print(" Aproxime o seu");  
  lcd.setCursor(0,1);
  lcd.print("cartao do leitor");  
}

A função que libera o acesso caso o cartão esteja cadastrado, no nosso caso, como estamos usando um LED ao invés do relê da porta, definimos um delay para o sistema apagar a luz como se a porta tivesse sido fechada.

void liberarAcesso() {
  // Levanta a cancela e acende o led verde
  digitalWrite(led_liberado, HIGH);
  Serial.println("Cartao1 - Acesso liberado !");
  Serial.println();
  // Exibe a mensagem no lcd
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Acesso liberado");
  delay(2000);
  microservo9g.write(90);
  digitalWrite(led_liberado, LOW);
  lcd.clear();
}

Função de mensagem para cartões de acordo com seu status.

bool isCartaoCadastrado(String cartao){
  if (cartoesCadastrados.indexOf(cartao) >= 0){
    Serial.print("Cartão Cadastrado!");
    return true;
    delay(500);
  }
  return false;
}

Quando o cartão master é lido, o sistema tem que escolher se cadastra ou remove o próximo cartão, para tal, criamos a função abaixo

void alterarCartoes(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Aproxime o novo");
  lcd.setCursor(0,1);  
  lcd.print("cartao");

  // Aguarda a aproximacao do cartao
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Seleciona um dos cartoes
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  // Mostra UID na serial
  Serial.print("UID da tag :");
  String conteudo= "";
  byte letra;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    conteudo.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    conteudo.concat(String(mfrc522.uid.uidByte[i], HEX));
  }

  String novoCartao = conteudo.substring(1);
  novoCartao.toUpperCase();
  novoCartao.trim();
  novoCartao = novoCartao + " ;";

  if (conteudo.length() > 0 && novoCartao.indexOf(master) < 0){
    if(cartoesCadastrados.indexOf(novoCartao) < 0){
      cadastrarNovoCartao(novoCartao);
    }else{
      removerCartao(novoCartao);
    }
    marcadorNovoCartao = 0;

    delay(2000);
    mensagemInicial();
  }

  Serial.print("Lista de Cartoes: ");
  Serial.println(cartoesCadastrados);
}

Abaixo as funções que cadastram novos cartões e que removem cartões já cadastrados.

void cadastrarNovoCartao(String cartao){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Cartao");
  lcd.setCursor(0,1);    
  lcd.print("Cadastrado");

  Serial.print("Adicionou o cartao ");
  Serial.print(cartao);
  Serial.println(" na lista");

  cartoesCadastrados = cartoesCadastrados + cartao;
  
  //remove os espacos em branco do cartao e adiciona o ';'
  cartao.replace(" ","");

  //Adicionar o novo cartão na memória
  for(int i = 0; i< 1024; i++){
    
    int aux = EEPROM.read(i);
    
    if (aux == 255){
      for(int j = 0; j< cartao.length(); j++){
        EEPROM.write(i, byte(cartao.charAt(j)));
        i++;
      }
      break;
    }
  } 

}

void removerCartao(String cartao){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Cartao");
  lcd.setCursor(0,1);    
  lcd.print("Removido");
  
  Serial.print("Removeu o cartao ");
  Serial.print(cartao);
  Serial.println(" da lista");
  
  cartoesCadastrados.replace(cartao, "");
  Serial.print("Cartoes atuais: ");
  Serial.println(cartoesCadastrados);
  
  
 //Remove o cartão na memória 
 String auxCartoesCadastrados = cartoesCadastrados;
 auxCartoesCadastrados.replace(" ","");
  for(int i = 0; i< 1024; i++){
    
   if(i < auxCartoesCadastrados.length()){
     EEPROM.write(i, byte(auxCartoesCadastrados.charAt(i)));
   }else{
     EEPROM.write(i, 255);
   }
    
    
  } 
  
}

É isso, infelizmente não dispomos de um relê nem de uma porta para testar o sistema na prática e também não chegamos a incluir mais armazenamento para poder trabalhar com mais cartões e com os nomes dos usuários (o Arduino que utilizamos só tem 1MB de memória), o uso dos botões para escrever o nome deverá vir numa próxima parte para este tutorial. Esperamos que o tutorial lhes ajudem a entender um pouco mais do Arduino, seus módulos e bibliotecas e lhe sirva de inspiração para novos projetos.

Segue o código completo para download:
https://www.dropbox.com/s/yutygcitixu40zw/controleAcesso-v01_03.zip?dl=0

Publicidade

10 comentários em “Controle de Acesso com Arduino+RFID

  1. Oi, primeiramente, parabéns pelo trabalho! Segundo, eu testei aqui o código de vocês, porém ele sempre entra em loop infinito “marcadorNocoCartao: 0” então eu passo o cartão no leitor de Rfid, ai ele exibe “marcadorNocoCartao: 1” até 14. e então volta a ficar exibindo sem parar “marcadorNocoCartao: 0” e não sai do loop… Help.. :/

    Curtir

  2. Boa noite Claudio parece muito interessante seu projeto parabéns, porém não consegui testar, por gentileza você poderia passar mais detalhes de como proceder, nem cheguei aos códigos o diagrama não ficou muito claro p/ mim, se possível.
    Meu e-mail: artilant_fb@hotmail.com
    valeu, aguardo retorno…

    Curtir

  3. Pessoal para rodar esse arquivo utilize a versão 1.6.0
    Estou desenvolvendo um projeto parecido com este e estava sempre dando erros, então voltei a esta versão e não me incomodei mais.

    Curtir

  4. Olá, gostei muito do seu projeto… Porém estou tentando ao invés de ser cartões de acesso, eu gostaria de usar senhas com um teclado matricial e display. Alguém poderia me indicar algum projeto parecido ou então esse projeto com alguma dica para mudar para senha ?
    Aguardo atenciosamente.

    Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s