Magos do Arduino

Sensor RFID RC522 de leitura de cartões

Aprenda a utilizar um sensor RFID RC522 de leitura de cartões com o Arduino

Magos do Arduino

Sensor RFID RC522 de leitura de cartões

O sensor RFID RC522 é um módulo leitor/gravação de cartões e tags RFID de 13,56 MHz.

Sensor RFID RC522 de leitura de cartões

Utiliza o chip MFRC522, que realiza a comunicação sem fio com os cartões.

Muito usado em projetos de controle de acesso, identificação e automação.

Ele suporta cartões e tags padrão MIFARE.

Seu alcance de leitura é de até 3 cm (dependendo da antena e do cartão).

Possui um baixo consumo de energia.

Utiliza a interface de comunicação SPI, I2C ou UART (sendo SPI o mais comum).

O módulo possui 8 pinos principais:

  1. SDA (ou NSS) -> Seleção de dispositivo (SPI)
  2. SCK -> Clock serial (SPI)
  3. MOSI -> Dados enviados do microcontrolador para o módulo
  4. MISO -> Dados enviados do módulo para o microcontrolador
  5. IRQ -> Interrupção (opcional)
  6. GND -> Terra
  7. RST -> Reset
  8. 3.3V -> Alimentação (somente 3.3V)

Cartões e tags RFID

Os cartões/tags possuem memória de armazenamento com capacidade total de 1KB.

Esta memória é dividida em 16 setores, onde cada setor contém 4 blocos de 16 bytes, totalizando 64 blocos (16 setores × 4 blocos).

O bloco 0 do setor 0 contém o UID (identificador único do cartão), e não deve ser alterado.

Já o último bloco de cada setor, chamado de Setor Trailer, é usado para armazenar as chaves A e B (utilizada para autenticação) e configurar permissões de acesso aos blocos do setor.

Protocolo SPI

O SPI (Serial Peripheral Interface) é um protocolo de comunicação serial síncrono que permite a troca rápida de dados entre um microcontrolador e periféricos.

Ele utiliza 4 linhas principais.

MOSI -> Dados do Arduino para o módulo.

MISO -> Dados do módulo para o Arduino.

SCK -> Clock gerado pelo Arduino.

SS (ou CS) -> Seleção do dispositivo/módulo.

Sensor RFID RC522 de leitura de cartões

Neste projeto você criará um circuito que faz o uso de um sensor RFID RC522 de leitura de cartões com o Arduino.

Para a criação deste circuito serão necessários os seguintes componentes:

  • 1x Breadboard (Opcional)
  • 1x Arduino UNO
  • 1x Sensor RFID RD522
  • 1x Cartão/tag compatível com o módulo RD522
  • Jumpers

Circuito sensor RFID RC522 de leitura de cartões

Para montar o circuito, visualize na imagem a seguir como conectar os componentes entre a placa Arduino e a breadboard.

Circuito Sensor RFID RC522 de leitura de cartões

Código fonte para o circuito do sensor RFID RC522 de leitura de cartões

Uma vez criado o circuito, use o código fonte a seguir no Arduino IDE para fazer o upload dele na placa Arduino e assim ver o resultado do circuito em funcionamento.

/**
 * Código do curso Magos do Arduino para utilizar um sensor de leitura RFID de cartões com o Arduino
 * 
 * Código de demonstração que grava e lê dados de um cartão RFID, imprimindo no monitor serial 
 * detalhes do processo com o Arduino.
 * 
 * Utiliza a biblioteca MFRC522 para a operação deste sensor com o Arduino. 
 * Esta biblioteca pode ser instalada diretamente através do Arduino IDE.
 * 
 * (c) Copyright KazaleIT
 * @kazaleitoficial no YouTube
 */

#include <SPI.h> // importa biblioteca para comunicação SPI
#include <MFRC522.h> // importa biblioteca para RFID

#define PINO_SDA 10
#define PINO_RESET 9

MFRC522 mfrc522(PINO_SDA, PINO_RESET); // cria instância do objeto MFRC522
MFRC522::MIFARE_Key key; // chave de armazenamento da chave de segurança do cartão

int bloco = 2; // bloco onde será escrito e lida as informções do cartão

byte conteudoBloco[16] = { "Kazale IT" };  // array de 16 bytes com o conteúdo a ser inscrito no cartão
byte valorLeituraBloco[18]; // array para a leitura de um bloco, tamanho 18 por causa da biblioteca

void setup() {
  Serial.begin(9600);  // inicializa a comunicação serial
  SPI.begin();         // inicializa a comunicação SPI
  mfrc522.PCD_Init();  // inicializa o objeto MFRC522

  Serial.println("Escaneamento de um cartão MIFARE");

  // prepara chave de segurança utilizada para autenticação e realização dos processos de leitura e escrita
  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;  // chave padrão definida para este tipo de cartões
  }
}

void loop() {
  // verifica se existe cartão disponível para leitura
  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // seleciona o cartão
  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  Serial.println("cartão selecionado");

  // realiza a gravação dos dados no cartão por bloco
  gravarBloco(bloco, conteudoBloco);

  // realiza a leitura dos dados do cartão por bloco
  lerBloco(bloco, valorLeituraBloco);

  // imprime todos os dados do cartão
  mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

  // imprime os dados lidos do cartão
  Serial.print("dados do cartão: ");
  for (int i = 0; i < 16; i++) {
    if (valorLeituraBloco[i] > 0) {
      Serial.write(valorLeituraBloco[i]);
    }
  }
  Serial.println("");
}

// grava no cartão o conteúdo passado como parâmetro no bloco informado
void gravarBloco(int numeroBloco, byte conteudo[]) {
  // realiza cálculos para validação do bloco
  int maiorModulo4 = numeroBloco / 4 * 4;
  int trailerBloco = maiorModulo4 + 3;
  if (numeroBloco > 2 && (numeroBloco + 1) % 4 == 0) {
    Serial.println("erro validando bloco.");
    return;
  }

  // autentica para acesso ao bloco
  MFRC522::StatusCode status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBloco, &key, &(mfrc522.uid));
  if (status != MFRC522::STATUS_OK) {
    Serial.print("erro ao autenticar cartão: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  // realiza a escrita dos dados no bloco
  status = mfrc522.MIFARE_Write(numeroBloco, conteudo, 16);
  if (status != MFRC522::STATUS_OK) {
    Serial.print("erro gravando dados no cartão: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  Serial.println("bloco gravado com sucesso!");
}

// realiza a leitura dos dados de um bloco do cartão
void lerBloco(int numeroBloco, byte conteudo[]) {
  int maiorModulo4 = numeroBloco / 4 * 4;
  int trailerBloco = maiorModulo4 + 3;

  // autentica para acesso ao bloco
  MFRC522::StatusCode status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBloco, &key, &(mfrc522.uid));

  if (status != MFRC522::STATUS_OK) {
    Serial.print("erro ao autenticar cartão: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  // realiza a leitura dos dados de um bloc do cartão
  byte tamanhoBuffer = 18;
  status = mfrc522.MIFARE_Read(numeroBloco, conteudo, &tamanhoBuffer);
  if (status != MFRC522::STATUS_OK) {
    Serial.print("erro lendo dados no cartão: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  Serial.println("bloco lido com sucesso!");
}